--- /dev/null
+MODEL=m\r
+CFLAGS=-f87 -2 -m$(MODEL)\r
+\r
+.c.obj:; bcc $(CFLAGS) -c $*.c\r
+\r
+OBJS= sst.obj setup.obj reports.obj finish.obj moving.obj\\r
+ battle.obj events.obj ai.obj planets.obj\r
+\r
+sst.exe: $(OBJS) sst.lnk\r
+ bcc @sst.lnk\r
+\r
+\r
+sst.lnk: makefile\r
+ >sst.lnk $(CFLAGS) -M $(OBJS) noeh$(MODEL).lib
\ No newline at end of file
--- /dev/null
+CFLAGS= -O\r
+\r
+.SUFFIXES: .o .c .s .exe\r
+\r
+.c.o:\r
+ $(CC) $(CFLAGS) -c $<\r
+\r
+OFILES= sst.o finish.o reports.o setup.o os2.o moving.o battle.o events.o ai.o planets.o\r
+\r
+HFILES= sst.h\r
+\r
+sstos2.exe: $(OFILES)\r
+ gcc -o sstos2.exe $(OFILES)\r
+\r
+ \r
+$(OFILES): $(HFILES)\r
+\r
--- /dev/null
+#include "sst.h"\r
+\r
+static int tryexit(int lookx, int looky, int ienm, int loccom, int irun) {\r
+ int iqx, iqy, l;\r
+\r
+ iqx = quadx+(lookx+9)/10 - 1;\r
+ iqy = quady+(looky+9)/10 - 1;\r
+ if (iqx < 1 || iqx > 8 || iqy < 1 || iqy > 8 ||\r
+ d.galaxy[iqx][iqy] > 899)\r
+ return 0; /* no can do -- neg energy, supernovae, or >8 Klingons */\r
+ if (ienm == IHR) return 0; /* Romulans cannot escape! */\r
+ if (irun == 0) {\r
+ /* avoid intruding on another commander's territory */\r
+ if (ienm == IHC) {\r
+ for (l = 1; l <= d.remcom; l++)\r
+ if (d.cx[l]==iqx && d.cy[l]==iqy) return 0;\r
+ /* refuse to leave if currently attacking starbase */\r
+ if (batx==quadx && baty==quady) return 0;\r
+ }\r
+ /* don't leave if over 1000 units of energy */\r
+ if (kpower[loccom] > 1000.) return 0;\r
+ }\r
+ /* print escape message and move out of quadrant.\r
+ We know this if either short or long range sensors are working */\r
+ if (damage[DSRSENS] == 0.0 || damage[DLRSENS] == 0.0 ||\r
+ condit == IHDOCKED) {\r
+ proutn("***");\r
+ cramen(ienm);\r
+ proutn(" escapes to");\r
+ cramlc(1, iqx, iqy);\r
+ prout(" (and regains strength).");\r
+ }\r
+ /* handle local matters related to escape */\r
+ kx[loccom] = kx[nenhere];\r
+ ky[loccom] = ky[nenhere];\r
+ kavgd[loccom] = kavgd[nenhere];\r
+ kpower[loccom] = kpower[nenhere];\r
+ kdist[loccom] = kdist[nenhere];\r
+ klhere--;\r
+ nenhere--;\r
+ if (condit != IHDOCKED) newcnd();\r
+ /* Handle global matters related to escape */\r
+ d.galaxy[quadx][quady] -= 100;\r
+ d.galaxy[iqx][iqy] += 100;\r
+ if (ienm==IHS) {\r
+ ishere=0;\r
+ iscate=0;\r
+ ientesc=0;\r
+ isatb=0;\r
+ future[FSCMOVE]=0.2777+d.date;\r
+ future[FSCDBAS]=1e30;\r
+ d.isx=iqx;\r
+ d.isy=iqy;\r
+ }\r
+ else {\r
+ for (l=1; l<=d.remcom; l++) {\r
+ if (d.cx[l]==quadx && d.cy[l]==quady) {\r
+ d.cx[l]=iqx;\r
+ d.cy[l]=iqy;\r
+ break;\r
+ }\r
+ }\r
+ comhere = 0;\r
+ }\r
+ return 1; /* success */\r
+}\r
+\r
+\r
+static void movebaddy(int comx, int comy, int loccom, int ienm) {\r
+ int motion, mdist, nsteps, mx, my, nextx, nexty, lookx, looky, ll;\r
+ int irun = 0;\r
+ int krawlx, krawly;\r
+ int success;\r
+ int attempts;\r
+ /* This should probably be just comhere + ishere */\r
+ int nbaddys = skill > 3 ?\r
+ (int)((comhere*2 + ishere*2+klhere*1.23+irhere*1.5)/2.0):\r
+ (comhere + ishere);\r
+ double dist1, forces;\r
+\r
+ dist1 = kdist[loccom];\r
+ mdist = dist1 + 0.5; /* Nearest integer distance */\r
+\r
+ /* If SC, check with spy to see if should hi-tail it */\r
+ if (ienm==IHS &&\r
+ (kpower[loccom] <= 500.0 || (condit==IHDOCKED && damage[DPHOTON]==0))) {\r
+ irun = 1;\r
+ motion = -10;\r
+ }\r
+ else {\r
+ /* decide whether to advance, retreat, or hold position */\r
+/* Algorithm:\r
+ * Enterprise has "force" based on condition of phaser and photon torpedoes.\r
+ If both are operating full strength, force is 1000. If both are damaged,\r
+ force is -1000. Having shields down subtracts an additional 1000.\r
+\r
+ * Enemy has forces equal to the energy of the attacker plus\r
+ 100*(K+R) + 500*(C+S) - 400 for novice through good levels OR\r
+ 346*K + 400*R + 500*(C+S) - 400 for expert and emeritus.\r
+\r
+ Attacker Initial energy levels (nominal):\r
+ Klingon Romulan Commander Super-Commander\r
+ Novice 400 700 1200 \r
+ Fair 425 750 1250\r
+ Good 450 800 1300 1750\r
+ Expert 475 850 1350 1875\r
+ Emeritus 500 900 1400 2000\r
+ VARIANCE 75 200 200 200\r
+\r
+ Enemy vessels only move prior to their attack. In Novice - Good games\r
+ only commanders move. In Expert games, all enemy vessels move if there\r
+ is a commander present. In Emeritus games all enemy vessels move.\r
+\r
+ * If Enterprise is not docked, an agressive action is taken if enemy\r
+ forces are 1000 greater than Enterprise.\r
+\r
+ Agressive action on average cuts the distance between the ship and\r
+ the enemy to 1/4 the original.\r
+\r
+ * At lower energy advantage, movement units are proportional to the\r
+ advantage with a 650 advantage being to hold ground, 800 to move forward\r
+ 1, 950 for two, 150 for back 4, etc. Variance of 100.\r
+\r
+ If docked, is reduced by roughly 1.75*skill, generally forcing a\r
+ retreat, especially at high skill levels.\r
+\r
+ * Motion is limited to skill level, except for SC hi-tailing it out.\r
+ */\r
+\r
+ forces = kpower[loccom]+100.0*nenhere+400*(nbaddys-1);\r
+ if (shldup==0) forces += 1000; /* Good for enemy if shield is down! */\r
+ if (damage[DPHASER] == 0.0 || damage[DPHOTON] == 0.0) {\r
+ if (damage[DPHASER] != 0) /* phasers damaged */\r
+ forces += 300.0;\r
+ else\r
+ forces -= 0.2*(energy - 2500.0);\r
+ if (damage[DPHOTON] != 0) /* photon torpedoes damaged */\r
+ forces += 300.0;\r
+ else\r
+ forces -= 50.0*torps;\r
+ }\r
+ else {\r
+ /* phasers and photon tubes both out! */\r
+ forces += 1000.0;\r
+ }\r
+ motion = 0;\r
+ if (forces <= 1000.0 && condit != IHDOCKED) /* Typical situation */\r
+ motion = ((forces+200.0*Rand())/150.0) - 5.0;\r
+ else {\r
+ if (forces > 1000.0) /* Very strong -- move in for kill */\r
+ motion = (1.0-square(Rand()))*dist1 + 1.0;\r
+ if (condit==IHDOCKED) /* protected by base -- back off ! */\r
+ motion -= skill*(2.0-square(Rand()));\r
+ }\r
+#ifdef DEBUG\r
+ if (idebug) {\r
+ proutn("MOTION = ");\r
+ cramf(motion, 1, 2);\r
+ proutn(" FORCES = ");\r
+ cramf(forces, 1, 2);\r
+ skip(1);\r
+ }\r
+#endif\r
+ /* don't move if no motion */\r
+ if (motion==0) return;\r
+ /* Limit motion according to skill */\r
+ if (abs(motion) > skill) motion = (motion < 0) ? -skill : skill;\r
+ }\r
+ /* calcuate preferred number of steps */\r
+ nsteps = motion < 0 ? -motion : motion;\r
+ if (motion > 0 && nsteps > mdist) nsteps = mdist; /* don't overshoot */\r
+ if (nsteps > 10) nsteps = 10; /* This shouldn't be necessary */\r
+ if (nsteps < 1) nsteps = 1; /* This shouldn't be necessary */\r
+#ifdef DEBUG\r
+ if (idebug) {\r
+ proutn("NSTEPS = ");\r
+ crami(nsteps, 1);\r
+ skip(1);\r
+ }\r
+#endif\r
+ /* Compute preferred values of delta X and Y */\r
+ mx = sectx - comx;\r
+ my = secty - comy;\r
+ if (2.0 * abs(mx) < abs(my)) mx = 0;\r
+ if (2.0 * abs(my) < abs(sectx-comx)) my = 0;\r
+ if (mx != 0) mx = mx*motion < 0 ? -1 : 1;\r
+ if (my != 0) my = my*motion < 0 ? -1 : 1;\r
+ nextx = comx;\r
+ nexty = comy;\r
+ quad[comx][comy] = IHDOT;\r
+ /* main move loop */\r
+ for (ll = 1; ll <= nsteps; ll++) {\r
+#ifdef DEBUG\r
+ if (idebug) {\r
+ crami(ll,2);\r
+ skip(1);\r
+ }\r
+#endif\r
+ /* Check if preferred position available */\r
+ lookx = nextx + mx;\r
+ looky = nexty + my;\r
+ krawlx = mx < 0 ? 1 : -1;\r
+ krawly = my < 0 ? 1 : -1;\r
+ success = 0;\r
+ attempts = 0; /* Settle mysterious hang problem */\r
+ while (attempts++ < 20 && !success) {\r
+ if (lookx < 1 || lookx > 10) {\r
+ if (motion < 0 && tryexit(lookx, looky, ienm, loccom, irun))\r
+ return;\r
+ if (krawlx == mx || my == 0) break;\r
+ lookx = nextx + krawlx;\r
+ krawlx = -krawlx;\r
+ }\r
+ else if (looky < 1 || looky > 10) {\r
+ if (motion < 0 && tryexit(lookx, looky, ienm, loccom, irun))\r
+ return;\r
+ if (krawly == my || mx == 0) break;\r
+ looky = nexty + krawly;\r
+ krawly = -krawly;\r
+ }\r
+ else if (quad[lookx][looky] != IHDOT) {\r
+ /* See if we should ram ship */\r
+ if (quad[lookx][looky] == ship &&\r
+ (ienm == IHC || ienm == IHS)) {\r
+ ram(1, ienm, comx, comy);\r
+ return;\r
+ }\r
+ if (krawlx != mx && my != 0) {\r
+ lookx = nextx + krawlx;\r
+ krawlx = -krawlx;\r
+ }\r
+ else if (krawly != my && mx != 0) {\r
+ looky = nexty + krawly;\r
+ krawly = -krawly;\r
+ }\r
+ else break; /* we have failed */\r
+ }\r
+ else success = 1;\r
+ }\r
+ if (success) {\r
+ nextx = lookx;\r
+ nexty = looky;\r
+#ifdef DEBUG\r
+ if (idebug) {\r
+ cramlc(0, nextx, nexty);\r
+ skip(1);\r
+ }\r
+#endif\r
+ }\r
+ else break; /* done early */\r
+ }\r
+ /* Put commander in place within same quadrant */\r
+ quad[nextx][nexty] = ienm;\r
+ if (nextx != comx || nexty != comy) {\r
+ /* it moved */\r
+ kx[loccom] = nextx;\r
+ ky[loccom] = nexty;\r
+ kdist[loccom] = kavgd[loccom] =\r
+ sqrt(square(sectx-nextx)+square(secty-nexty));\r
+ if (damage[DSRSENS] == 0 || condit == IHDOCKED) {\r
+ proutn("***");\r
+ cramen(ienm);\r
+ if (kdist[loccom] < dist1) proutn(" advances to");\r
+ else proutn(" retreats to");\r
+ cramlc(2, nextx, nexty);\r
+ skip(1);\r
+ }\r
+ }\r
+}\r
+\r
+void movcom(void) {\r
+ int ix, iy, i;\r
+\r
+#ifdef DEBUG\r
+ if (idebug) prout("MOVCOM");\r
+#endif\r
+\r
+ /* Figure out which Klingon is the commander (or Supercommander)\r
+ and do move */\r
+ if (comhere) for (i = 1; i <= nenhere; i++) {\r
+ ix = kx[i];\r
+ iy = ky[i];\r
+ if (quad[ix][iy] == IHC) {\r
+ movebaddy(ix, iy, i, IHC);\r
+ break;\r
+ }\r
+ }\r
+ if (ishere) for (i = 1; i <= nenhere; i++) {\r
+ ix = kx[i];\r
+ iy = ky[i];\r
+ if (quad[ix][iy] == IHS) {\r
+ movebaddy(ix, iy, i, IHS);\r
+ break;\r
+ }\r
+ }\r
+ /* if skill level is high, move other Klingons and Romulans too!\r
+ Move these last so they can base their actions on what the\r
+ commander(s) do. */\r
+ if (skill > 3) for (i = 1; i <= nenhere; i++) {\r
+ ix = kx[i];\r
+ iy = ky[i];\r
+ if (quad[ix][iy] == IHK || quad[ix][iy] == IHR)\r
+ movebaddy(ix, iy, i, quad[ix][iy]);\r
+ }\r
+\r
+ sortkl();\r
+}\r
+\r
+static int checkdest(int iqx, int iqy, int flag, int *ipage) {\r
+ int i, j;\r
+\r
+ if ((iqx==quadx && iqy==quady) ||\r
+ iqx < 1 || iqx > 8 || iqy < 1 || iqy > 8 ||\r
+ d.galaxy[iqx][iqy] > 899) return 1;\r
+ if (flag) {\r
+ /* Avoid quadrants with bases if we want to avoid Enterprise */\r
+ for (i = 1; i <= d.rembase; i++)\r
+ if (d.baseqx[i]==iqx && d.baseqy[i]==iqy) return 1;\r
+ }\r
+\r
+ /* do the move */\r
+ d.galaxy[d.isx][d.isy] -= 100;\r
+ d.isx = iqx;\r
+ d.isy = iqy;\r
+ d.galaxy[d.isx][d.isy] += 100;\r
+ if (iscate) {\r
+ /* SC has scooted, Remove him from current quadrant */\r
+ iscate=0;\r
+ isatb=0;\r
+ ishere=0;\r
+ ientesc=0;\r
+ future[FSCDBAS]=1e30;\r
+ for (i = 1; i <= nenhere; i++) \r
+ if (quad[kx[i]][ky[i]] == IHS) break;\r
+ quad[kx[i]][ky[i]] = IHDOT;\r
+ kx[i] = kx[nenhere];\r
+ ky[i] = ky[nenhere];\r
+ kdist[i] = kdist[nenhere];\r
+ kavgd[i] = kavgd[nenhere];\r
+ kpower[i] = kpower[nenhere];\r
+ klhere--;\r
+ nenhere--;\r
+ if (condit!=IHDOCKED) newcnd();\r
+ sortkl();\r
+ }\r
+ /* check for a helpful planet */\r
+ for (i = 1; i <= inplan; i++) {\r
+ if (d.plnets[i].x==d.isx && d.plnets[i].y==d.isy &&\r
+ d.plnets[i].crystals == 1) {\r
+ /* destroy the planet */\r
+ d.plnets[i] = nulplanet;\r
+ d.newstuf[d.isx][d.isy] -= 1;\r
+ if (damage[DRADIO] == 0.0 || condit == IHDOCKED) {\r
+ if (*ipage==0) pause(1);\r
+ *ipage = 1;\r
+ prout("Lt. Uhura- \"Captain, Starfleet Intelligence reports");\r
+ proutn(" a planet in");\r
+ cramlc(1, d.isx, d.isy);\r
+ prout(" has been destroyed");\r
+ prout(" by the Super-commander.\"");\r
+ }\r
+ break;\r
+ }\r
+ }\r
+ return 0; /* looks good! */\r
+}\r
+ \r
+ \r
+ \r
+\r
+\r
+void scom(int *ipage) {\r
+ int i, i2, j, ideltax, ideltay, ibqx, ibqy, sx, sy, ifindit, iwhichb;\r
+ int iqx, iqy;\r
+ int basetbl[6];\r
+ double bdist[6];\r
+ int flag;\r
+#ifdef DEBUG\r
+ if (idebug) prout("SCOM");\r
+#endif\r
+\r
+ /* Decide on being active or passive */\r
+ flag = ((d.killc+d.killk)/(d.date+0.01-indate) < 0.1*skill*(skill+1.0) ||\r
+ (d.date-indate) < 3.0);\r
+ if (iscate==0 && flag) {\r
+ /* compute move away from Enterprise */\r
+ ideltax = d.isx-quadx;\r
+ ideltay = d.isy-quady;\r
+ if (sqrt(ideltax*(double)ideltax+ideltay*(double)ideltay) > 2.0) {\r
+ /* circulate in space */\r
+ ideltax = d.isy-quady;\r
+ ideltay = quadx-d.isx;\r
+ }\r
+ }\r
+ else {\r
+ /* compute distances to starbases */\r
+ if (d.rembase <= 0) {\r
+ /* nothing left to do */\r
+ future[FSCMOVE] = 1e30;\r
+ return;\r
+ }\r
+ sx = d.isx;\r
+ sy = d.isy;\r
+ for (i = 1; i <= d.rembase; i++) {\r
+ basetbl[i] = i;\r
+ ibqx = d.baseqx[i];\r
+ ibqy = d.baseqy[i];\r
+ bdist[i] = sqrt(square(ibqx-sx) + square(ibqy-sy));\r
+ }\r
+ if (d.rembase > 1) {\r
+ /* sort into nearest first order */\r
+ int iswitch;\r
+ do {\r
+ iswitch = 0;\r
+ for (i=1; i < d.rembase-1; i++) {\r
+ if (bdist[i] > bdist[i+1]) {\r
+ int ti = basetbl[i];\r
+ double t = bdist[i];\r
+ bdist[i] = bdist[i+1];\r
+ bdist[i+1] = t;\r
+ basetbl[i] = basetbl[i+1];\r
+ basetbl[i+1] =ti;\r
+ iswitch = 1;\r
+ }\r
+ }\r
+ } while (iswitch);\r
+ }\r
+ /* look for nearest base without a commander, no Enterprise, and\r
+ without too many Klingons, and not already under attack. */\r
+ ifindit = iwhichb = 0;\r
+\r
+ for (i2 = 1; i2 <= d.rembase; i2++) {\r
+ i = basetbl[i2]; /* bug in original had it not finding nearest*/\r
+ ibqx = d.baseqx[i];\r
+ ibqy = d.baseqy[i];\r
+ if ((ibqx == quadx && ibqy == quady) ||\r
+ (ibqx == batx && ibqy == baty) ||\r
+ d.galaxy[ibqx][ibqy] > 899) continue;\r
+ /* if there is a commander, an no other base is appropriate,\r
+ we will take the one with the commander */\r
+ for (j = 1; j <= d.remcom; j++) {\r
+ if (ibqx==d.cx[j] && ibqy==d.cy[j] && ifindit!= 2) {\r
+ ifindit = 2;\r
+ iwhichb = i;\r
+ break;\r
+ }\r
+ }\r
+ if (j > d.remcom) { /* no commander -- use this one */\r
+ ifindit = 1;\r
+ iwhichb = i;\r
+ break;\r
+ }\r
+ }\r
+ if (ifindit==0) return; /* Nothing suitable -- wait until next time*/\r
+ ibqx = d.baseqx[iwhichb];\r
+ ibqy = d.baseqy[iwhichb];\r
+ /* decide how to move toward base */\r
+ ideltax = ibqx - d.isx;\r
+ ideltay = ibqy - d.isy;\r
+ }\r
+ /* Maximum movement is 1 quadrant in either or both axis */\r
+ if (ideltax > 1) ideltax = 1;\r
+ if (ideltax < -1) ideltax = -1;\r
+ if (ideltay > 1) ideltay = 1;\r
+ if (ideltay < -1) ideltay = -1;\r
+\r
+ /* try moving in both x and y directions */\r
+ iqx = d.isx + ideltax;\r
+ iqy = d.isy + ideltax;\r
+ if (checkdest(iqx, iqy, flag, ipage)) {\r
+ /* failed -- try some other maneuvers */\r
+ if (ideltax==0 || ideltay==0) {\r
+ /* attempt angle move */\r
+ if (ideltax != 0) {\r
+ iqy = d.isy + 1;\r
+ if (checkdest(iqx, iqy, flag, ipage)) {\r
+ iqy = d.isy - 1;\r
+ checkdest(iqx, iqy, flag, ipage);\r
+ }\r
+ }\r
+ else {\r
+ iqx = d.isx + 1;\r
+ if (checkdest(iqx, iqy, flag, ipage)) {\r
+ iqx = d.isx - 1;\r
+ checkdest(iqx, iqy, flag, ipage);\r
+ }\r
+ }\r
+ }\r
+ else {\r
+ /* try moving just in x or y */\r
+ iqy = d.isy;\r
+ if (checkdest(iqx, iqy, flag, ipage)) {\r
+ iqy = d.isy + ideltay;\r
+ iqx = d.isx;\r
+ checkdest(iqx, iqy, flag, ipage);\r
+ }\r
+ }\r
+ }\r
+ /* check for a base */\r
+ if (d.rembase == 0) {\r
+ future[FSCMOVE] = 1e30;\r
+ }\r
+ else for (i=1; i<=d.rembase; i++) {\r
+ ibqx = d.baseqx[i];\r
+ ibqy = d.baseqy[i];\r
+ if (ibqx==d.isx && ibqy == d.isy && d.isx != batx && d.isy != baty) {\r
+ /* attack the base */\r
+ if (flag) return; /* no, don't attack base! */\r
+ iseenit = 0;\r
+ isatb=1;\r
+ future[FSCDBAS] = d.date + 1.0 +2.0*Rand();\r
+ if (batx != 0) future[FSCDBAS] += future[FCDBAS]-d.date;\r
+ if (damage[DRADIO] > 0 && condit != IHDOCKED)\r
+ return; /* no warning */\r
+ iseenit = 1;\r
+ if (*ipage == 0) pause(1);\r
+ *ipage=1;\r
+ proutn("Lt. Uhura- \"Captain, the starbase in");\r
+ cramlc(1, d.isx, d.isy);\r
+ skip(1);\r
+ prout(" reports that it is under attack from the Klingon Super-commander.");\r
+ proutn(" It can survive until stardate ");\r
+ cramf(future[FSCDBAS], 0, 1);\r
+ prout(" .\"");\r
+ if (resting==0) return;\r
+ prout("Mr. Spock- \"Captain, shall we cancel the rest period?\"");\r
+ if (ja()==0) return;\r
+ resting = 0;\r
+ Time = 0.0; /* actually finished */\r
+ return;\r
+ }\r
+ }\r
+ /* Check for intelligence report */\r
+ if (\r
+#ifdef DEBUG\r
+ idebug==0 &&\r
+#endif\r
+ (Rand() > 0.2 ||\r
+ (damage[DRADIO] > 0.0 && condit != IHDOCKED) ||\r
+ starch[d.isx][d.isy] > 0))\r
+ return;\r
+ if (*ipage==0) pause(1);\r
+ *ipage = 1;\r
+ prout("Lt. Uhura- \"Captain, Starfleet Intelligence reports");\r
+ proutn(" the Super-commander is in");\r
+ cramlc(1, d.isx, d.isy);\r
+ prout(".\"");\r
+ return;\r
+}\r
+\r
+void movetho(void) {\r
+ int idx, idy, im, i, dum, my;\r
+ /* Move the Tholean */\r
+ if (ithere==0 || justin == 1) return;\r
+\r
+ if (ithx == 1 && ithy == 1) {\r
+ idx = 1; idy = 10;\r
+ }\r
+ else if (ithx == 1 && ithy == 10) {\r
+ idx = 10; idy = 10;\r
+ }\r
+ else if (ithx == 10 && ithy == 10) {\r
+ idx = 10; idy = 1;\r
+ }\r
+ else if (ithx == 10 && ithy == 1) {\r
+ idx = 1; idy = 1;\r
+ }\r
+ else {\r
+ /* something is wrong! */\r
+ ithere = 0;\r
+ return;\r
+ }\r
+\r
+ /* Do nothing if we are blocked */\r
+ if (quad[idx][idy]!= IHDOT && quad[idx][idy]!= IHWEB) return;\r
+ quad[ithx][ithy] = IHWEB;\r
+\r
+ if (ithx != idx) {\r
+ /* move in x axis */\r
+ im = fabs((double)idx - ithx)/((double)idx - ithx);\r
+ while (ithx != idx) {\r
+ ithx += im;\r
+ if (quad[ithx][ithy]==IHDOT) quad[ithx][ithy] = IHWEB;\r
+ }\r
+ }\r
+ else if (ithy != idy) {\r
+ /* move in y axis */\r
+ im = fabs((double)idy - ithy)/((double)idy - ithy);\r
+ while (ithy != idy) {\r
+ ithy += im;\r
+ if (quad[ithx][ithy]==IHDOT) quad[ithx][ithy] = IHWEB;\r
+ }\r
+ }\r
+ quad[ithx][ithy] = IHT;\r
+\r
+ /* check to see if all holes plugged */\r
+ for (i = 1; i < 11; i++) {\r
+ if (quad[1][i]!=IHWEB && quad[1][i]!=IHT) return;\r
+ if (quad[10][i]!=IHWEB && quad[10][i]!=IHT) return;\r
+ if (quad[i][1]!=IHWEB && quad[i][1]!=IHT) return;\r
+ if (quad[i][10]!=IHWEB && quad[i][10]!=IHT) return;\r
+ }\r
+ /* All plugged up -- Tholian splits */\r
+ quad[ithx][ithy]=IHWEB;\r
+ dropin(IHBLANK, &dum, &my);\r
+ crmena(1,IHT, 2, ithx, ithy);\r
+ prout(" completes web.");\r
+ ithere = ithx = ithy = 0;\r
+ return;\r
+}\r
--- /dev/null
+#include "sst.h"\r
+\r
+void sheild(int i) {\r
+ int key;\r
+ enum {NONE, SHUP, SHDN, NRG} action = NONE;\r
+\r
+ ididit = 0;\r
+\r
+ if (i == 2) action = SHUP;\r
+ else {\r
+ key = scan();\r
+ if (key == IHALPHA) {\r
+ if (isit("transfer"))\r
+ action = NRG;\r
+ else {\r
+ chew();\r
+ if (damage[DSHIELD]) {\r
+ prout("Shields damaged and down.");\r
+ return;\r
+ }\r
+ if (isit("up"))\r
+ action = SHUP;\r
+ else if (isit("down"))\r
+ action = SHDN;\r
+ }\r
+ }\r
+ if (action==NONE) {\r
+ proutn("Do you wish to change shield energy? ");\r
+ if (ja()) {\r
+ proutn("Energy to transfer to shields- ");\r
+ action = NRG;\r
+ }\r
+ else if (damage[DSHIELD]) {\r
+ prout("Shields damaged and down.");\r
+ return;\r
+ }\r
+ else if (shldup) {\r
+ proutn("Shields are up. Do you want them down? ");\r
+ if (ja()) action = SHDN;\r
+ else {\r
+ chew();\r
+ return;\r
+ }\r
+ }\r
+ else {\r
+ proutn("Shields are down. Do you want them up? ");\r
+ if (ja()) action = SHUP;\r
+ else {\r
+ chew();\r
+ return;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ switch (action) {\r
+ case SHUP: /* raise shields */\r
+ if (shldup) {\r
+ prout("Shields already up.");\r
+ return;\r
+ }\r
+ shldup = 1;\r
+ shldchg = 1;\r
+ if (condit != IHDOCKED) energy -= 50.0;\r
+ prout("Shields raised.");\r
+ if (energy <= 0) {\r
+ skip(1);\r
+ prout("Shields raising uses up last of energy.");\r
+ finish(FNRG);\r
+ return;\r
+ }\r
+ ididit=1;\r
+ return;\r
+ case SHDN:\r
+ if (shldup==0) {\r
+ prout("Shields already down.");\r
+ return;\r
+ }\r
+ shldup=0;\r
+ shldchg=1;\r
+ prout("Shields lowered.");\r
+ ididit=1;\r
+ return;\r
+ case NRG:\r
+ while (scan() != IHREAL) {\r
+ chew();\r
+ proutn("Energy to transfer to shields- ");\r
+ }\r
+ chew();\r
+ if (aaitem==0) return;\r
+ if (aaitem > energy) {\r
+ prout("Insufficient ship energy.");\r
+ return;\r
+ }\r
+ ididit = 1;\r
+ if (shield+aaitem >= inshld) {\r
+ prout("Shield energy maximized.");\r
+ if (shield+aaitem > inshld) {\r
+ prout("Excess energy requested returned to ship energy");\r
+ }\r
+ energy -= inshld-shield;\r
+ shield = inshld;\r
+ return;\r
+ }\r
+ if (aaitem < 0.0 && energy-aaitem > inenrg) {\r
+ /* Prevent shield drain loophole */\r
+ skip(1);\r
+ prout("Engineering to bridge--");\r
+ prout(" Scott here. Power circuit problem, Captain.");\r
+ prout(" I can't drain the shields.");\r
+ ididit = 0;\r
+ return;\r
+ }\r
+ if (shield+aaitem < 0) {\r
+ prout("All shield energy transferred to ship.");\r
+ energy += shield;\r
+ shield = 0.0;\r
+ return;\r
+ }\r
+ proutn("Scotty- \"");\r
+ if (aaitem > 0)\r
+ prout("Transferring energy to shields.\"");\r
+ else\r
+ prout("Draining energy from shields.\"");\r
+ shield += aaitem;\r
+ energy -= aaitem;\r
+ return;\r
+ }\r
+}\r
+\r
+void ram(int ibumpd, int ienm, int ix, int iy) {\r
+ double type = 1.0, extradm;\r
+ int icas, l;\r
+ \r
+ prouts("***RED ALERT! RED ALERT!");\r
+ skip(1);\r
+ prout("***COLLISION IMMINENT.");\r
+ skip(2);\r
+ proutn("***");\r
+ crmshp();\r
+ switch (ienm) {\r
+ case IHR: type = 1.5; break;\r
+ case IHC: type = 2.0; break;\r
+ case IHS: type = 2.5; break;\r
+ case IHT: type = 0.5; break;\r
+ }\r
+ proutn(ibumpd ? " rammed by " : " rams ");\r
+ crmena(0, ienm, 2, ix, iy);\r
+ if (ibumpd) proutn(" (original position)");\r
+ skip(1);\r
+ deadkl(ix, iy, ienm, sectx, secty);\r
+ proutn("***");\r
+ crmshp();\r
+ prout(" heavily damaged.");\r
+ icas = 10.0+20.0*Rand();\r
+ proutn("***Sickbay reports ");\r
+ crami(icas, 1);\r
+ prout(" casualties.");\r
+ casual += icas;\r
+ for (l=1; l <= ndevice; l++) {\r
+ if (l == DDRAY) continue; // Don't damage deathray \r
+ if (damage[l] < 0) continue;\r
+ extradm = (10.0*type*Rand()+1.0)*damfac;\r
+ damage[l] += Time + extradm; /* Damage for at least time of travel! */\r
+ }\r
+ shldup = 0;\r
+ if (d.remkl) {\r
+ pause(2);\r
+ dreprt();\r
+ }\r
+ else finish(FWON);\r
+ return;\r
+}\r
+\r
+void torpedo(double course, double r, int inx, int iny, double *hit) {\r
+ int l, iquad, ix, iy, jx, jy, shoved=0, ll;\r
+ double ac=course + 0.25*r;\r
+ double angle = (15.0-ac)*0.5235988;\r
+ double bullseye = (15.0 - course)*0.5235988;\r
+ double deltax=-sin(angle), deltay=cos(angle), x=inx, y=iny, bigger;\r
+ double ang, temp, xx, yy, kp, h1;\r
+\r
+ bigger = fabs(deltax);\r
+ if (fabs(deltay) > bigger) bigger = fabs(deltay);\r
+ deltax /= bigger;\r
+ deltay /= bigger;\r
+\r
+ /* Loop to move a single torpedo */\r
+ for (l=1; l <= 15; l++) {\r
+ x += deltax;\r
+ ix = x + 0.5;\r
+ if (ix < 1 || ix > 10) break;\r
+ y += deltay;\r
+ iy = y + 0.5;\r
+ if (iy < 1 || iy > 10) break;\r
+ if (l==4 || l==9) skip(1);\r
+ cramf(x, 0, 1);\r
+ proutn(" - ");\r
+ cramf(y, 0, 1);\r
+ proutn(" ");\r
+ iquad=quad[ix][iy];\r
+ if (iquad==IHDOT) continue;\r
+ /* hit something */\r
+ skip(1);\r
+ switch(iquad) {\r
+ case IHE: /* Hit our ship */\r
+ case IHF:\r
+ skip(1);\r
+ proutn("Torpedo hits ");\r
+ crmshp();\r
+ prout(".");\r
+ *hit = 700.0 + 100.0*Rand() -\r
+ 1000.0*sqrt(square(ix-inx)+square(iy-iny))*\r
+ fabs(sin(bullseye-angle));\r
+ *hit = fabs(*hit);\r
+ newcnd(); /* undock */\r
+ /* We may be displaced. */\r
+ if (landed==1) return; /* Cheat if on a planet */\r
+ ang = angle + 2.5*(Rand()-0.5);\r
+ temp = fabs(sin(ang));\r
+ if (fabs(cos(ang)) > temp) temp = fabs(cos(ang));\r
+ xx = -sin(ang)/temp;\r
+ yy = cos(ang)/temp;\r
+ jx=ix+xx+0.5;\r
+ jy=iy+yy+0.5;\r
+ if (jx<1 || jx>10 || jy<1 ||jy > 10) return;\r
+ if (quad[jx][jy]==IHBLANK) {\r
+ finish(FHOLE);\r
+ return;\r
+ }\r
+ if (quad[jx][jy]!=IHDOT) {\r
+ /* can't move into object */\r
+ return;\r
+ }\r
+ sectx = jx;\r
+ secty = jy;\r
+ crmshp();\r
+ shoved = 1;\r
+ break;\r
+ \r
+ case IHC: /* Hit a commander */\r
+ case IHS:\r
+ if (Rand() <= 0.05) {\r
+ crmena(1, iquad, 2, ix, iy);\r
+ prout(" uses anti-photon device;");\r
+ prout(" torpedo neutralized.");\r
+ return;\r
+ }\r
+ case IHR: /* Hit a regular enemy */\r
+ case IHK:\r
+ /* find the enemy */\r
+ for (ll=1; ll <= nenhere; ll++)\r
+ if (ix==kx[ll] && iy==ky[ll]) break;\r
+ kp = fabs(kpower[ll]);\r
+ h1 = 700.0 + 100.0*Rand() -\r
+ 1000.0*sqrt(square(ix-inx)+square(iy-iny))*\r
+ fabs(sin(bullseye-angle));\r
+ h1 = fabs(h1);\r
+ if (kp < h1) h1 = kp;\r
+ kpower[ll] -= (kpower[ll]<0 ? -h1 : h1);\r
+ if (kpower[ll] == 0) {\r
+ deadkl(ix, iy, iquad, ix, iy);\r
+ return;\r
+ }\r
+ crmena(1, iquad, 2, ix, iy);\r
+ /* If enemy damaged but not destroyed, try to displace */\r
+ ang = angle + 2.5*(Rand()-0.5);\r
+ temp = fabs(sin(ang));\r
+ if (fabs(cos(ang)) > temp) temp = fabs(cos(ang));\r
+ xx = -sin(ang)/temp;\r
+ yy = cos(ang)/temp;\r
+ jx=ix+xx+0.5;\r
+ jy=iy+yy+0.5;\r
+ if (jx<1 || jx>10 || jy<1 ||jy > 10) {\r
+ prout(" damaged but not destroyed.");\r
+ return;\r
+ }\r
+ if (quad[jx][jy]==IHBLANK) {\r
+ prout(" buffeted into black hole.");\r
+ deadkl(ix, iy, iquad, jx, jy);\r
+ return;\r
+ }\r
+ if (quad[jx][jy]!=IHDOT) {\r
+ /* can't move into object */\r
+ prout(" damaged but not destroyed.");\r
+ return;\r
+ }\r
+ prout(" damaged--");\r
+ kx[ll] = jx;\r
+ ky[ll] = jy;\r
+ shoved = 1;\r
+ break;\r
+ case IHB: /* Hit a base */\r
+ prout("***STARBASE DESTROYED..");\r
+ if (starch[quadx][quady] < 0) starch[quadx][quady] = 0;\r
+ for (ll=1; ll<=d.rembase; ll++) {\r
+ if (d.baseqx[ll]==quadx && d.baseqy[ll]==quady) {\r
+ d.baseqx[ll]=d.baseqx[d.rembase];\r
+ d.baseqy[ll]=d.baseqy[d.rembase];\r
+ break;\r
+ }\r
+ }\r
+ quad[ix][iy]=IHDOT;\r
+ d.rembase--;\r
+ basex=basey=0;\r
+ d.galaxy[quadx][quady] -= 10;\r
+ d.basekl++;\r
+ newcnd();\r
+ return;\r
+ case IHP: /* Hit a planet */\r
+ crmena(1, iquad, 2, ix, iy);\r
+ prout(" destroyed.");\r
+ d.nplankl++;\r
+ d.newstuf[quadx][quady] -= 1;\r
+ d.plnets[iplnet] = nulplanet;\r
+ iplnet = 0;\r
+ plnetx = plnety = 0;\r
+ quad[ix][iy] = IHDOT;\r
+ if (landed==1) {\r
+ /* captain parishes on planet */\r
+ finish(FDPLANET);\r
+ }\r
+ return;\r
+ case IHSTAR: /* Hit a star */\r
+ if (Rand() > 0.10) {\r
+ nova(ix, iy);\r
+ return;\r
+ }\r
+ crmena(1, IHSTAR, 2, ix, iy);\r
+ prout(" unaffected by photon blast.");\r
+ return;\r
+ case IHQUEST: /* Hit a thingy */\r
+ skip(1);\r
+ prouts("AAAAIIIIEEEEEEEEAAAAAAAAUUUUUGGGGGHHHHHHHHHHHH!!!");\r
+ skip(1);\r
+ prouts(" HACK! HACK! HACK! *CHOKE!* ");\r
+ skip(1);\r
+ proutn("Mr. Spock-");\r
+ prouts(" \"Facinating!\"");\r
+ skip(1);\r
+ quad[ix][iy] = IHDOT;\r
+ return;\r
+ case IHBLANK: /* Black hole */\r
+ skip(1);\r
+ crmena(1, IHBLANK, 2, ix, iy);\r
+ prout(" swallows torpedo.");\r
+ return;\r
+ case IHWEB: /* hit the web */\r
+ skip(1);\r
+ prout("***Torpedo absorbed by Tholian web.");\r
+ return;\r
+ case IHT: /* Hit a Tholian */\r
+ skip(1);\r
+ crmena(1, IHT, 2, ix, iy);\r
+ h1 = 700.0 + 100.0*Rand() -\r
+ 1000.0*sqrt(square(ix-inx)+square(iy-iny))*\r
+ fabs(sin(bullseye-angle));\r
+ h1 = fabs(h1);\r
+ if (h1 >= 600) {\r
+ prout(" destroyed.");\r
+ quad[ix][iy] = IHDOT;\r
+ ithere = 0;\r
+ ithx = ithy = 0;\r
+ return;\r
+ }\r
+ if (Rand() > 0.05) {\r
+ prout(" survives photon blast.");\r
+ return;\r
+ }\r
+ prout(" disappears.");\r
+ quad[ix][iy] = IHWEB;\r
+ ithere = ithx = ithy = 0;\r
+ {\r
+ int dum, my;\r
+ dropin(IHBLANK, &dum, &my);\r
+ }\r
+ return;\r
+ \r
+ default: /* Problem! */\r
+ skip(1);\r
+ proutn("Don't know how to handle collision with ");\r
+ crmena(1, iquad, 2, ix, iy);\r
+ skip(1);\r
+ return;\r
+ }\r
+ break;\r
+ }\r
+ if (shoved) {\r
+ quad[jx][jy]=iquad;\r
+ quad[ix][iy]=IHDOT;\r
+ proutn(" displaced by blast to");\r
+ cramlc(2, jx, jy);\r
+ skip(1);\r
+ for (ll=1; ll<=nenhere; ll++)\r
+ kdist[ll] = kavgd[ll] = sqrt(square(sectx-kx[ll])+square(secty-ky[ll]));\r
+ sortkl();\r
+ return;\r
+ }\r
+ skip(1);\r
+ prout("Torpedo missed.");\r
+ return;\r
+}\r
+\r
+static void fry(double hit) {\r
+ double ncrit, extradm;\r
+ int ktr=1, l, ll, j, cdam[6], crptr;\r
+\r
+ /* a critical hit occured */\r
+ if (hit < (275.0-25.0*skill)*(1.0+0.5*Rand())) return;\r
+\r
+ ncrit = 1.0 + hit/(500.0+100.0*Rand());\r
+ proutn("***CRITICAL HIT--");\r
+ /* Select devices and cause damage */\r
+ for (l = 1; l <= ncrit; l++) {\r
+ do {\r
+ j = ndevice*Rand()+1.0;\r
+ /* Cheat to prevent shuttle damage unless on ship */\r
+ } while (damage[j] < 0.0 || (j == DSHUTTL && iscraft != 1) ||\r
+ j == DDRAY);\r
+ cdam[l] = j;\r
+ extradm = (hit*damfac)/(ncrit*(75.0+25.0*Rand()));\r
+ damage[j] += extradm;\r
+ if (l > 1) {\r
+ for (ll=2; ll<=l && j != cdam[ll-1]; ll++) ;\r
+ if (ll<=l) continue;\r
+ ktr += 1;\r
+ if (ktr==3) skip(1);\r
+ proutn(" and ");\r
+ }\r
+ proutn(device[j]);\r
+ }\r
+ prout(" damaged.");\r
+ if (damage[DSHIELD] && shldup) {\r
+ prout("***Shields knocked down.");\r
+ shldup=0;\r
+ }\r
+}\r
+\r
+void attack(int k) {\r
+ /* k == 0 forces use of phasers in an attack */\r
+ int percent, ihurt=0, l, i=0, jx, jy, iquad, itflag;\r
+ int atackd = 0, attempt = 0;\r
+ double hit;\r
+ double pfac, dustfac, hitmax=0.0, hittot=0.0, chgfac=1.0, r;\r
+\r
+ iattak = 1;\r
+ if (alldone) return;\r
+#ifdef DEBUG\r
+ if (idebug) prout("ATTACK!");\r
+#endif\r
+\r
+ if (ithere) movetho();\r
+\r
+ if (neutz) { /* The one chance not to be attacked */\r
+ neutz = 0;\r
+ return;\r
+ }\r
+ if (((comhere || ishere) && (justin == 0)) || skill == 5) movcom();\r
+ if (nenhere==0) return;\r
+ pfac = 1.0/inshld;\r
+ if (shldchg == 1) chgfac = 0.25+0.5*Rand();\r
+ skip(1);\r
+ if (skill <= 2) i = 2;\r
+ for (l=1; l <= nenhere; l++) {\r
+ if (kpower[l] < 0) continue; /* too weak to attack */\r
+ /* compute hit strength and diminsh shield power */\r
+ r = Rand();\r
+ /* Increase chance of photon torpedos if docked or enemy energy low */\r
+ if (condit == IHDOCKED) r *= 0.25;\r
+ if (kpower[l] < 500) r *= 0.25; \r
+ jx = kx[l];\r
+ jy = ky[l];\r
+ iquad = quad[jx][jy];\r
+ itflag = (iquad == IHK && r > 0.0005) || k == 0 ||\r
+ (iquad==IHC && r > 0.015) ||\r
+ (iquad==IHR && r > 0.3) ||\r
+ (iquad==IHS && r > 0.07);\r
+ if (itflag) {\r
+ /* Enemy uses phasers */\r
+ if (condit == IHDOCKED) continue; /* Don't waste the effort! */\r
+ attempt = 1; /* Attempt to attack */\r
+ dustfac = 0.8+0.05*Rand();\r
+ hit = kpower[l]*pow(dustfac,kavgd[l]);\r
+ kpower[l] *= 0.75;\r
+ }\r
+ else { /* Enemy used photon torpedo */\r
+ double course = 1.90985*atan2((double)secty-jy, (double)jx-sectx);\r
+ hit = 0;\r
+ proutn("***TORPEDO INCOMING");\r
+ if (damage[DSRSENS] <= 0.0) {\r
+ proutn(" From ");\r
+ crmena(0, iquad, i, jx, jy);\r
+ }\r
+ attempt = 1;\r
+ prout("--");\r
+ r = (Rand()+Rand())*0.5 -0.5;\r
+ r += 0.002*kpower[l]*r;\r
+ torpedo(course, r, jx, jy, &hit);\r
+ if (d.remkl==0) finish(FWON); /* Klingons did themselves in! */\r
+ if (d.galaxy[quadx][quady] == 1000 ||\r
+ alldone) return; /* Supernova or finished */\r
+ if (hit == 0) continue;\r
+ }\r
+ if (shldup != 0 || shldchg != 0) {\r
+ /* shields will take hits */\r
+ double absorb, hitsh, propor = pfac*shield;\r
+ if(propor < 0.1) propor = 0.1;\r
+ hitsh = propor*chgfac*hit+1.0;\r
+ atackd=1;\r
+ absorb = 0.8*hitsh;\r
+ if (absorb > shield) absorb = shield;\r
+ shield -= absorb;\r
+ hit -= hitsh;\r
+ if (propor > 0.1 && hit < 0.005*energy) continue;\r
+ }\r
+ /* It's a hit -- print out hit size */\r
+ atackd = 1; /* We weren't going to check casualties, etc. if\r
+ shields were down for some strange reason. This\r
+ doesn't make any sense, so I've fixed it */\r
+ ihurt = 1;\r
+ cramf(hit, 0, 2);\r
+ proutn(" unit hit");\r
+ if ((damage[DSRSENS] > 0 && itflag) || skill <= 2) {\r
+ proutn(" on the ");\r
+ crmshp();\r
+ }\r
+ if (damage[DSRSENS] <= 0.0 && itflag) {\r
+ proutn(" from ");\r
+ crmena(0, iquad, i, jx, jy);\r
+ }\r
+ skip(1);\r
+ /* Decide if hit is critical */\r
+ if (hit > hitmax) hitmax = hit;\r
+ hittot += hit;\r
+ fry(hit);\r
+ printf("Hit %g energy %g\n", hit, energy);\r
+ energy -= hit;\r
+ }\r
+ if (energy <= 0) {\r
+ /* Returning home upon your shield, not with it... */\r
+ finish(FBATTLE);\r
+ return;\r
+ }\r
+ if (attempt == 0 && condit == IHDOCKED)\r
+ prout("***Enemies decide against attacking your ship.");\r
+ if (atackd == 0) return;\r
+ percent = 100.0*pfac*shield+0.5;\r
+ if (ihurt==0) {\r
+ /* Shields fully protect ship */\r
+ proutn("Enemy attack reduces shield strength to ");\r
+ }\r
+ else {\r
+ /* Print message if starship suffered hit(s) */\r
+ skip(1);\r
+ proutn("Energy left ");\r
+ cramf(energy, 0, 2);\r
+ proutn(" shields ");\r
+ if (shldup) proutn("up, ");\r
+ else if (damage[DSHIELD] == 0) proutn("down, ");\r
+ else proutn("damaged, ");\r
+ }\r
+ crami(percent, 1);\r
+ proutn("% torpedoes left ");\r
+ crami(torps, 1);\r
+ skip(1);\r
+ /* Check if anyone was hurt */\r
+ if (hitmax >= 200 || hittot >= 500) {\r
+ int icas= hittot*Rand()*0.015;\r
+ if (icas >= 2) {\r
+ skip(1);\r
+ proutn("Mc Coy- \"Sickbay to bridge. We suffered ");\r
+ crami(icas, 1);\r
+ prout(" casualties");\r
+ prout(" in that last attack.\"");\r
+ casual += icas;\r
+ }\r
+ }\r
+ /* After attack, reset average distance to enemies */\r
+ for (l = 1; l <= nenhere; l++)\r
+ kavgd[l] = kdist[l];\r
+ sortkl();\r
+ return;\r
+}\r
+ \r
+void deadkl(int ix, int iy, int type, int ixx, int iyy) {\r
+ /* Added ixx and iyy allow enemy to "move" before dying */\r
+\r
+ int i,j;\r
+ \r
+ crmena(1, type, 2, ixx, iyy);\r
+ /* Decide what kind of enemy it is and update approriately */\r
+ if (type == IHR) {\r
+ /* chalk up a Romulan */\r
+ d.newstuf[quadx][quady] -= 10;\r
+ irhere--;\r
+ d.nromkl++;\r
+ d.nromrem--;\r
+ }\r
+ else if (type == IHT) {\r
+ /* Killed a Tholean */\r
+ ithere = 0;\r
+ }\r
+ else {\r
+ /* Some type of a Klingon */\r
+ d.galaxy[quadx][quady] -= 100;\r
+ klhere--;\r
+ d.remkl--;\r
+ switch (type) {\r
+ case IHC:\r
+ comhere = 0;\r
+ for (i=1; i<=d.remcom; i++)\r
+ if (d.cx[i]==quadx && d.cy[i]==quady) break;\r
+ d.cx[i] = d.cx[d.remcom];\r
+ d.cy[i] = d.cy[d.remcom];\r
+ d.cx[d.remcom] = 0;\r
+ d.cy[d.remcom] = 0;\r
+ d.remcom--;\r
+ future[FTBEAM] = 1e30;\r
+ if (d.remcom != 0)\r
+ future[FTBEAM] = d.date + expran(1.0*incom/d.remcom);\r
+ d.killc++;\r
+ break;\r
+ case IHK:\r
+ d.killk++;\r
+ break;\r
+ case IHS:\r
+ d.nscrem = ishere = d.isx = d.isy = isatb = iscate = 0;\r
+ d.nsckill = 1;\r
+ future[FSCMOVE] = future[FSCDBAS] = 1e30;\r
+ break;\r
+ }\r
+ }\r
+\r
+ /* For each kind of enemy, finish message to player */\r
+ prout(" destroyed.");\r
+ quad[ix][iy] = IHDOT;\r
+ if (d.remkl==0) return;\r
+\r
+ d.remtime = d.remres/(d.remkl + 4*d.remcom);\r
+\r
+ if (type == IHT) return;\r
+\r
+ /* Remove enemy ship from arrays describing local conditions */\r
+\r
+ for (i=1; i<=nenhere; i++)\r
+ if (kx[i]==ix && ky[i]==iy) break;\r
+ nenhere--;\r
+ if (i <= nenhere) {\r
+ for (j=i; j<=nenhere; j++) {\r
+ kx[j] = kx[j+1];\r
+ ky[j] = ky[j+1];\r
+ kpower[j] = kpower[j+1];\r
+ kavgd[j] = kdist[j] = kdist[j+1];\r
+ }\r
+ }\r
+ kx[nenhere+1] = 0;\r
+ ky[nenhere+1] = 0;\r
+ kdist[nenhere+1] = 0;\r
+ kavgd[nenhere+1] = 0;\r
+ kpower[nenhere+1] = 0;\r
+ return;\r
+}\r
+\r
+static int targetcheck(double x, double y, double *course) {\r
+ double deltx, delty;\r
+ /* Return TRUE if target is invalid */\r
+ if (x < 1.0 || x > 10.0 || y < 1.0 || y > 10.0) {\r
+ huh();\r
+ return 1;\r
+ }\r
+ deltx = 0.1*(y - secty);\r
+ delty = 0.1*(sectx - x);\r
+ if (deltx==0 && delty== 0) {\r
+ skip(1);\r
+ prout("Spock- \"Bridge to sickbay. Dr. McCoy,");\r
+ prout(" I recommend an immediate review of");\r
+ prout(" the Captain's psychological profile.");\r
+ chew();\r
+ return 1;\r
+ }\r
+ *course = 1.90985932*atan2(deltx, delty);\r
+ return 0;\r
+}\r
+\r
+void photon(void) {\r
+ double targ[4][3], course[4];\r
+ double r, dummy;\r
+ int key, n, i, osuabor;\r
+\r
+ ididit = 0;\r
+\r
+ if (damage[DPHOTON]) {\r
+ prout("Photon tubes damaged.");\r
+ chew();\r
+ return;\r
+ }\r
+ if (torps == 0) {\r
+ prout("No torpedoes left.");\r
+ chew();\r
+ return;\r
+ }\r
+ key = scan();\r
+ for (;;) {\r
+ if (key == IHALPHA) {\r
+ huh();\r
+ return;\r
+ }\r
+ else if (key == IHEOL) {\r
+ crami(torps,1);\r
+ prout(" torpedoes left.");\r
+ proutn("Number of torpedoes to fire- ");\r
+ key = scan();\r
+ }\r
+ else /* key == IHREAL */ {\r
+ n = aaitem + 0.5;\r
+ if (n <= 0) { /* abort command */\r
+ chew();\r
+ return;\r
+ }\r
+ if (n > 3) {\r
+ chew();\r
+ prout("Maximum of 3 torpedoes per burst.");\r
+ key = IHEOL;\r
+ }\r
+ if (n <= torps) break;\r
+ chew();\r
+ key = IHEOL;\r
+ }\r
+ }\r
+ for (i = 1; i <= n; i++) {\r
+ key = scan();\r
+ if (i==1 && key == IHEOL) {\r
+ break; /* we will try prompting */\r
+ }\r
+ if (i==2 && key == IHEOL) {\r
+ /* direct all torpedoes at one target */\r
+ while (i <= n) {\r
+ targ[i][1] = targ[1][1];\r
+ targ[i][2] = targ[1][2];\r
+ course[i] = course[1];\r
+ i++;\r
+ }\r
+ break;\r
+ }\r
+ if (key != IHREAL) {\r
+ huh();\r
+ return;\r
+ }\r
+ targ[i][1] = aaitem;\r
+ key = scan();\r
+ if (key != IHREAL) {\r
+ huh();\r
+ return;\r
+ }\r
+ targ[i][2] = aaitem;\r
+ if (targetcheck(targ[i][1], targ[i][2], &course[i])) return;\r
+ }\r
+ chew();\r
+ if (i == 1 && key == IHEOL) {\r
+ /* prompt for each one */\r
+ for (i = 1; i <= n; i++) {\r
+ proutn("Target sector for torpedo number");\r
+ crami(i, 2);\r
+ proutn("- ");\r
+ key = scan();\r
+ if (key != IHREAL) {\r
+ huh();\r
+ return;\r
+ }\r
+ targ[i][1] = aaitem;\r
+ key = scan();\r
+ if (key != IHREAL) {\r
+ huh();\r
+ return;\r
+ }\r
+ targ[i][2] = aaitem;\r
+ chew();\r
+ if (targetcheck(targ[i][1], targ[i][2], &course[i])) return;\r
+ }\r
+ }\r
+ ididit = 1;\r
+ /* Loop for moving <n> torpedoes */\r
+ osuabor = 0;\r
+ for (i = 1; i <= n && !osuabor; i++) {\r
+ if (condit != IHDOCKED) torps--;\r
+ r = (Rand()+Rand())*0.5 -0.5;\r
+ if (fabs(r) >= 0.47) {\r
+ /* misfire! */\r
+ r = (Rand()+1.2) * r;\r
+ if (n>1) {\r
+ prouts("***TORPEDO NUMBER");\r
+ crami(i, 2);\r
+ prouts(" MISFIRES.");\r
+ }\r
+ else prouts("***TORPEDO MISFIRES.");\r
+ skip(1);\r
+ if (i < n)\r
+ prout(" Remainder of burst aborted.");\r
+ osuabor=1;\r
+ if (Rand() <= 0.2) {\r
+ prout("***Photon tubes damaged by misfire.");\r
+ damage[DPHOTON] = damfac*(1.0+2.0*Rand());\r
+ break;\r
+ }\r
+ }\r
+ if (shldup != 0 || condit == IHDOCKED) r *= 1.0 + 0.0001*shield;\r
+ if (n != 1) {\r
+ skip(1);\r
+ proutn("Track for torpedo number");\r
+ crami(i, 2);\r
+ proutn("- ");\r
+ }\r
+ else {\r
+ skip(1);\r
+ proutn("Torpedo track- ");\r
+ }\r
+ torpedo(course[i], r, sectx, secty, &dummy);\r
+ if (alldone || d.galaxy[quadx][quady]==1000) return;\r
+ }\r
+ if (d.remkl==0) finish(FWON);\r
+}\r
+\r
+ \r
+\r
+static void overheat(double rpow) {\r
+ if (rpow > 1500) {\r
+ double chekbrn = (rpow-1500.)*0.00038;\r
+ if (Rand() <= chekbrn) {\r
+ prout("Weapons officer Sulu- \"Phasers overheated, sir.\"");\r
+ damage[DPHASER] = damfac*(1.0 + Rand()) * (1.0+chekbrn);\r
+ }\r
+ }\r
+}\r
+\r
+static int checkshctrl(double rpow) {\r
+ double hit;\r
+ int icas;\r
+ \r
+ skip(1);\r
+ if (Rand() < .998) {\r
+ prout("Shields lowered.");\r
+ return 0;\r
+ }\r
+ /* Something bad has happened */\r
+ prouts("***RED ALERT! RED ALERT!");\r
+ skip(2);\r
+ hit = rpow*shield/inshld;\r
+ energy -= rpow+hit*0.8;\r
+ shield -= hit*0.2;\r
+ if (energy <= 0.0) {\r
+ prouts("Sulu- \"Captain! Shield malf***********************\"");\r
+ skip(1);\r
+ stars();\r
+ finish(FPHASER);\r
+ return 1;\r
+ }\r
+ prouts("Sulu- \"Captain! Shield malfunction! Phaser fire contained!\"");\r
+ skip(2);\r
+ prout("Lt. Uhura- \"Sir, all decks reporting damage.\"");\r
+ icas = hit*Rand()*0.012;\r
+ skip(1);\r
+ fry(0.8*hit);\r
+ if (icas) {\r
+ skip(1);\r
+ prout("McCoy to bridge- \"Severe radiation burns, Jim.");\r
+ proutn(" ");\r
+ crami(icas, 1);\r
+ prout(" casualties so far.\"");\r
+ casual -= icas;\r
+ }\r
+ skip(1);\r
+ prout("Phaser energy dispersed by shields.");\r
+ prout("Enemy unaffected.");\r
+ overheat(rpow);\r
+ return 1;\r
+}\r
+ \r
+\r
+void phasers(void) {\r
+ double hits[21], rpow, extra, powrem, over, temp;\r
+ int kz = 0, k=1, i; /* Cheating inhibitor */\r
+ int ifast=0, no=0, ipoop=1, msgflag = 1;\r
+ enum {NOTSET, MANUAL, FORCEMAN, AUTOMATIC} automode = NOTSET;\r
+ int key;\r
+\r
+ skip(1);\r
+ /* SR sensors and Computer */\r
+ if (damage[DSRSENS]+damage[DCOMPTR] > 0) ipoop = 0;\r
+ if (condit == IHDOCKED) {\r
+ prout("Phasers can't be fired through base shields.");\r
+ chew();\r
+ return;\r
+ }\r
+ if (damage[DPHASER] != 0) {\r
+ prout("Phaser control damaged.");\r
+ chew();\r
+ return;\r
+ }\r
+ if (shldup) {\r
+ if (damage[DSHCTRL]) {\r
+ prout("High speed shield control damaged.");\r
+ chew();\r
+ return;\r
+ }\r
+ if (energy <= 200.0) {\r
+ prout("Insufficient energy to activate high-speed shield control.");\r
+ chew();\r
+ return;\r
+ }\r
+ prout("Weapons Officer Sulu- \"High-speed shield control enabled, sir.\"");\r
+ ifast = 1;\r
+ \r
+ }\r
+ ididit = 1;\r
+ /* Original code so convoluted, I re-did it all */\r
+ while (automode==NOTSET) {\r
+ key=scan();\r
+ if (key == IHALPHA) {\r
+ if (isit("manual")) {\r
+ if (nenhere==0) {\r
+ prout("There is no enemy present to select.");\r
+ chew();\r
+ key = IHEOL;\r
+ automode=AUTOMATIC;\r
+ }\r
+ else {\r
+ automode = MANUAL;\r
+ key = scan();\r
+ }\r
+ }\r
+ else if (isit("automatic")) {\r
+ if ((!ipoop) && nenhere != 0) {\r
+ automode = FORCEMAN;\r
+ }\r
+ else {\r
+ if (nenhere==0)\r
+ prout("Energy will be expended into space.");\r
+ automode = AUTOMATIC;\r
+ key = scan();\r
+ }\r
+ }\r
+ else if (isit("no")) {\r
+ no = 1;\r
+ }\r
+ else {\r
+ huh();\r
+ ididit = 0;\r
+ return;\r
+ }\r
+ }\r
+ else if (key == IHREAL) {\r
+ if (nenhere==0) {\r
+ prout("Energy will be expended into space.");\r
+ automode = AUTOMATIC;\r
+ }\r
+ else if (!ipoop)\r
+ automode = FORCEMAN;\r
+ else\r
+ automode = AUTOMATIC;\r
+ }\r
+ else {\r
+ /* IHEOL */\r
+ if (nenhere==0) {\r
+ prout("Energy will be expended into space.");\r
+ automode = AUTOMATIC;\r
+ }\r
+ else if (!ipoop)\r
+ automode = FORCEMAN;\r
+ else \r
+ proutn("Manual or automatic? ");\r
+ }\r
+ }\r
+ \r
+ switch (automode) {\r
+ case AUTOMATIC:\r
+ if (key == IHALPHA && isit("no")) {\r
+ no = 1;\r
+ key = scan();\r
+ }\r
+ if (key != IHREAL && nenhere != 0) {\r
+ proutn("Phasers locked on target. Energy available =");\r
+ cramf(ifast?energy-200.0:energy,1,2);\r
+ skip(1);\r
+ }\r
+ do {\r
+ while (key != IHREAL) {\r
+ chew();\r
+ proutn("Units to fire=");\r
+ key = scan();\r
+ }\r
+ rpow = aaitem;\r
+ if (rpow >= (ifast?energy-200:energy)) {\r
+ proutn("Energy available= ");\r
+ cramf(ifast?energy-200:energy, 1,2);\r
+ skip(1);\r
+ key = IHEOL;\r
+ }\r
+ } while (rpow >= (ifast?energy-200:energy));\r
+ if (rpow<=0) {\r
+ /* chicken out */\r
+ ididit = 0;\r
+ chew();\r
+ return;\r
+ }\r
+ if ((key=scan()) == IHALPHA && isit("no")) {\r
+ no = 1;\r
+ }\r
+ if (ifast) {\r
+ energy -= 200; /* Go and do it! */\r
+ if (checkshctrl(rpow)) return;\r
+ }\r
+ chew();\r
+ energy -= rpow;\r
+ extra = rpow;\r
+ if (nenhere) {\r
+ extra = 0.0;\r
+ powrem = rpow;\r
+ for (i = 1; i <= nenhere; i++) {\r
+ hits[i] = 0.0;\r
+ if (powrem <= 0) continue;\r
+ hits[i] = fabs(kpower[i])/(phasefac*pow(0.90,kdist[i]));\r
+ over = (0.01 + 0.05*Rand())*hits[i];\r
+ temp = powrem;\r
+ powrem -= hits[i] + over;\r
+ if (powrem <= 0 && temp < hits[i]) hits[i] = temp;\r
+ if (powrem <= 0) over = 0.0;\r
+ extra += over;\r
+ }\r
+ if (powrem > 0.0) extra += powrem;\r
+ hittem(hits);\r
+ }\r
+ if (extra > 0 && alldone == 0) {\r
+ if (ithere) {\r
+ proutn("*** Tholian web absorbs ");\r
+ if (nenhere>0) proutn("excess ");\r
+ prout("phaser energy.");\r
+ }\r
+ else {\r
+ cramf(extra, 0, 2);\r
+ prout(" expended on empty space.");\r
+ }\r
+ }\r
+ break;\r
+\r
+ case FORCEMAN:\r
+ chew();\r
+ key = IHEOL;\r
+ if (damage[DCOMPTR]!=0)\r
+ prout("Battle comuter damaged, manual file only.");\r
+ else {\r
+ skip(1);\r
+ prouts("---WORKING---");\r
+ skip(1);\r
+ prout("Short-range-sensors-damaged");\r
+ prout("Insufficient-data-for-automatic-phaser-fire");\r
+ prout("Manual-fire-must-be-used");\r
+ skip(1);\r
+ }\r
+ case MANUAL:\r
+ rpow = 0.0;\r
+ for (k = 1; k <= nenhere;) {\r
+ int ii = kx[k], jj = ky[k];\r
+ int ienm = quad[ii][jj];\r
+ if (msgflag) {\r
+ proutn("Energy available= ");\r
+ cramf(energy-.006-(ifast?200:0), 0, 2);\r
+ skip(1);\r
+ msgflag = 0;\r
+ rpow = 0.0;\r
+ }\r
+ if (damage[DSRSENS] && !(abs(sectx-ii) < 2 && abs(secty-jj) < 2) &&\r
+ (ienm == IHC || ienm == IHS)) {\r
+ cramen(ienm);\r
+ prout(" can't be located without short range scan.");\r
+ chew();\r
+ key = IHEOL;\r
+ hits[k] = 0; /* prevent overflow -- thanks to Alexei Voitenko */\r
+ k++;\r
+ continue;\r
+ }\r
+ if (key == IHEOL) {\r
+ chew();\r
+ if (ipoop && k > kz) {\r
+ int irec=(fabs(kpower[k])/(phasefac*pow(0.9,kdist[k])))*\r
+ (1.01+0.05*Rand()) + 1.0;\r
+ kz = k;\r
+ proutn("(");\r
+ crami(irec, 1);\r
+ proutn(") ");\r
+ }\r
+ proutn("units to fire at ");\r
+ crmena(0, ienm, 2, ii, jj);\r
+ proutn("- ");\r
+ key = scan();\r
+ }\r
+ if (key == IHALPHA && isit("no")) {\r
+ no = 1;\r
+ key = scan();\r
+ continue;\r
+ }\r
+ if (key == IHALPHA) {\r
+ huh();\r
+ ididit = 0;\r
+ return;\r
+ }\r
+ if (key == IHEOL) {\r
+ if (k==1) { /* Let me say I'm baffled by this */\r
+ msgflag = 1;\r
+ }\r
+ continue;\r
+ }\r
+ if (aaitem < 0) {\r
+ /* abort out */\r
+ ididit = 0;\r
+ chew();\r
+ return;\r
+ }\r
+ hits[k] = aaitem;\r
+ rpow += aaitem;\r
+ /* If total requested is too much, inform and start over */\r
+ \r
+ if (rpow >= (ifast?energy-200:energy)) {\r
+ prout("Available energy exceeded -- try again.");\r
+ chew();\r
+ key = IHEOL;\r
+ k = 1;\r
+ msgflag = 1;\r
+ continue;\r
+ }\r
+ key = scan(); /* scan for next value */\r
+ k++;\r
+ }\r
+ if (rpow == 0.0) {\r
+ /* zero energy -- abort */\r
+ ididit = 0;\r
+ chew();\r
+ return;\r
+ }\r
+ if (key == IHALPHA & isit("no")) {\r
+ no = 1;\r
+ }\r
+ energy -= rpow;\r
+ chew();\r
+ if (ifast) {\r
+ energy -= 200.0;\r
+ if (checkshctrl(rpow)) return;\r
+ }\r
+ hittem(hits);\r
+ ididit=1;\r
+ }\r
+ /* Say shield raised or malfunction, if necessary */\r
+ if (alldone) return;\r
+ if (ifast) {\r
+ skip(1);\r
+ if (no == 0) {\r
+ if (Rand() >= 0.99) {\r
+ prout("Sulu- \"Sir, the high-speed shield control has malfunctioned . . .");\r
+ prouts(" CLICK CLICK POP . . .");\r
+ prout(" No response, sir!");\r
+ shldup = 0;\r
+ }\r
+ else\r
+ prout("Shields raised.");\r
+ }\r
+ else\r
+ shldup = 0;\r
+ }\r
+ overheat(rpow);\r
+}\r
+\r
+void hittem(double *hits) {\r
+ double kp, kpow, wham, hit, dustfac, kpini;\r
+ int nenhr2=nenhere, k=1, kk=1, ii, jj, ienm;\r
+\r
+ skip(1);\r
+\r
+ for (; k <= nenhr2; k++, kk++) {\r
+ if ((wham = hits[k])==0) continue;\r
+ dustfac = 0.9 + 0.01*Rand();\r
+ hit = wham*pow(dustfac,kdist[kk]);\r
+ kpini = kpower[kk];\r
+ kp = fabs(kpini);\r
+ if (phasefac*hit < kp) kp = phasefac*hit;\r
+ kpower[kk] -= (kpower[kk] < 0 ? -kp: kp);\r
+ kpow = kpower[kk];\r
+ ii = kx[kk];\r
+ jj = ky[kk];\r
+ if (hit > 0.005) {\r
+ cramf(hit, 0, 2);\r
+ proutn(" unit hit on ");\r
+ }\r
+ else\r
+ proutn("Very small hit on ");\r
+ ienm = quad[ii][jj];\r
+ crmena(0,ienm,2,ii,jj);\r
+ skip(1);\r
+ if (kpow == 0) {\r
+ deadkl(ii, jj, ienm, ii, jj);\r
+ if (d.remkl==0) finish(FWON);\r
+ if (alldone) return;\r
+ kk--; /* don't do the increment */\r
+ }\r
+ else /* decide whether or not to emasculate klingon */\r
+ if (kpow > 0 && Rand() >= 0.9 &&\r
+ kpow <= ((0.4 + 0.4*Rand())*kpini)) {\r
+ proutn("***Mr. Spock- \"Captain, the vessel at");\r
+ cramlc(2,ii,jj);\r
+ skip(1);\r
+ prout(" has just lost its firepower.\"");\r
+ kpower[kk] = -kpow;\r
+ }\r
+ }\r
+ return;\r
+}\r
+\r
--- /dev/null
+#include "sst.h"\r
+#include <math.h>\r
+\r
+void events(void) {\r
+\r
+ int ictbeam=0, ipage=0, istract=0, line, i, j, k, l, ixhold, iyhold;\r
+ double fintim = d.date + Time, datemin, xtime, repair, yank;\r
+ \r
+\r
+#ifdef DEBUG\r
+ if (idebug) prout("EVENTS");\r
+#endif\r
+\r
+ if (stdamtim == 1e30 && damage[DRADIO] != 0.0) {\r
+ /* chart will no longer be updated because radio is dead */\r
+ stdamtim = d.date;\r
+ for (i=1; i <= 8 ; i++)\r
+ for (j=1; j <= 8; j++)\r
+ if (starch[i][j] == 1) starch[i][j] = d.galaxy[i][j]+1000;\r
+ }\r
+\r
+ for (;;) {\r
+ /* Select earliest extraneous event, line==0 if no events */\r
+ line = FSPY;\r
+ if (alldone) return;\r
+ datemin = fintim;\r
+ for (l=1; l<=NEVENTS; l++)\r
+ if (future[l] <= datemin) {\r
+ line = l;\r
+ datemin = future[l];\r
+ }\r
+ xtime = datemin-d.date;\r
+ d.date = datemin;\r
+ /* Decrement Federation resources and recompute remaining time */\r
+ d.remres -= (d.remkl+4*d.remcom)*xtime;\r
+ d.remtime = d.remres/(d.remkl+4*d.remcom);\r
+ if (d.remtime <=0) {\r
+ finish(FDEPLETE);\r
+ return;\r
+ }\r
+ /* Is life support adequate? */\r
+ if (damage[DLIFSUP] && condit != IHDOCKED) {\r
+ if (lsupres < xtime && damage[DLIFSUP] > lsupres) {\r
+ finish(FLIFESUP);\r
+ return;\r
+ }\r
+ lsupres -= xtime;\r
+ if (damage[DLIFSUP] <= xtime) lsupres = inlsr;\r
+ }\r
+ /* Fix devices */\r
+ repair = xtime;\r
+ if (condit == IHDOCKED) repair /= docfac;\r
+ /* Don't fix Deathray here */\r
+ for (l=1; l<=ndevice; l++)\r
+ if (damage[l] > 0.0 && l != DDRAY)\r
+ damage[l] -= (damage[l]-repair > 0.0 ? repair : damage[l]);\r
+ /* If radio repaired, update star chart and attack reports */\r
+ if (stdamtim != 1e30 && damage[DRADIO] == 0.0) {\r
+ stdamtim = 1e30;\r
+ prout("Lt. Uhura- \"Captain, the sub-space radio is working and");\r
+ prout(" surveillance reports are coming in.");\r
+ skip(1);\r
+ for (i=1; i <= 8 ; i++)\r
+ for (j=1; j <= 8; j++)\r
+ if (starch[i][j] > 999) starch[i][j] = 1;\r
+ if (iseenit==0) {\r
+ attakreport();\r
+ iseenit = 1;\r
+ }\r
+ skip(1);\r
+ prout(" The star chart is now up to date.\"");\r
+ skip(1);\r
+ }\r
+ /* Cause extraneous event LINE to occur */\r
+ Time -= xtime;\r
+ switch (line) {\r
+ case FSNOVA: /* Supernova */\r
+ if (ipage==0) pause(1);\r
+ ipage=1;\r
+ snova(0,0);\r
+ future[FSNOVA] = d.date + expran(0.5*intime);\r
+ if (d.galaxy[quadx][quady] == 1000) return;\r
+ break;\r
+ case FSPY: /* Check with spy to see if S.C. should tractor beam */\r
+ if (d.nscrem == 0 ||\r
+ ictbeam+istract > 0 ||\r
+ condit==IHDOCKED || isatb==1 || iscate==1) return;\r
+ if (ientesc ||\r
+ (energy < 2000 && torps < 4 && shield < 1250) ||\r
+ (damage[DPHASER]>0 && (damage[DPHOTON]>0 || torps < 4)) ||\r
+ (damage[DSHIELD] > 0 &&\r
+ (energy < 2500 || damage[DPHASER] > 0) &&\r
+ (torps < 5 || damage[DPHOTON] > 0))) {\r
+ /* Tractor-beam her! */\r
+ istract=1;\r
+ yank = square(d.isx-quadx) + square(d.isy-quady);\r
+ /*********TBEAM CODE***********/\r
+ }\r
+ else return;\r
+ case FTBEAM: /* Tractor beam */\r
+ if (line==FTBEAM) {\r
+ if (d.remcom == 0) {\r
+ future[FTBEAM] = 1e30;\r
+ break;\r
+ }\r
+ i = Rand()*d.remcom+1.0;\r
+ yank = square(d.cx[i]-quadx) + square(d.cy[i]-quady);\r
+ if (istract || condit == IHDOCKED || yank == 0) {\r
+ /* Drats! Have to reschedule */\r
+ future[FTBEAM] = d.date + Time +\r
+ expran(1.5*intime/d.remcom);\r
+ break;\r
+ }\r
+ }\r
+ /* tractor beaming cases merge here */\r
+ yank = sqrt(yank);\r
+ if (ipage==0) pause(1);\r
+ ipage=1;\r
+ Time = (10.0/(7.5*7.5))*yank; /* 7.5 is yank rate (warp 7.5) */\r
+ ictbeam = 1;\r
+ skip(1);\r
+ proutn("***");\r
+ crmshp();\r
+ prout(" caught in long range tractor beam--");\r
+ /* If Kirk & Co. screwing around on planet, handle */\r
+ atover(1); /* atover(1) is Grab */\r
+ if (alldone) return;\r
+ if (icraft == 1) { /* Caught in Galileo? */\r
+ finish(FSTRACTOR);\r
+ return;\r
+ }\r
+ /* Check to see if shuttle is aboard */\r
+ if (iscraft==0) {\r
+ skip(1);\r
+ if (Rand() >0.5) {\r
+ prout("Galileo, left on the planet surface, is captured");\r
+ prout("by aliens and made into a flying McDonald's.");\r
+ damage[DSHUTTL] = -10;\r
+ iscraft = -1;\r
+ }\r
+ else {\r
+ prout("Galileo, left on the planet surface, is well hidden.");\r
+ }\r
+ }\r
+ if (line==0) {\r
+ quadx = d.isx;\r
+ quady = d.isy;\r
+ }\r
+ else {\r
+ quadx = d.cx[i];\r
+ quady = d.cy[i];\r
+ }\r
+ iran10(§x, §y);\r
+ crmshp();\r
+ proutn(" is pulled to");\r
+ cramlc(1, quadx, quady);\r
+ proutn(", ");\r
+ cramlc(2, sectx, secty);\r
+ skip(1);\r
+ if (resting) {\r
+ prout("(Remainder of rest/repair period cancelled.)");\r
+ resting = 0;\r
+ }\r
+ if (shldup==0) {\r
+ if (damage[DSHIELD]==0 && shield > 0) {\r
+ sheild(2); /* Shldsup */\r
+ shldchg=0;\r
+ }\r
+ else prout("(Shields not currently useable.)");\r
+ }\r
+ newqad(0);\r
+ /* Adjust finish time to time of tractor beaming */\r
+ fintim = d.date+Time;\r
+ if (d.remcom <= 0) future[FTBEAM] = 1e30;\r
+ else future[FTBEAM] = d.date+Time+expran(1.5*intime/d.remcom);\r
+ break;\r
+ case FSNAP: /* Snapshot of the universe (for time warp) */\r
+ snapsht = d;\r
+ d.snap = 1;\r
+ future[FSNAP] = d.date + expran(0.5 * intime);\r
+ break;\r
+ case FBATTAK: /* Commander attacks starbase */\r
+ if (d.remcom==0 || d.rembase==0) {\r
+ /* no can do */\r
+ future[FBATTAK] = future[FCDBAS] = 1e30;\r
+ break;\r
+ }\r
+ i = 0;\r
+ for (j=1; j<=d.rembase; j++) {\r
+ for (k=1; k<=d.remcom; k++)\r
+ if (d.baseqx[j]==d.cx[k] && d.baseqy[j]==d.cy[k] &&\r
+ (d.baseqx[j]!=quadx || d.baseqy[j]!=quady) &&\r
+ (d.baseqx[j]!=d.isx || d.baseqy[j]!=d.isy)) {\r
+ i = 1;\r
+ break;\r
+ }\r
+ if (i == 1) break;\r
+ }\r
+ if (j>d.rembase) {\r
+ /* no match found -- try later */\r
+ future[FBATTAK] = d.date + expran(0.3*intime);\r
+ future[FCDBAS] = 1e30;\r
+ break;\r
+ }\r
+ /* commander + starbase combination found -- launch attack */\r
+ batx = d.baseqx[j];\r
+ baty = d.baseqy[j];\r
+ future[FCDBAS] = d.date+1.0+3.0*Rand();\r
+ if (isatb) /* extra time if SC already attacking */\r
+ future[FCDBAS] += future[FSCDBAS]-d.date;\r
+ future[FBATTAK] = future[FCDBAS] +expran(0.3*intime);\r
+ iseenit = 0;\r
+ if (damage[DRADIO] != 0.0 &&\r
+ condit != IHDOCKED) break; /* No warning :-( */\r
+ iseenit = 1;\r
+ if (ipage==0) pause(1);\r
+ ipage = 1;\r
+ skip(1);\r
+ proutn("Lt. Uhura- \"Captain, the starbase in");\r
+ cramlc(1, batx, baty);\r
+ skip(1);\r
+ prout(" reports that it is under atttack and that it can");\r
+ proutn(" hold out only until stardate ");\r
+ cramf(future[FCDBAS],1,1);\r
+ prout(".\"");\r
+ if (resting) {\r
+ skip(1);\r
+ proutn("Mr. Spock- \"Captain, shall we cancel the rest period?\"");\r
+ if (ja()) {\r
+ resting = 0;\r
+ Time = 0.0;\r
+ return;\r
+ }\r
+ }\r
+ break;\r
+ case FSCDBAS: /* Supercommander destroys base */\r
+ future[FSCDBAS] = 1e30;\r
+ isatb = 2;\r
+ if (d.galaxy[d.isx][d.isy]%100 < 10) break; /* WAS RETURN! */\r
+ ixhold = batx;\r
+ iyhold = baty;\r
+ batx = d.isx;\r
+ baty = d.isy;\r
+ case FCDBAS: /* Commander succeeds in destroying base */\r
+ if (line==FCDBAS) {\r
+ future[FCDBAS] = 1e30;\r
+ /* find the lucky pair */\r
+ for (i = 1; i <= d.remcom; i++)\r
+ if (d.cx[i]==batx && d.cy[i]==baty) break;\r
+ if (i > d.remcom || d.rembase == 0 ||\r
+ d.galaxy[batx][baty] % 100 < 10) {\r
+ /* No action to take after all */\r
+ batx = baty = 0;\r
+ break;\r
+ }\r
+ }\r
+ /* Code merges here for any commander destroying base */\r
+ /* Not perfect, but will have to do */\r
+ if (starch[batx][baty] == -1) starch[batx][baty] = 0;\r
+ /* Handle case where base is in same quadrant as starship */\r
+ if (batx==quadx && baty==quady) {\r
+ if (starch[batx][baty] > 999) starch[batx][baty] -= 10;\r
+ quad[basex][basey]= IHDOT;\r
+ basex=basey=0;\r
+ newcnd();\r
+ skip(1);\r
+ prout("Spock- \"Captain, I believe the starbase has been destroyed.\"");\r
+ }\r
+ else if (d.rembase != 1 &&\r
+ (damage[DRADIO] <= 0.0 || condit == IHDOCKED)) {\r
+ /* Get word via subspace radio */\r
+ if (ipage==0) pause(1);\r
+ ipage = 1;\r
+ skip(1);\r
+ prout("Lt. Uhura- \"Captain, Starfleet Command reports that");\r
+ proutn(" the starbase in");\r
+ cramlc(1, batx, baty);\r
+ prout(" has been destroyed by");\r
+ if (isatb==2) prout("the Klingon Super-Commander");\r
+ else prout("a Klingon Commander");\r
+ }\r
+ /* Remove Starbase from galaxy */\r
+ d.galaxy[batx][baty] -= 10;\r
+ for (i=1; i <= d.rembase; i++)\r
+ if (d.baseqx[i]==batx && d.baseqy[i]==baty) {\r
+ d.baseqx[i]=d.baseqx[d.rembase];\r
+ d.baseqy[i]=d.baseqy[d.rembase];\r
+ }\r
+ d.rembase--;\r
+ if (isatb == 2) {\r
+ /* reinstate a commander's base attack */\r
+ batx = ixhold;\r
+ baty = iyhold;\r
+ isatb = 0;\r
+ }\r
+ else {\r
+ batx = baty = 0;\r
+ }\r
+ break;\r
+ case FSCMOVE: /* Supercommander moves */\r
+ future[FSCMOVE] = d.date+0.2777;\r
+ if (ientesc+istract==0 &&\r
+ isatb!=1 &&\r
+ (iscate!=1 || justin==1)) scom(&ipage);\r
+ break;\r
+ case FDSPROB: /* Move deep space probe */\r
+ future[FDSPROB] = d.date + 0.01;\r
+ probex += probeinx;\r
+ probey += probeiny;\r
+ i = (int)(probex/10 +0.05);\r
+ j = (int)(probey/10 + 0.05);\r
+ if (probecx != i || probecy != j) {\r
+ probecx = i;\r
+ probecy = j;\r
+ if (i < 1 || i > 8 || j < 1 || j > 8 ||\r
+ d.galaxy[probecx][probecy] == 1000) {\r
+ // Left galaxy or ran into supernova\r
+ if (damage[DRADIO]==0.0 || condit == IHDOCKED) {\r
+ if (ipage==0) pause(1);\r
+ ipage = 1;\r
+ skip(1);\r
+ proutn("Lt. Uhura- \"The deep space probe ");\r
+ if (i < 1 ||i > 8 || j < 1 || j > 8)\r
+ proutn("has left the galaxy");\r
+ else\r
+ proutn("is no longer transmitting");\r
+ prout(".\"");\r
+ }\r
+ future[FDSPROB] = 1e30;\r
+ break;\r
+ }\r
+ if (damage[DRADIO]==0.0 || condit == IHDOCKED) {\r
+ if (ipage==0) pause(1);\r
+ ipage = 1;\r
+ skip(1);\r
+ proutn("Lt. Uhura- \"The deep space probe is now in ");\r
+ cramlc(1, probecx, probecy);\r
+ prout(".\"");\r
+ }\r
+ }\r
+ /* Update star chart if Radio is working or have access to\r
+ radio. */\r
+ if (damage[DRADIO] == 0.0 || condit == IHDOCKED)\r
+ starch[probecx][probecy] = damage[DRADIO] > 0.0 ?\r
+ d.galaxy[probecx][probecy]+1000 : 1;\r
+ proben--; // One less to travel\r
+ if (proben == 0 && isarmed &&\r
+ d.galaxy[probecx][probecy] % 10 > 0) {\r
+ /* lets blow the sucker! */\r
+ snova(1,0);\r
+ future[FDSPROB] = 1e30;\r
+ if (d.galaxy[quadx][quady] == 1000) return;\r
+ }\r
+ break;\r
+ }\r
+ }\r
+}\r
+\r
+ \r
+void wait(void) {\r
+ int key;\r
+ double temp, delay, origTime;\r
+\r
+ ididit = 0;\r
+ for (;;) {\r
+ key = scan();\r
+ if (key != IHEOL) break;\r
+ proutn("How long? ");\r
+ }\r
+ chew();\r
+ if (key != IHREAL) {\r
+ huh();\r
+ return;\r
+ }\r
+ origTime = delay = aaitem;\r
+ if (delay <= 0.0) return;\r
+ if (delay >= d.remtime || nenhere != 0) {\r
+ prout("Are you sure? ");\r
+ if (ja() == 0) return;\r
+ }\r
+\r
+ /* Alternate resting periods (events) with attacks */\r
+\r
+ resting = 1;\r
+ do {\r
+ if (delay <= 0) resting = 0;\r
+ if (resting == 0) {\r
+ cramf(d.remtime, 0, 2);\r
+ prout(" stardates left.");\r
+ return;\r
+ }\r
+ temp = Time = delay;\r
+\r
+ if (nenhere) {\r
+ double rtime = 1.0 + Rand();\r
+ if (rtime < temp) temp = rtime;\r
+ Time = temp;\r
+ }\r
+ if (Time < delay) attack(0);\r
+ if (nenhere==0) movetho();\r
+ if (alldone) return;\r
+ events();\r
+ ididit = 1;\r
+ if (alldone) return;\r
+ delay -= temp;\r
+ /* Repair Deathray if long rest at starbase */\r
+ if (origTime-delay >= 9.99 && condit == IHDOCKED)\r
+ damage[DDRAY] = 0.0;\r
+ } while (d.galaxy[quadx][quady] != 1000); // leave if quadrant supernovas\r
+\r
+ resting = 0;\r
+ Time = 0;\r
+}\r
+\r
+void nova(int ix, int iy) {\r
+ static double course[] =\r
+ {0.0, 10.5, 12.0, 1.5, 9.0, 0.0, 3.0, 7.5, 6.0, 4.5};\r
+ int bot, top, top2, burst, hits[11][3], kount, icx, icy, mm, nn, j;\r
+ int iquad, iquad1, i, ll, newcx, newcy, ii, jj;\r
+ if (Rand() < 0.05) {\r
+ /* Wow! We've supernova'ed */\r
+ snova(ix, iy);\r
+ return;\r
+ }\r
+\r
+ /* handle initial nova */\r
+ quad[ix][iy] = IHDOT;\r
+ crmena(1, IHSTAR, 2, ix, iy);\r
+ prout(" novas.");\r
+ d.galaxy[quadx][quady] -= 1;\r
+ d.starkl++;\r
+ \r
+ /* Set up stack to recursively trigger adjacent stars */\r
+ bot = top = top2 = 1;\r
+ kount = 0;\r
+ icx = icy = 0;\r
+ hits[1][1] = ix;\r
+ hits[1][2] = iy;\r
+ while (1) {\r
+ for (mm = bot; mm <= top; mm++) \r
+ for (nn = 1; nn <= 3; nn++) /* nn,j represents coordinates around current */\r
+ for (j = 1; j <= 3; j++) {\r
+ if (j==2 && nn== 2) continue;\r
+ ii = hits[mm][1]+nn-2;\r
+ jj = hits[mm][2]+j-2;\r
+ if (ii < 1 || ii > 10 || jj < 1 || jj > 10) continue;\r
+ iquad = quad[ii][jj];\r
+ switch (iquad) {\r
+// case IHDOT: /* Empty space ends reaction\r
+// case IHQUEST:\r
+// case IHBLANK:\r
+// case IHT:\r
+// case IHWEB:\r
+ default:\r
+ break;\r
+ case IHSTAR: /* Affect another star */\r
+ if (Rand() < 0.05) {\r
+ /* This star supernovas */\r
+ snova(ii,jj);\r
+ return;\r
+ }\r
+ top2++;\r
+ hits[top2][1]=ii;\r
+ hits[top2][2]=jj;\r
+ d.galaxy[quadx][quady] -= 1;\r
+ d.starkl++;\r
+ crmena(1, IHSTAR, 2, ii, jj);\r
+ prout(" novas.");\r
+ quad[ii][jj] = IHDOT;\r
+ break;\r
+ case IHP: /* Destroy planet */\r
+ d.newstuf[quadx][quady] -= 1;\r
+ d.nplankl++;\r
+ crmena(1, IHP, 2, ii, jj);\r
+ prout(" destroyed.");\r
+ d.plnets[iplnet] = nulplanet;\r
+ iplnet = plnetx = plnety = 0;\r
+ if (landed == 1) {\r
+ finish(FPNOVA);\r
+ return;\r
+ }\r
+ quad[ii][jj] = IHDOT;\r
+ break;\r
+ case IHB: /* Destroy base */\r
+ d.galaxy[quadx][quady] -= 10;\r
+ for (i = 1; i <= d.rembase; i++)\r
+ if (d.baseqx[i]==quadx && d.baseqy[i]==quady) break;\r
+ d.baseqx[i] = d.baseqx[d.rembase];\r
+ d.baseqy[i] = d.baseqy[d.rembase];\r
+ d.rembase--;\r
+ basex = basey = 0;\r
+ d.basekl++;\r
+ newcnd();\r
+ crmena(1, IHB, 2, ii, jj);\r
+ prout(" destroyed.");\r
+ quad[ii][jj] = IHDOT;\r
+ break;\r
+ case IHE: /* Buffet ship */\r
+ case IHF:\r
+ prout("***Starship buffeted by nova.");\r
+ if (shldup) {\r
+ if (shield >= 2000.0) shield -= 2000.0;\r
+ else {\r
+ double diff = 2000.0 - shield;\r
+ energy -= diff;\r
+ shield = 0.0;\r
+ shldup = 0;\r
+ prout("***Shields knocked out.");\r
+ damage[DSHIELD] += 0.005*damfac*Rand()*diff;\r
+ }\r
+ }\r
+ else energy -= 2000.0;\r
+ if (energy <= 0) {\r
+ finish(FNOVA);\r
+ return;\r
+ }\r
+ /* add in course nova contributes to kicking starship*/\r
+ icx += sectx-hits[mm][1];\r
+ icy += secty-hits[mm][2];\r
+ kount++;\r
+ break;\r
+ case IHK: /* kill klingon */\r
+ deadkl(ii,jj,iquad, ii, jj);\r
+ break;\r
+ case IHC: /* Damage/destroy big enemies */\r
+ case IHS:\r
+ case IHR:\r
+ for (ll = 1; ll <= nenhere; ll++)\r
+ if (kx[ll]==ii && ky[ll]==jj) break;\r
+ kpower[ll] -= 800.0; /* If firepower is lost, die */\r
+ if (kpower[ll] <= 0.0) {\r
+ deadkl(ii, jj, iquad, ii, jj);\r
+ break;\r
+ }\r
+ newcx = ii + ii - hits[mm][1];\r
+ newcy = jj + jj - hits[mm][2];\r
+ crmena(1, iquad, 2, ii, jj);\r
+ proutn(" damaged");\r
+ if (newcx<1 || newcx>10 || newcy<1 || newcy>10) {\r
+ /* can't leave quadrant */\r
+ skip(1);\r
+ break;\r
+ }\r
+ iquad1 = quad[newcx][newcy];\r
+ if (iquad1 == IHBLANK) {\r
+ proutn(", blasted into ");\r
+ crmena(0, IHBLANK, 2, newcx, newcy);\r
+ skip(1);\r
+ deadkl(ii, jj, iquad, newcx, newcy);\r
+ break;\r
+ }\r
+ if (iquad1 != IHDOT) {\r
+ /* can't move into something else */\r
+ skip(1);\r
+ break;\r
+ }\r
+ proutn(", buffeted to");\r
+ cramlc(2, newcx, newcy);\r
+ quad[ii][jj] = IHDOT;\r
+ quad[newcx][newcy] = iquad;\r
+ kx[ll] = newcx;\r
+ ky[ll] = newcy;\r
+ kavgd[ll] = sqrt(square(sectx-newcx)+square(secty-newcy));\r
+ kdist[ll] = kavgd[ll];\r
+ skip(1);\r
+ break;\r
+ }\r
+ }\r
+ if (top == top2) break;\r
+ bot = top + 1;\r
+ top = top2;\r
+ }\r
+ if (kount==0) return;\r
+\r
+ /* Starship affected by nova -- kick it away. */\r
+ dist = kount*0.1;\r
+ if (icx) icx = (icx < 0 ? -1 : 1);\r
+ if (icy) icy = (icy < 0 ? -1 : 1);\r
+ direc = course[3*(icx+1)+icy+2];\r
+ if (direc == 0.0) dist = 0.0;\r
+ if (dist == 0.0) return;\r
+ Time = 10.0*dist/16.0;\r
+ skip(1);\r
+ prout("Force of nova displaces starship.");\r
+ iattak=2; /* Eliminates recursion problem */\r
+ move();\r
+ Time = 10.0*dist/16.0;\r
+ return;\r
+}\r
+ \r
+ \r
+void snova(int insx, int insy) {\r
+ int comdead, nqx, nqy, nsx, nsy, num, kldead, iscdead;\r
+ int nrmdead, npdead;\r
+ int insipient=0;\r
+\r
+ nsx = insy;\r
+ nsy = insy;\r
+\r
+ if (insy== 0) {\r
+ if (insx == 1) {\r
+ /* NOVAMAX being used */\r
+ nqx = probecx;\r
+ nqy = probecy;\r
+ }\r
+ else {\r
+ int stars = 0;\r
+ /* Scheduled supernova -- select star */\r
+ /* logic changed here so that we won't favor quadrants in top\r
+ left of universe */\r
+ for (nqx = 1; nqx<=8; nqx++) {\r
+ for (nqy = 1; nqy<=8; nqy++) {\r
+ stars += d.galaxy[nqx][nqy] % 10;\r
+ }\r
+ }\r
+ if (stars == 0) return; /* nothing to supernova exists */\r
+ num = Rand()*stars + 1;\r
+ for (nqx = 1; nqx<=8; nqx++) {\r
+ for (nqy = 1; nqy<=8; nqy++) {\r
+ num -= d.galaxy[nqx][nqy] % 10;\r
+ if (num <= 0) break;\r
+ }\r
+ if (num <=0) break;\r
+ }\r
+#ifdef DEBUG\r
+ if (idebug) {\r
+ proutn("Super nova here?");\r
+ if (ja()==1) {\r
+ nqx = quadx;\r
+ nqy = quady;\r
+ }\r
+ }\r
+#endif\r
+ }\r
+\r
+ if (nqx != quady || nqy != quady || justin != 0) {\r
+ /* it isn't here, or we just entered (treat as inroute) */\r
+ if (damage[DRADIO] == 0.0 || condit == IHDOCKED) {\r
+ skip(1);\r
+ proutn("Message from Starfleet Command Stardate ");\r
+ cramf(d.date, 0, 1);\r
+ skip(1);\r
+ proutn(" Supernova in");\r
+ cramlc(1, nqx, nqy);\r
+ prout("; caution advised.");\r
+ }\r
+ }\r
+ else {\r
+ /* we are in the quadrant! */\r
+ insipient = 1;\r
+ num = Rand()* (d.galaxy[nqx][nqy]%10) + 1;\r
+ for (nsx=1; nsx < 10; nsx++) {\r
+ for (nsy=1; nsy < 10; nsy++) {\r
+ if (quad[nsx][nsy]==IHSTAR) {\r
+ num--;\r
+ if (num==0) break;\r
+ }\r
+ }\r
+ if (num==0) break;\r
+ }\r
+ }\r
+ }\r
+ else {\r
+ insipient = 1;\r
+ }\r
+\r
+ if (insipient) {\r
+ skip(1);\r
+ prouts("***RED ALERT! RED ALERT!");\r
+ skip(1);\r
+ proutn("***Incipient supernova detected at");\r
+ cramlc(2, nsx, nsy);\r
+ skip(1);\r
+ nqx = quadx;\r
+ nqy = quady;\r
+ if (square(nsx-sectx) + square(nsy-secty) <= 2.1) {\r
+ proutn("Emergency override attempts t");\r
+ prouts("***************");\r
+ skip(1);\r
+ stars();\r
+ alldone=1;\r
+ }\r
+ }\r
+ /* destroy any Klingons in supernovaed quadrant */\r
+ num=d.galaxy[nqx][nqy];\r
+ kldead = num/100;\r
+ comdead = iscdead = 0;\r
+ if (nqx==d.isx && nqy == d.isy) {\r
+ /* did in the Supercommander! */\r
+ d.nscrem = d.isx = d.isy = isatb = iscate = 0;\r
+ iscdead = 1;\r
+ future[FSCMOVE] = future[FSCDBAS] = 1e30;\r
+ }\r
+ d.remkl -= kldead;\r
+ if (d.remcom) {\r
+ int maxloop = d.remcom, l;\r
+ for (l = 1; l <= maxloop; l++) {\r
+ if (d.cx[l] == nqx && d.cy[l] == nqy) {\r
+ d.cx[l] = d.cx[d.remcom];\r
+ d.cy[l] = d.cy[d.remcom];\r
+ d.cx[d.remcom] = d.cy[d.remcom] = 0;\r
+ d.remcom--;\r
+ kldead--;\r
+ comdead++;\r
+ if (d.remcom==0) future[FTBEAM] = 1e30;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ /* destroy Romulans and planets in supernovaed quadrant */\r
+ num = d.newstuf[nqx][nqy];\r
+ d.newstuf[nqx][nqy] = 0;\r
+ nrmdead = num/10;\r
+ d.nromrem -= nrmdead;\r
+ npdead = num - nrmdead*10;\r
+ if (npdead) {\r
+ int l;\r
+ for (l = 1; l <= inplan; l++)\r
+ if (d.plnets[l].x == nqx && d.plnets[l].y == nqy) {\r
+ d.plnets[l] = nulplanet;\r
+ }\r
+ }\r
+ /* Destroy any base in supernovaed quadrant */\r
+ if (d.rembase) {\r
+ int maxloop = d.rembase, l;\r
+ for (l = 1; l <= maxloop; l++)\r
+ if (d.baseqx[l]==nqx && d.baseqy[l]==nqy) {\r
+ d.baseqx[l] = d.baseqx[d.rembase];\r
+ d.baseqy[l] = d.baseqy[d.rembase];\r
+ d.baseqx[d.rembase] = d.baseqy[d.rembase] = 0;\r
+ d.rembase--;\r
+ break;\r
+ }\r
+ }\r
+ /* If starship caused supernova, tally up destruction */\r
+ if (insx) {\r
+ num = d.galaxy[nqx][nqy] % 100;\r
+ d.starkl += num % 10;\r
+ d.basekl += num/10;\r
+ d.killk += kldead;\r
+ d.killc += comdead;\r
+ d.nromkl += nrmdead;\r
+ d.nplankl += npdead;\r
+ d.nsckill += iscdead;\r
+ }\r
+ /* mark supernova in galaxy and in star chart */\r
+ if ((quadx == nqx && quady == nqy) ||\r
+ damage[DRADIO] == 0 ||\r
+ condit == IHDOCKED)\r
+ starch[nqx][nqy] = 1;\r
+ d.galaxy[nqx][nqy] = 1000;\r
+ /* If supernova destroys last klingons give special message */\r
+ if (d.remkl==0 && (nqx != quadx || nqy != quady)) {\r
+ skip(2);\r
+ if (insx == 0) prout("Lucky you!");\r
+ proutn("A supernova in");\r
+ cramlc(1, nqx, nqy);\r
+ prout(" has just destroyed the last Klingons.");\r
+ finish(FWON);\r
+ return;\r
+ }\r
+ /* if some Klingons remain, continue or die in supernova */\r
+ if (alldone) finish(FSNOVAED);\r
+ return;\r
+}\r
+ \r
+ \r
--- /dev/null
+#include "sst.h"\r
+#include <string.h>\r
+#include <time.h>\r
+\r
+void dstrct() {\r
+ /* Finish with a BANG! */\r
+ chew();\r
+ if (damage[DCOMPTR] != 0.0) {\r
+ prout("Computer damaged; cannot execute destruct sequence.");\r
+ return;\r
+ }\r
+ skip(1);\r
+ prouts("---WORKING---"); skip(1);\r
+ prout("SELF-DESTRUCT-SEQUENCE-ACTIVATED");\r
+ prouts(" 10"); skip(1);\r
+ prouts(" 9"); skip(1);\r
+ prouts(" 8"); skip(1);\r
+ prouts(" 7"); skip(1);\r
+ prouts(" 6"); skip(1);\r
+ prout("ENTER-CORRECT-PASSWORD-TO-CONTINUE-");\r
+ prout("SELF-DESTRUCT-SEQUENCE-OTHERWISE-");\r
+ prout("SELF-DESTRUCT-SEQUENCE-WILL-BE-ABORTED");\r
+ scan();\r
+ chew();\r
+ if (strcmp(passwd, citem) != 0) {\r
+ prouts("PASSWORD-REJECTED;"); skip(1);\r
+ prout("CONTINUITY-EFFECTED");\r
+ skip(1);\r
+ return;\r
+ }\r
+ prouts("PASSWORD-ACCEPTED"); skip(1);\r
+ prouts(" 5"); skip(1);\r
+ prouts(" 4"); skip(1);\r
+ prouts(" 3"); skip(1);\r
+ prouts(" 2"); skip(1);\r
+ prouts(" 1"); skip(1);\r
+ if (Rand() < 0.15) {\r
+ prouts("GOODBYE-CRUEL-WORLD");\r
+ skip(1);\r
+ }\r
+ skip(2);\r
+ kaboom();\r
+}\r
+\r
+void kaboom(void) {\r
+ stars();\r
+ if (ship==IHE) prouts("***");\r
+ prouts("********* Entropy of ");\r
+ crmshp();\r
+ prouts(" maximized *********");\r
+ skip(1);\r
+ stars();\r
+ skip(1);\r
+ if (nenhere != 0) {\r
+ double whammo = 25.0 * energy;\r
+ int l=1;\r
+ while (l <= nenhere) {\r
+ if (kpower[l]*kdist[l] <= whammo) \r
+ deadkl(kx[l],ky[l], quad[kx[l]][ky[l]], kx[l], ky[l]);\r
+ l++;\r
+ }\r
+ }\r
+ finish(FDILITHIUM);\r
+}\r
+ \r
+\r
+void finish(FINTYPE ifin) {\r
+ int igotit = 0;\r
+ alldone = 1;\r
+ skip(3);\r
+ printf("It is stardate %.1f .\n\n", d.date);\r
+ switch (ifin) {\r
+ case FWON: // Game has been won\r
+ if (d.nromrem != 0)\r
+ printf("The remaining %d Romulans surrender to Starfleet Command.\n",\r
+ d.nromrem);\r
+ \r
+ prout("You have smashed the Klingon invasion fleet and saved");\r
+ prout("the Federation.");\r
+ gamewon=1;\r
+ if (alive) {\r
+ double badpt;\r
+ badpt = 5.*d.starkl + casual + 10.*d.nplankl +\r
+ 45.*nhelp+100.*d.basekl;\r
+ if (ship == IHF) badpt += 100.0;\r
+ else if (ship == 0) badpt += 200.0;\r
+ if (badpt < 100.0) badpt = 0.0; // Close enough!\r
+ if (d.date-indate < 5.0 ||\r
+ // killsPerDate >= RateMax\r
+ (d.killk+d.killc+d.nsckill)/(d.date-indate) >=\r
+ 0.1*skill*(skill+1.0) + 0.1 + 0.008*badpt) {\r
+ skip(1);\r
+ prout("In fact, you have done so well that Starfleet Command");\r
+ switch (skill) {\r
+ case 1:\r
+ prout("promotes you one step in rank from \"Novice\" to \"Fair\".");\r
+ break;\r
+ case 2:\r
+ prout("promotes you one step in rank from \"Fair\" to \"Good\".");\r
+ break;\r
+ case 3:\r
+ prout("promotes you one step in rank from \"Good\" to \"Expert\".");\r
+ break;\r
+ case 4:\r
+ prout("promotes you to Commodore Emeritus.");\r
+ skip(1);\r
+ prout("Now that you think you're really good, try playing");\r
+ prout("the \"Emeritus\" game. It will splatter your ego.");\r
+ break;\r
+ case 5:\r
+ skip(1);\r
+ prout("Computer- ERROR-ERROR-ERROR-ERROR");\r
+ skip(1);\r
+ prout(" YOUR-SKILL-HAS-EXCEEDED-THE-CAPACITY-OF-THIS-PROGRAM");\r
+ prout(" THIS-PROGRAM-MUST-SURVIVE");\r
+ prout(" THIS-PROGRAM-MUST-SURVIVE");\r
+ prout(" THIS-PROGRAM-MUST-SURVIVE");\r
+ prout(" THIS-PROGRAM-MUST?- MUST ? - SUR? ? -? VI");\r
+ skip(1);\r
+ prout("Now you can retire and write your own Star Trek game!");\r
+ skip(1);\r
+ break;\r
+ }\r
+ if (skill > 3) {\r
+ if (thawed\r
+#ifdef DEBUG\r
+ && !idebug\r
+#endif\r
+ )\r
+ prout("You cannot get a citation, so...");\r
+ else {\r
+ prout("Do you want your Commodore Emeritus Citation printed?");\r
+ proutn("(You need a 132 column printer.)");\r
+ chew();\r
+ if (ja()) {\r
+ igotit = 1;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ // Only grant long life if alive (original didn't!)\r
+ skip(1);\r
+ prout("LIVE LONG AND PROSPER.");\r
+ }\r
+ score();\r
+ if (igotit != 0) plaque();\r
+ return;\r
+ case FDEPLETE: // Federation Resources Depleted\r
+ prout("Your time has run out and the Federation has been");\r
+ prout("conquered. Your starship is now Klingon property,");\r
+ prout("and you are put on trial as a war criminal. On the");\r
+ proutn("basis of your record, you are ");\r
+ if (d.remkl*3.0 > inkling) {\r
+ prout("aquitted.");\r
+ skip(1);\r
+ prout("LIVE LONG AND PROSPER.");\r
+ }\r
+ else {\r
+ prout("found guilty and");\r
+ prout("sentenced to death by slow torture.");\r
+ alive = 0;\r
+ }\r
+ score();\r
+ return;\r
+ case FLIFESUP:\r
+ prout("Your life support reserves have run out, and");\r
+ prout("you die of thirst, starvation, and asphyxiation.");\r
+ prout("Your starship is a derelict in space.");\r
+ break;\r
+ case FNRG:\r
+ prout("Your energy supply is exhausted.");\r
+ skip(1);\r
+ prout("Your starship is a derelict in space.");\r
+ break;\r
+ case FBATTLE:\r
+ proutn("The ");\r
+ crmshp();\r
+ prout("has been destroyed in battle.");\r
+ skip(1);\r
+ prout("Dulce et decorum est pro patria mori.");\r
+ break;\r
+ case FNEG3:\r
+ prout("You have made three attempts to cross the negative energy");\r
+ prout("barrier which surrounds the galaxy.");\r
+ skip(1);\r
+ prout("Your navigation is abominable.");\r
+ score();\r
+ return;\r
+ case FNOVA:\r
+ prout("Your starship has been destroyed by a nova.");\r
+ prout("That was a great shot.");\r
+ skip(1);\r
+ break;\r
+ case FSNOVAED:\r
+ proutn("The ");\r
+ crmshp();\r
+ prout(" has been fried by a supernova.");\r
+ prout("...Not even cinders remain...");\r
+ break;\r
+ case FABANDN:\r
+ prout("You have been captured by the Klingons. If you still");\r
+ prout("had a starbase to be returned to, you would have been");\r
+ prout("repatriated and given another chance. Since you have");\r
+ prout("no starbases, you will be mercilessly tortured to death.");\r
+ break;\r
+ case FDILITHIUM:\r
+ prout("Your starship is now an expanding cloud of subatomic particles");\r
+ break;\r
+ case FMATERIALIZE:\r
+ prout("Starbase was unable to re-materialize your starship.");\r
+ prout("Sic transit gloria muntdi");\r
+ break;\r
+ case FPHASER:\r
+ proutn("The ");\r
+ crmshp();\r
+ prout(" has been cremated by its own phasers.");\r
+ break;\r
+ case FLOST:\r
+ prout("You and your landing party have been");\r
+ prout("converted to energy, disipating through space.");\r
+ break;\r
+ case FMINING:\r
+ prout("You are left with your landing party on");\r
+ prout("a wild jungle planet inhabited by primitive cannibals.");\r
+ skip(1);\r
+ prout("They are very fond of \"Captain Kirk\" soup.");\r
+ skip(1);\r
+ proutn("Without your leadership, the ");\r
+ crmshp();\r
+ prout(" is destroyed.");\r
+ break;\r
+ case FDPLANET:\r
+ prout("You and your mining party perish.");\r
+ skip(1);\r
+ prout("That was a great shot.");\r
+ skip(1);\r
+ break;\r
+ case FSSC:\r
+ prout("The Galileo is instantly annihilated by the supernova.");\r
+ // no break;\r
+ case FPNOVA:\r
+ prout("You and your mining party are atomized.");\r
+ skip(1);\r
+ proutn("Mr. Spock takes command of the ");\r
+ crmshp();\r
+ prout(" and");\r
+ prout("joins the Romulans, reigning terror on the Federation.");\r
+ break;\r
+ case FSTRACTOR:\r
+ prout("The shuttle craft Galileo is also caught,");\r
+ prout("and breaks up under the strain.");\r
+ skip(1);\r
+ prout("Your debris is scattered for millions of miles.");\r
+ proutn("Without your leadership, the ");\r
+ crmshp();\r
+ prout(" is destroyed.");\r
+ break;\r
+ case FDRAY:\r
+ prout("The mutants attack and kill Spock.");\r
+ prout("Your ship is captured by Klingons, and");\r
+ prout("your crew is put on display in a Klingon zoo.");\r
+ break;\r
+ case FTRIBBLE:\r
+ prout("Tribbles consume all remaining water,");\r
+ prout("food, and oxygen on your ship.");\r
+ skip(1);\r
+ prout("You die of thirst, starvation, and asphyxiation.");\r
+ prout("Your starship is a derelict in space.");\r
+ break;\r
+ case FHOLE:\r
+ prout("Your ship is drawn to the center of the black hole.");\r
+ prout("You are crushed into extremely dense matter.");\r
+ break;\r
+ }\r
+ if (ship==IHF) ship= 0;\r
+ else if (ship == IHE) ship = IHF;\r
+ alive = 0;\r
+ if (d.remkl != 0) {\r
+ double goodies = d.remres/inresor;\r
+ double baddies = (d.remkl + 2.0*d.remcom)/(inkling+2.0*incom);\r
+ if (goodies/baddies >= 1.0+0.5*Rand()) {\r
+ prout("As a result of your actions, a treaty with the Klingon");\r
+ prout("Empire has been signed. The terms of the treaty are");\r
+ if (goodies/baddies >= 3.0+Rand()) {\r
+ prout("favorable to the Federation.");\r
+ skip(1);\r
+ prout("Congratulations!");\r
+ }\r
+ else\r
+ prout("highly unfavorable to the Federation.");\r
+ }\r
+ else\r
+ prout("The Federation will be destroyed.");\r
+ }\r
+ else {\r
+ prout("Since you took the last Klingon with you, you are a");\r
+ prout("martyr and a hero. Someday maybe they'll erect a");\r
+ prout("statue in your memory. Rest in peace, and try not");\r
+ prout("to think about pigeons.");\r
+ gamewon = 1;\r
+ }\r
+ score();\r
+}\r
+\r
+void score(void) {\r
+ double timused = d.date - indate;\r
+ int ithperd, iwon, klship;\r
+\r
+ pause(0);\r
+\r
+ iskill = skill;\r
+ if ((timused == 0 || d.remkl != 0) && timused < 5.0) timused = 5.0;\r
+ perdate = (d.killc + d.killk + d.nsckill)/timused;\r
+ ithperd = 500*perdate + 0.5;\r
+ iwon = 0;\r
+ if (gamewon) iwon = 100*skill;\r
+ if (ship == IHE) klship = 0;\r
+ else if (ship == IHF) klship = 1;\r
+ else klship = 2;\r
+ if (gamewon == 0) d.nromrem = 0; // None captured if no win\r
+ iscore = 10*d.killk + 50*d.killc + ithperd + iwon\r
+ - 100*d.basekl - 100*klship - 45*nhelp -5*d.starkl - casual\r
+ + 20*d.nromkl + 200*d.nsckill - 10*d.nplankl + d.nromrem;\r
+ if (alive == 0) iscore -= 200;\r
+ skip(2);\r
+ prout("Your score --");\r
+ if (d.nromkl)\r
+ printf("%6d Romulans destroyed %5d\n",\r
+ d.nromkl,20*d.nromkl);\r
+ if (d.nromrem)\r
+ printf("%6d Romulans captured %5d\n",\r
+ d.nromrem, d.nromrem);\r
+ if (d.killk)\r
+ printf("%6d ordinary Klingons destroyed %5d\n",\r
+ d.killk, 10*d.killk);\r
+ if (d.killc)\r
+ printf("%6d Klingon commanders destroyed %5d\n",\r
+ d.killc, 50*d.killc);\r
+ if (d.nsckill)\r
+ printf("%6d Super-Commander destroyed %5d\n",\r
+ d.nsckill, 200*d.nsckill);\r
+ if (ithperd)\r
+ printf("%6.2f Klingons per stardate %5d\n",\r
+ perdate, ithperd);\r
+ if (d.starkl)\r
+ printf("%6d stars destroyed by your action %5d\n",\r
+ d.starkl, -5*d.starkl);\r
+ if (d.nplankl)\r
+ printf("%6d planets destroyed by your action %5d\n",\r
+ d.nplankl, -10*d.nplankl);\r
+ if (d.basekl)\r
+ printf("%6d bases destroyed by your action %5d\n",\r
+ d.basekl, -100*d.basekl);\r
+ if (nhelp)\r
+ printf("%6d calls for help from starbase %5d\n",\r
+ nhelp, -45*nhelp);\r
+ if (casual)\r
+ printf("%6d casualties incurred %5d\n",\r
+ casual, -casual);\r
+ if (klship)\r
+ printf("%6d ship(s) lost or destroyed %5d\n",\r
+ klship, -100*klship);\r
+ if (alive==0)\r
+ prout("Penalty for getting yourself killed -200");\r
+ if (gamewon) {\r
+ skip(1);\r
+ proutn("Bonus for winning ");\r
+ switch (skill) {\r
+ case 1: proutn("Novice game "); break;\r
+ case 2: proutn("Fair game "); break;\r
+ case 3: proutn("Good game "); break;\r
+ case 4: proutn("Expert game "); break;\r
+ case 5: proutn("Emeritus game"); break;\r
+ }\r
+ printf(" %5d\n", iwon);\r
+ }\r
+ skip(2);\r
+ printf("TOTAL SCORE %5d\n", iscore);\r
+}\r
+\r
+void plaque(void) {\r
+ FILE *fp=NULL;\r
+ time_t t;\r
+ char *timestring;\r
+ int nskip;\r
+ char winner[128];\r
+\r
+ skip(2);\r
+ \r
+ while (fp == NULL) {\r
+ printf("File or device name for your plaque:");\r
+ fgets(winner, 128, stdin);\r
+ winner[strlen(winner)-1] = '\0';\r
+ fp = fopen(winner, "w");\r
+ if (fp==NULL) {\r
+ printf("Invalid name.\n");\r
+ }\r
+ }\r
+\r
+ printf("Enter name to go on plaque (up to 30 characters):");\r
+ fgets(winner, 128, stdin);\r
+ winner[strlen(winner)-1] = '\0';\r
+ winner[30] = '\0';\r
+ nskip = 64 - strlen(winner)/2;\r
+\r
+ fprintf(fp,"\n\n\n\n");\r
+ /* --------DRAW ENTERPRISE PICTURE. */\r
+ fprintf(fp, " EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n" );\r
+ fprintf(fp, " EEE E : : : E\n" );\r
+ fprintf(fp, " EE EEE E : : NCC-1701 : E\n");\r
+ fprintf(fp, " EEEEEEEEEEEEEEEE EEEEEEEEEEEEEEE E : : : E\n");\r
+ fprintf(fp, " E E EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n");\r
+ fprintf(fp, " EEEEEEEEE EEEEEEEEEEEEE E E\n");\r
+ fprintf(fp, " EEEEEEE EEEEE E E E E\n");\r
+ fprintf(fp, " EEE E E E E\n");\r
+ fprintf(fp, " E E E E\n");\r
+ fprintf(fp, " EEEEEEEEEEEEE E E\n");\r
+ fprintf(fp, " EEE : EEEEEEE EEEEEEEE\n");\r
+ fprintf(fp, " :E : EEEE E\n");\r
+ fprintf(fp, " .-E -:----- E\n");\r
+ fprintf(fp, " :E : E\n");\r
+ fprintf(fp, " EE : EEEEEEEE\n");\r
+ fprintf(fp, " EEEEEEEEEEEEEEEEEEEEEEE\n");\r
+ fprintf(fp, "\n\n\n");\r
+ fprintf(fp, " U. S. S. ENTERPRISE\n");\r
+ fprintf(fp, "\n\n\n\n");\r
+ fprintf(fp, " For demonstrating outstanding ability as a starship captain\n");\r
+ fprintf(fp, "\n");\r
+ fprintf(fp, " Starfleet Command bestows to you\n");\r
+ fprintf(fp, "\n");\r
+ fprintf(fp,"%*s%s\n\n", nskip, "", winner);\r
+ fprintf(fp, " the rank of\n\n");\r
+ fprintf(fp, " \"Commodore Emeritus\"\n\n");\r
+ fprintf(fp, " ");\r
+ switch (iskill) {\r
+ case 4: fprintf(fp," Expert level\n\n"); break;\r
+ case 5: fprintf(fp,"Emeritus level\n\n"); break;\r
+ default: fprintf(fp," Cheat level\n\n"); break;\r
+ }\r
+ t = time(NULL);\r
+ timestring = ctime(&t);\r
+ fprintf(fp, " This day of %.6s %.4s, %.8s\n\n",\r
+ timestring+4, timestring+20, timestring+11);\r
+ fprintf(fp," Your score: %d\n\n", iscore);\r
+ fprintf(fp," Klingons per stardate: %.2f\n", perdate);\r
+ fclose(fp);\r
+}\r
--- /dev/null
+#include <stdlib.h>
+#include <time.h>
+#include <sys/ioctl.h>
+
+void randomize(void) {
+ srand((int)time(NULL));
+}
+
+
+int max(int a, int b) {
+ if (a > b) return a;
+ return b;
+}
+
+int min(int a, int b) {
+ if (a < b) return a;
+ return b;
+}
+
+int getch(void) {
+ char chbuf[1];
+ struct termio oldstate, newstate;
+ ioctl(0,TCGETA,&oldstate);
+ newstate = oldstate;
+ newstate.c_iflag = 0;
+ newstate.c_lflag = 0;
+ ioctl(0,TCSETA,&newstate);
+ read(0, &chbuf, 1);
+ ioctl(0,TCSETA,&oldstate);
+}
+
--- /dev/null
+CFLAGS= -O
+
+.c.o:
+ $(CC) $(CFLAGS) -c $<
+
+OFILES= sst.o finish.o reports.o setup.o linux.o moving.o battle.o events.o ai.o planets.o
+
+HFILES= sst.h
+
+sstos2.exe: $(OFILES)
+ gcc -o sst $(OFILES) -lm
+
+
+$(OFILES): $(HFILES)
+
--- /dev/null
+#include "sst.h"\r
+\r
+static void getcd(int, int);\r
+\r
+void move(void) {\r
+ double angle, deltax, deltay, bigger, x, y,\r
+ finald, finalx, finaly, stopegy;\r
+ int trbeam = 0, n, l, ix, iy, kink, kinks, iquad;\r
+\r
+ if (inorbit) {\r
+ prout("SULU- \"Leaving standard orbit.\"");\r
+ inorbit = 0;\r
+ }\r
+\r
+ angle = ((15.0 - direc) * 0.5235988);\r
+ deltax = -sin(angle);\r
+ deltay = cos(angle);\r
+ if (fabs(deltax) > fabs(deltay))\r
+ bigger = fabs(deltax);\r
+ else\r
+ bigger = fabs(deltay);\r
+ \r
+ deltay /= bigger;\r
+ deltax /= bigger;\r
+\r
+ /* If tractor beam is to occur, don't move full distance */\r
+ if (d.date+Time >= future[FTBEAM]) {\r
+ trbeam = 1;\r
+ condit = IHRED;\r
+ dist = dist*(future[FTBEAM]-d.date)/Time + 0.1;\r
+ Time = future[FTBEAM] - d.date + 1e-5;\r
+ }\r
+ /* Move within the quadrant */\r
+ quad[sectx][secty] = IHDOT;\r
+ x = sectx;\r
+ y = secty;\r
+ n = 10.0*dist*bigger+0.5;\r
+\r
+ if (n > 0) {\r
+ for (l = 1; l <= n; l++) {\r
+ ix = (x += deltax) + 0.5;\r
+ iy = (y += deltay) + 0.5;\r
+ if (ix < 1 || ix > 10 || iy < 1 || iy > 10) {\r
+ /* Leaving quadrant -- allow final enemy attack */\r
+ /* Don't do it if being pushed by Nova */\r
+ if (nenhere != 0 && iattak != 2) {\r
+ newcnd();\r
+ for (l = 1; l <= nenhere; l++) {\r
+ finald = sqrt((ix-kx[l])*(double)(ix-kx[l]) +\r
+ (iy-ky[l])*(double)(iy-ky[l]));\r
+ kavgd[l] = 0.5 * (finald+kdist[l]);\r
+ }\r
+ if (d.galaxy[quadx][quady] != 1000) attack(0);\r
+ if (alldone) return;\r
+ }\r
+ /* compute final position -- new quadrant and sector */\r
+ x = 10*(quadx-1)+sectx;\r
+ y = 10*(quady-1)+secty;\r
+ ix = x+10.0*dist*bigger*deltax+0.5;\r
+ iy = y+10.0*dist*bigger*deltay+0.5;\r
+ /* check for edge of galaxy */\r
+ kinks = 0;\r
+ do {\r
+ kink = 0;\r
+ if (ix <= 0) {\r
+ ix = -ix + 1;\r
+ kink = 1;\r
+ }\r
+ if (iy <= 0) {\r
+ iy = -iy + 1;\r
+ kink = 1;\r
+ }\r
+ if (ix > 80) {\r
+ ix = 161 - ix;\r
+ kink = 1;\r
+ }\r
+ if (iy > 80) {\r
+ iy = 161 - iy;\r
+ kink = 1;\r
+ }\r
+ if (kink) kinks = 1;\r
+ } while (kink);\r
+\r
+ if (kinks) {\r
+ nkinks += 1;\r
+ if (nkinks == 3) {\r
+ /* Three strikes -- you're out! */\r
+ finish(FNEG3);\r
+ return;\r
+ }\r
+ prout("\nYOU HAVE ATTEMPTED TO CROSS THE NEGATIVE ENERGY BARRIER\n"\r
+ "AT THE EDGE OF THE GALAXY. THE THIRD TIME YOU TRY THIS,\n"\r
+ "YOU WILL BE DESTROYED.\n");\r
+ }\r
+ /* Compute final position in new quadrant */\r
+ if (trbeam) return; /* Don't bother if we are to be beamed */\r
+ quadx = (ix+9)/10;\r
+ quady = (iy+9)/10;\r
+ sectx = ix - 10*(quadx-1);\r
+ secty = iy - 10*(quady-1);\r
+ proutn("\nEntering");\r
+ cramlc(1, quadx, quady);\r
+ skip(1);\r
+ quad[sectx][secty] = ship;\r
+ newqad(0);\r
+ return;\r
+ }\r
+ iquad = quad[ix][iy];\r
+ if (iquad != IHDOT) {\r
+ /* object encountered in flight path */\r
+ stopegy = 50.0*dist/Time;\r
+ dist=0.1*sqrt((sectx-ix)*(double)(sectx-ix) +\r
+ (secty-iy)*(double)(secty-iy));\r
+ switch (iquad) {\r
+ case IHT: /* Ram a Tholean */\r
+ case IHK: /* Ram enemy ship */\r
+ case IHC:\r
+ case IHS:\r
+ case IHR:\r
+ sectx = ix;\r
+ secty = iy;\r
+ ram(0, iquad, sectx, secty);\r
+ finalx = sectx;\r
+ finaly = secty;\r
+ break;\r
+ case IHBLANK:\r
+ skip(1);\r
+ prouts("***RED ALERT! RED ALERT!");\r
+ skip(1);\r
+ proutn("***");\r
+ crmshp();\r
+ proutn(" pulled into black hole at");\r
+ cramlc(2, ix, iy);\r
+ skip(1);\r
+ finish(FHOLE);\r
+ return;\r
+ default:\r
+ /* something else */\r
+ skip(1);\r
+ crmshp();\r
+ if (iquad == IHWEB)\r
+ proutn(" encounters Tholian web at");\r
+ else\r
+ proutn(" blocked by object at");\r
+ cramlc(2, ix,iy);\r
+ prout(";");\r
+ proutn("Emergency stop required ");\r
+ cramf(stopegy, 0, 2);\r
+ prout(" units of energy.");\r
+ energy -= stopegy;\r
+ finalx = x-deltax+0.5;\r
+ sectx = finalx;\r
+ finaly = y-deltay+0.5;\r
+ secty = finaly;\r
+ if (energy <= 0) {\r
+ finish(FNRG);\r
+ return;\r
+ }\r
+ break;\r
+ }\r
+ goto label100; /* sorry! */\r
+ }\r
+ }\r
+ dist = 0.1*sqrt((sectx-ix)*(double)(sectx-ix) +\r
+ (secty-iy)*(double)(secty-iy));\r
+ sectx = ix;\r
+ secty = iy;\r
+ }\r
+ finalx = sectx;\r
+ finaly = secty;\r
+label100:\r
+ /* No quadrant change -- compute new avg enemy distances */\r
+ quad[sectx][secty] = ship;\r
+ if (nenhere) {\r
+ for (l = 1; l <= nenhere; l++) {\r
+ finald = sqrt((ix-kx[l])*(double)(ix-kx[l]) +\r
+ (iy-ky[l])*(double)(iy-ky[l]));\r
+ kavgd[l] = 0.5 * (finald+kdist[l]);\r
+ kdist[l] = finald;\r
+ }\r
+ sortkl();\r
+ if (d.galaxy[quadx][quady] != 1000 && iattak == 0)\r
+ attack(0);\r
+ for (l = 1 ; l <= nenhere; l++) kavgd[l] = kdist[l];\r
+ }\r
+ newcnd();\r
+ iattak = 0;\r
+ return;\r
+}\r
+\r
+void dock(void) {\r
+ chew();\r
+ if (condit == IHDOCKED) {\r
+ prout("Already docked.");\r
+ return;\r
+ }\r
+ if (inorbit) {\r
+ prout("You must first leave standard orbit.");\r
+ return;\r
+ }\r
+ if (basex==0 || abs(sectx-basex) > 1 || abs(secty-basey) > 1) {\r
+ crmshp();\r
+ prout(" not adjacent to base.");\r
+ return;\r
+ }\r
+ condit = IHDOCKED;\r
+ prout("Docked.");\r
+ if (energy < inenrg) energy = inenrg;\r
+ shield = inshld;\r
+ torps = intorps;\r
+ lsupres = inlsr;\r
+ if (stdamtim != 1e30 &&\r
+ (future[FCDBAS] < 1e30 || isatb == 1) && iseenit == 0) {\r
+ /* get attack report from base */\r
+ prout("Lt. Uhura- \"Captain, an important message from the starbase:\"");\r
+ attakreport();\r
+ iseenit = 1;\r
+ }\r
+}\r
+\r
+static void getcd(int isprobe, int akey) {\r
+ /* This program originally required input in terms of a (clock)\r
+ direction and distance. Somewhere in history, it was changed to\r
+ cartesian coordinates. So we need to convert. I think\r
+ "manual" input should still be done this way -- it's a real\r
+ pain if the computer isn't working! Manual mode is still confusing\r
+ because it involves giving x and y motions, yet the coordinates\r
+ are always displayed y - x, where +y is downward! */\r
+\r
+ \r
+ int irowq=quadx, icolq=quady, irows, icols, itemp=0, iprompt=0, key;\r
+ double xi, xj, xk, xl;\r
+ double deltax, deltay;\r
+ int automatic = -1;\r
+\r
+ /* Get course direction and distance. If user types bad values, return\r
+ with DIREC = -1.0. */\r
+\r
+ direc = -1.0;\r
+ \r
+ if (landed == 1 && !isprobe) {\r
+ prout("Dummy! You can't leave standard orbit until you");\r
+ proutn("are back abourt the ");\r
+ crmshp();\r
+ prout(".");\r
+ chew();\r
+ return;\r
+ }\r
+ while (automatic == -1) {\r
+ if (damage[DCOMPTR]) {\r
+ if (isprobe)\r
+ prout("Computer damaged; manual navigation only");\r
+ else\r
+ prout("Computer damaged; manual movement only");\r
+ chew();\r
+ automatic = 0;\r
+ key = IHEOL;\r
+ break;\r
+ }\r
+ if (isprobe && akey != -1) {\r
+ /* For probe launch, use pre-scaned value first time */\r
+ key = akey;\r
+ akey = -1;\r
+ }\r
+ else \r
+ key = scan();\r
+\r
+ if (key == IHEOL) {\r
+ proutn("Manual or automatic- ");\r
+ iprompt = 1;\r
+ chew();\r
+ }\r
+ else if (key == IHALPHA) {\r
+ if (isit("manual")) {\r
+ automatic =0;\r
+ key = scan();\r
+ break;\r
+ }\r
+ else if (isit("automatic")) {\r
+ automatic = 1;\r
+ key = scan();\r
+ break;\r
+ }\r
+ else {\r
+ huh();\r
+ chew();\r
+ return;\r
+ }\r
+ }\r
+ else { /* numeric */\r
+ if (isprobe)\r
+ prout("(Manual navigation assumed.)");\r
+ else\r
+ prout("(Manual movement assumed.)");\r
+ automatic = 0;\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (automatic) {\r
+ while (key == IHEOL) {\r
+ if (isprobe)\r
+ proutn("Target quadrant or quadrant§or- ");\r
+ else\r
+ proutn("Destination sector or quadrant§or- ");\r
+ chew();\r
+ iprompt = 1;\r
+ key = scan();\r
+ }\r
+\r
+ if (key != IHREAL) {\r
+ huh();\r
+ return;\r
+ }\r
+ xi = aaitem;\r
+ key = scan();\r
+ if (key != IHREAL){\r
+ huh();\r
+ return;\r
+ }\r
+ xj = aaitem;\r
+ key = scan();\r
+ if (key == IHREAL) {\r
+ /* both quadrant and sector specified */\r
+ xk = aaitem;\r
+ key = scan();\r
+ if (key != IHREAL) {\r
+ huh();\r
+ return;\r
+ }\r
+ xl = aaitem;\r
+\r
+ irowq = xi + 0.5;\r
+ icolq = xj + 0.5;\r
+ irows = xk + 0.5;\r
+ icols = xl + 0.5;\r
+ }\r
+ else {\r
+ if (isprobe) {\r
+ /* only quadrant specified -- go to center of dest quad */\r
+ irowq = xi + 0.5;\r
+ icolq = xj + 0.5;\r
+ irows = icols = 5;\r
+ }\r
+ else {\r
+ irows = xi + 0.5;\r
+ icols = xj + 0.5;\r
+ }\r
+ itemp = 1;\r
+ }\r
+ if (irowq<1 || irowq > 8 || icolq<1 || icolq > 8 ||\r
+ irows<1 || irows > 10 || icols<1 || icols > 10) {\r
+ huh();\r
+ return;\r
+ }\r
+ skip(1);\r
+ if (!isprobe) {\r
+ if (itemp) {\r
+ if (iprompt) {\r
+ proutn("Helmsman Sulu- \"Course locked in for");\r
+ cramlc(2, irows, icols);\r
+ prout(".\"");\r
+ }\r
+ }\r
+ else prout("Ensign Chekov- \"Course laid in, Captain.\"");\r
+ }\r
+ deltax = icolq - quady + 0.1*(icols-secty);\r
+ deltay = quadx - irowq + 0.1*(sectx-irows);\r
+ }\r
+ else { /* manual */\r
+ while (key == IHEOL) {\r
+ proutn("X and Y displacements- ");\r
+ chew();\r
+ iprompt = 1;\r
+ key = scan();\r
+ }\r
+ itemp = 2;\r
+ if (key != IHREAL) {\r
+ huh();\r
+ return;\r
+ }\r
+ deltax = aaitem;\r
+ key = scan();\r
+ if (key != IHREAL) {\r
+ huh();\r
+ return;\r
+ }\r
+ deltay = aaitem;\r
+ }\r
+ /* Check for zero movement */\r
+ if (deltax == 0 && deltay == 0) {\r
+ chew();\r
+ return;\r
+ }\r
+ if (itemp == 2 && !isprobe) {\r
+ skip(1);\r
+ prout("Helmsman Sulu- \"Aye, Sir.\"");\r
+ }\r
+ dist = sqrt(deltax*deltax + deltay*deltay);\r
+ direc = atan2(deltax, deltay)*1.90985932;\r
+ if (direc < 0.0) direc += 12.0;\r
+ chew();\r
+ return;\r
+\r
+}\r
+ \r
+\r
+\r
+void impuls(void) {\r
+ double power;\r
+\r
+ ididit = 0;\r
+ if (damage[DIMPULS]) {\r
+ chew();\r
+ skip(1);\r
+ prout("Engineer Scott- \"The impulse engines are damaged, Sir.\"");\r
+ return;\r
+ }\r
+\r
+ if (energy > 30.0) {\r
+ getcd(FALSE, 0);\r
+ if (direc == -1.0) return;\r
+ power = 20.0 + 100.0*dist;\r
+ }\r
+ else\r
+ power = 30.0;\r
+\r
+ if (power >= energy) {\r
+ /* Insufficient power for trip */\r
+ skip(1);\r
+ prout("First Officer Spock- \"Captain, the impulse engines");\r
+ prout("require 20.0 units to engage, plus 100.0 units per");\r
+ if (energy > 30) {\r
+ proutn("quadrant. We can go, therefore, a maximum of ");\r
+ cramf(0.01 * (energy-20.0)-0.05, 0, 1);\r
+ prout(" quadrants.\"");\r
+ }\r
+ else {\r
+ prout("quadrant. They are, therefore, useless.\"");\r
+ }\r
+ chew();\r
+ return;\r
+ }\r
+ /* Make sure enough time is left for the trip */\r
+ Time = dist/0.095;\r
+ if (Time >= d.remtime) {\r
+ prout("First Officer Spock- \"Captain, our speed under impulse");\r
+ prout("power is only 0.95 sectors per stardate. Are you sure");\r
+ prout("we dare spend the time?\"");\r
+ if (ja() == 0) return;\r
+ }\r
+ /* Activate impulse engines and pay the cost */\r
+ move();\r
+ ididit = 1;\r
+ if (alldone) return;\r
+ power = 20.0 + 100.0*dist;\r
+ energy -= power;\r
+ Time = dist/0.095;\r
+ if (energy <= 0) finish(FNRG);\r
+ return;\r
+}\r
+\r
+\r
+void warp(int i) {\r
+ int blooey=0, twarp=0, iwarp;\r
+ double power;\r
+\r
+ if (i!=2) { /* Not WARPX entry */\r
+ ididit = 0;\r
+ if (damage[DWARPEN] > 10.0) {\r
+ chew();\r
+ skip(1);\r
+ prout("Engineer Scott- \"The impulse engines are damaged, Sir.\"");\r
+ return;\r
+ }\r
+ if (damage[DWARPEN] > 0.0 && warpfac > 4.0) {\r
+ chew();\r
+ skip(1);\r
+ prout("Engineer Scott- \"Sorry, Captain. Until this damage");\r
+ prout(" is repaired, I can only give you warp 4.\"");\r
+ return;\r
+ }\r
+ \r
+ /* Read in course and distance */\r
+ getcd(FALSE, 0);\r
+ if (direc == -1.0) return;\r
+\r
+ /* Make sure starship has enough energy for the trip */\r
+ power = (dist+0.05)*warpfac*warpfac*warpfac*(shldup+1);\r
+\r
+\r
+ if (power >= energy) {\r
+ /* Insufficient power for trip */\r
+ ididit = 0;\r
+ skip(1);\r
+ prout("Engineering to bridge--");\r
+ if (shldup==0 || 0.5*power > energy) {\r
+ iwarp = pow((energy/(dist+0.05)), 0.333333333);\r
+ if (iwarp <= 0) {\r
+ prout("We can't do it, Captain. We haven't the energy.");\r
+ }\r
+ else {\r
+ proutn("We haven't the energy, but we could do it at warp ");\r
+ crami(iwarp, 1);\r
+ if (shldup)\r
+ prout(",\nif you'll lower the shields.");\r
+ else\r
+ prout(".");\r
+ }\r
+ }\r
+ else\r
+ prout("We haven't the energy to go that far with the shields up.");\r
+ return;\r
+ }\r
+ \r
+ /* Make sure enough time is left for the trip */\r
+ Time = 10.0*dist/wfacsq;\r
+ if (Time >= 0.8*d.remtime) {\r
+ skip(1);\r
+ prout("First Officer Spock- \"Captain, I compute that such");\r
+ proutn(" a trip would require approximately ");\r
+ cramf(100.0*Time/d.remtime, 0, 2);\r
+ prout(" percent of our");\r
+ prout(" remaining time. Are you sure this is wise?\"");\r
+ if (ja() == 0) { ididit = 0; return;}\r
+ }\r
+ }\r
+ /* Entry WARPX */\r
+ if (warpfac > 6.0) {\r
+ /* Decide if engine damage will occur */\r
+ double prob = dist*(6.0-warpfac)*(6.0-warpfac)/66.666666666;\r
+ if (prob > Rand()) {\r
+ blooey = 1;\r
+ dist = Rand()*dist;\r
+ }\r
+ /* Decide if time warp will occur */\r
+ if (0.5*dist*pow(7.0,warpfac-10.0) > Rand()) twarp=1;\r
+#ifdef DEBUG\r
+ if (idebug &&warpfac==10 && twarp==0) {\r
+ blooey=0;\r
+ proutn("Force time warp? ");\r
+ if (ja()==1) twarp=1;\r
+ }\r
+#endif\r
+ if (blooey || twarp) {\r
+ /* If time warp or engine damage, check path */\r
+ /* If it is obstructed, don't do warp or damage */\r
+ double angle = ((15.0-direc)*0.5235998);\r
+ double deltax = -sin(angle);\r
+ double deltay = cos(angle);\r
+ double bigger, x, y;\r
+ int n, l, ix, iy;\r
+ if (fabs(deltax) > fabs(deltay))\r
+ bigger = fabs(deltax);\r
+ else\r
+ bigger = fabs(deltay);\r
+ \r
+ deltax /= bigger;\r
+ deltay /= bigger;\r
+ n = 10.0 * dist * bigger +0.5;\r
+ x = sectx;\r
+ y = secty;\r
+ for (l = 1; l <= n; l++) {\r
+ x += deltax;\r
+ ix = x + 0.5;\r
+ if (ix < 1 || ix > 10) break;\r
+ y += deltay;\r
+ iy = y +0.5;\r
+ if (iy < 1 || iy > 10) break;\r
+ if (quad[ix][iy] != IHDOT) {\r
+ blooey = 0;\r
+ twarp = 0;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ \r
+\r
+ /* Activate Warp Engines and pay the cost */\r
+ move();\r
+ if (alldone) return;\r
+ energy -= dist*warpfac*warpfac*warpfac*(shldup+1);\r
+ if (energy <= 0) finish(FNRG);\r
+ Time = 10.0*dist/wfacsq;\r
+ if (twarp) timwrp();\r
+ if (blooey) {\r
+ damage[DWARPEN] = damfac*(3.0*Rand()+1.0);\r
+ skip(1);\r
+ prout("Engineering to bridge--");\r
+ prout(" Scott here. The warp engines are damaged.");\r
+ prout(" We'll have to reduce speed to warp 4.");\r
+ }\r
+ ididit = 1;\r
+ return;\r
+}\r
+\r
+\r
+\r
+void setwrp(void) {\r
+ int key;\r
+ double oldfac;\r
+ \r
+ while ((key=scan()) == IHEOL) {\r
+ chew();\r
+ proutn("Warp factor-");\r
+ }\r
+ chew();\r
+ if (key != IHREAL) {\r
+ huh();\r
+ return;\r
+ }\r
+ if (damage[DWARPEN] > 10.0) {\r
+ prout("Warp engines inoperative.");\r
+ return;\r
+ }\r
+ if (damage[DWARPEN] > 0.0 && aaitem > 4.0) {\r
+ prout("Engineer Scott- \"I'm doing my best, Captain,\n"\r
+ " but right now we can only go warp 4.\"");\r
+ return;\r
+ }\r
+ if (aaitem > 10.0) {\r
+ prout("Helmsman Sulu- \"Our top speed is warp 10, Captain.\"");\r
+ return;\r
+ }\r
+ if (aaitem < 1.0) {\r
+ prout("Helmsman Sulu- \"We can't go below warp 1, Captain.\"");\r
+ return;\r
+ }\r
+ oldfac = warpfac;\r
+ warpfac = aaitem;\r
+ wfacsq=warpfac*warpfac;\r
+ if (warpfac <= oldfac || warpfac <= 6.0) {\r
+ proutn("Helmsman Sulu- \"Warp factor ");\r
+ cramf(warpfac, 0, 1);\r
+ prout(", Captain.\"");\r
+ return;\r
+ }\r
+ if (warpfac < 8.00) {\r
+ prout("Engineer Scott- \"Aye, but our maximum safe speed is warp 6.\"");\r
+ return;\r
+ }\r
+ if (warpfac == 10.0) {\r
+ prout("Engineer Scott- \"Aye, Captain, we'll try it.\"");\r
+ return;\r
+ }\r
+ prout("Engineer Scott- \"Aye, Captain, but our engines may not take it.\"");\r
+ return;\r
+}\r
+\r
+void atover(int igrab) {\r
+ double power, distreq;\r
+\r
+ chew();\r
+ /* is captain on planet? */\r
+ if (landed==1) {\r
+ if (damage[DTRANSP]) {\r
+ finish(FPNOVA);\r
+ return;\r
+ }\r
+ prout("Scotty rushes to the transporter controls.");\r
+ if (shldup) {\r
+ prout("But with the shields up it's hopeless.");\r
+ finish(FPNOVA);\r
+ }\r
+ prouts("His desperate attempt to rescue you . . .");\r
+ if (Rand() <= 0.5) {\r
+ prout("fails.");\r
+ finish(FPNOVA);\r
+ return;\r
+ }\r
+ prout("SUCCEEDS!");\r
+ if (imine) {\r
+ imine = 0;\r
+ proutn("The crystals mined were ");\r
+ if (Rand() <= 0.25) {\r
+ prout("lost.");\r
+ }\r
+ else {\r
+ prout("saved.");\r
+ icrystl = 1;\r
+ }\r
+ }\r
+ }\r
+ if (igrab) return;\r
+\r
+ /* Check to see if captain in shuttle craft */\r
+ if (icraft) finish(FSTRACTOR);\r
+ if (alldone) return;\r
+\r
+ /* Inform captain of attempt to reach safety */\r
+ skip(1);\r
+ do {\r
+ if (justin) {\r
+ prouts("***RED ALERT! READ ALERT!");\r
+ skip(1);\r
+ proutn("The ");\r
+ crmshp();\r
+ prout(" has stopped in a quadrant containing");\r
+ prouts(" a supernova.");\r
+ skip(2);\r
+ }\r
+ proutn("***Emergency automatic override attempts to hurl ");\r
+ crmshp();\r
+ skip(1);\r
+ prout("safely out of quadrant.");\r
+ starch[quadx][quady] = damage[DRADIO] > 0.0 ? d.galaxy[quadx][quady]+1000:1;\r
+\r
+ /* Try to use warp engines */\r
+ if (damage[DWARPEN]) {\r
+ skip(1);\r
+ prout("Warp engines damaged.");\r
+ finish(FSNOVAED);\r
+ return;\r
+ }\r
+ warpfac = 6.0+2.0*Rand();\r
+ wfacsq = warpfac * warpfac;\r
+ proutn("Warp factor set to ");\r
+ cramf(warpfac, 1, 1);\r
+ skip(1);\r
+ power = 0.75*energy;\r
+ dist = power/(warpfac*warpfac*warpfac*(shldup+1));\r
+ distreq = 1.4142+Rand();\r
+ if (distreq < dist) dist = distreq;\r
+ Time = 10.0*dist/wfacsq;\r
+ direc = 12.0*Rand(); /* How dumb! */\r
+ justin = 0;\r
+ inorbit = 0;\r
+ warp(2);\r
+ if (justin == 0) {\r
+ /* This is bad news, we didn't leave quadrant. */\r
+ if (alldone) return;\r
+ skip(1);\r
+ prout("Insufficient energy to leave quadrant.");\r
+ finish(FSNOVAED);\r
+ return;\r
+ }\r
+ /* Repeat if another snova */\r
+ } while (d.galaxy[quadx][quady] == 1000);\r
+ if (d.remkl==0) finish(FWON); /* Snova killed remaining enemy. */\r
+}\r
+\r
+void timwrp() {\r
+ int l, ll, gotit;\r
+ prout("***TIME WARP ENTERED.");\r
+ if (d.snap && Rand() < 0.5) {\r
+ /* Go back in time */\r
+ proutn("You are traveling backwards in time ");\r
+ cramf(d.date-snapsht.date, 0, 2);\r
+ prout(" stardates.");\r
+ d = snapsht;\r
+ d.snap = 0;\r
+ if (d.remcom) {\r
+ future[FTBEAM] = d.date + expran(intime/d.remcom);\r
+ future[FBATTAK] = d.date + expran(0.3*intime);\r
+ }\r
+ future[FSNOVA] = d.date + expran(0.5*intime);\r
+ future[FSNAP] = d.date +expran(0.25*d.remtime); /* next snapshot will\r
+ be sooner */\r
+ if (d.nscrem) future[FSCMOVE] = 0.2777;\r
+ isatb = 0;\r
+ future[FCDBAS] = future[FSCDBAS] = 1e30;\r
+ batx = baty = 0;\r
+\r
+ /* Make sure Galileo is consistant -- Snapshot may have been taken\r
+ when on planet, which would give us two Galileos! */\r
+ gotit = 0;\r
+ for (l = 1; l <= inplan; l++) {\r
+ if (d.plnets[l].known == 2) {\r
+ gotit = 1;\r
+ if (iscraft==1 && ship==IHE) {\r
+ prout("Checkov- \"Security reports the Galileo has disappeared, Sir!");\r
+ iscraft = 0;\r
+ }\r
+ }\r
+ }\r
+ /* Likewise, if in the original time the Galileo was abandoned, but\r
+ was on ship earlier, it would have vanished -- lets restore it */\r
+ if (iscraft==0 && gotit==0 && damage[DSHUTTL] >= 0.0) {\r
+ prout("Checkov- \"Security reports the Galileo has reappeared in the dock!\"");\r
+ iscraft = 1;\r
+ }\r
+\r
+ /* Revert star chart to earlier era, if it was known then*/\r
+ if (damage[DRADIO]==0.0 || stdamtim > d.date) {\r
+ for (l = 1; l <= 8; l++)\r
+ for (ll = 1; ll <= 8; ll++)\r
+ if (starch[l][ll] > 1)\r
+ starch[l][ll]=damage[DRADIO]>0.0 ? d.galaxy[l][ll]+1000 :1;\r
+ prout("Spock has reconstructed a correct star chart from memory");\r
+ if (damage[DRADIO] > 0.0) stdamtim = d.date;\r
+ }\r
+ }\r
+ else {\r
+ /* Go forward in time */\r
+ Time = -0.5*intime*log(Rand());\r
+ proutn("You are traveling forward in time ");\r
+ cramf(Time, 1, 2);\r
+ prout(" stardates.");\r
+ /* cheat to make sure no tractor beams occur during time warp */\r
+ future[FTBEAM] += Time;\r
+ damage[DRADIO] += Time;\r
+ }\r
+ newqad(0);\r
+}\r
+\r
+void probe(void) {\r
+ double angle, bigger;\r
+ int key;\r
+ /* New code to launch a deep space probe */\r
+ if (nprobes == 0) {\r
+ chew();\r
+ skip(1);\r
+ if (ship == IHE) \r
+ prout("Engineer Scott- \"We have no more deep space probes, Sir.\"");\r
+ else\r
+ prout("Ye Faerie Queene has no deep space probes.");\r
+ return;\r
+ }\r
+ if (damage[DDSP] != 0.0) {\r
+ chew();\r
+ skip(1);\r
+ prout("Engineer Scott- \"The probe launcher is damaged, Sir.\"");\r
+ return;\r
+ }\r
+ if (future[FDSPROB] != 1e30) {\r
+ chew();\r
+ skip(1);\r
+ if (damage[DRADIO] != 0 && condit != IHDOCKED) {\r
+ prout("Spock- \"Records show the previous probe has not yet");\r
+ prout(" reached it's destination.\"");\r
+ }\r
+ else\r
+ prout("Uhura- \"The previous probe is still reporting data, Sir.\"");\r
+ return;\r
+ }\r
+ key = scan();\r
+\r
+ if (key == IHEOL) {\r
+ /* slow mode, so let Kirk know how many probes there are left */\r
+ crami(nprobes,1);\r
+ prout(nprobes==1 ? " probe left." : " probes left.");\r
+ proutn("Are you sure you want to fire a probe? ");\r
+ if (ja()==0) return;\r
+ }\r
+\r
+ isarmed = FALSE;\r
+ if (key == IHALPHA && strcmp(citem,"armed") == 0) {\r
+ isarmed = TRUE;\r
+ key = scan();\r
+ }\r
+ else if (key == IHEOL) {\r
+ proutn("Arm NOVAMAX warhead?");\r
+ isarmed = ja();\r
+ }\r
+ getcd(TRUE, key);\r
+ if (direc == -1.0) return;\r
+ nprobes--;\r
+ angle = ((15.0 - direc) * 0.5235988);\r
+ probeinx = -sin(angle);\r
+ probeiny = cos(angle);\r
+ if (fabs(probeinx) > fabs(probeiny))\r
+ bigger = fabs(probeinx);\r
+ else\r
+ bigger = fabs(probeiny);\r
+ \r
+ probeiny /= bigger;\r
+ probeinx /= bigger;\r
+ proben = 10.0*dist*bigger +0.5;\r
+ probex = quadx*10 + sectx - 1; // We will use better packing than original\r
+ probey = quady*10 + secty - 1;\r
+ probecx = quadx;\r
+ probecy = quady;\r
+ future[FDSPROB] = d.date + 0.01; // Time to move one sector\r
+ prout("Ensign Chekov- \"The deep space probe is launched, Captain.\"");\r
+ return;\r
+}\r
+\r
+void help(void) {\r
+ /* There's more than one way to move in this game! */\r
+ double ddist, xdist, probf;\r
+ int line, l, ix, iy;\r
+\r
+ chew();\r
+ /* Test for conditions which prevent calling for help */\r
+ if (condit == IHDOCKED) {\r
+ prout("Lt. Uhura- \"But Captain, we're already docked.\"");\r
+ return;\r
+ }\r
+ if (damage[DRADIO] != 0) {\r
+ prout("Subspace radio damaged.");\r
+ return;\r
+ }\r
+ if (d.rembase==0) {\r
+ prout("Lt. Uhura- \"Captain, I'm not getting any response from Starbase.\"");\r
+ return;\r
+ }\r
+ if (landed == 1) {\r
+ proutn("You must be aboard the ");\r
+ crmshp();\r
+ prout(".");\r
+ return;\r
+ }\r
+ /* OK -- call for help from nearest starbase */\r
+ nhelp++;\r
+ if (basex!=0) {\r
+ /* There's one in this quadrant */\r
+ ddist = sqrt(square(basex-sectx)+square(basey-secty));\r
+ }\r
+ else {\r
+ ddist = 1e30;\r
+ for (l = 1; l <= d.rembase; l++) {\r
+ xdist=10.0*sqrt(square(d.baseqx[l]-quadx)+square(d.baseqy[l]-quady));\r
+ if (xdist < ddist) {\r
+ ddist = xdist;\r
+ line = l;\r
+ }\r
+ }\r
+ /* Since starbase not in quadrant, set up new quadrant */\r
+ quadx = d.baseqx[line];\r
+ quady = d.baseqy[line];\r
+ newqad(1);\r
+ }\r
+ /* dematerialize starship */\r
+ quad[sectx][secty]=IHDOT;\r
+ proutn("Starbase in");\r
+ cramlc(1, quadx, quady);\r
+ proutn(" responds--");\r
+ crmshp();\r
+ prout(" dematerializes.");\r
+ /* Give starbase three chances to rematerialize starship */\r
+ probf = pow((1.0 - pow(0.98,ddist)), 0.33333333);\r
+ for (l = 1; l <= 3; l++) {\r
+ switch (l) {\r
+ case 1: proutn("1st"); break;\r
+ case 2: proutn("2nd"); break;\r
+ case 3: proutn("3rd"); break;\r
+ }\r
+ proutn(" attempt to re-materialize ");\r
+ crmshp();\r
+ prouts(" . . . . . ");\r
+ if (Rand() > probf) break;\r
+ prout("fails.");\r
+ }\r
+ if (l > 3) {\r
+ finish(FMATERIALIZE);\r
+ return;\r
+ }\r
+ /* Rematerialization attempt should succeed if can get adj to base */\r
+ for (l = 1; l <= 5; l++) {\r
+ ix = basex+3.0*Rand()-1;\r
+ iy = basey+3.0*Rand()-1;\r
+ if (ix>=1 && ix<=10 && iy>=1 && iy<=10 && quad[ix][iy]==IHDOT) {\r
+ /* found one -- finish up */\r
+ prout("succeeds.");\r
+ sectx=ix;\r
+ secty=iy;\r
+ quad[ix][iy]=ship;\r
+ dock();\r
+ skip(1);\r
+ prout("Lt. Uhura- \"Captain, we made it!\"");\r
+ return;\r
+ }\r
+ }\r
+ finish(FMATERIALIZE);\r
+ return;\r
+}\r
--- /dev/null
+#include <stdlib.h>\r
+#include <time.h>\r
+#include <sys/ioctl.h>\r
+#include <sys/termio.h>\r
+\r
+void randomize(void) {\r
+ srand((int)time(NULL));\r
+}\r
+\r
+\r
+int max(int a, int b) {\r
+ if (a > b) return a;\r
+ return b;\r
+}\r
+\r
+int min(int a, int b) {\r
+ if (a < b) return a;\r
+ return b;\r
+}\r
+\r
+int getch(void) {\r
+ char chbuf[1];\r
+ struct termio oldstate, newstate;\r
+ ioctl(0,TCGETA,&oldstate);\r
+ newstate = oldstate;\r
+ newstate.c_iflag = 0;\r
+ newstate.c_lflag = 0;\r
+ ioctl(0,TCSETA,&newstate);\r
+ read(0, &chbuf, 1);\r
+ ioctl(0,TCSETA,&oldstate);\r
+}
\ No newline at end of file
--- /dev/null
+#include "sst.h"\r
+\r
+static char classes[4][2]={"","M","N","O"};\r
+static int height;\r
+\r
+static int consumeTime(void) {\r
+/* I think most of this avoidance was caused by overlay scheme.\r
+ Let's see what happens if all events can occur here */\r
+\r
+// double asave;\r
+ ididit = 1;\r
+#if 0\r
+ /* Don't wory about this */\r
+ if (future[FTBEAM] <= d.date+Time && d.remcom != 0 && condit != IHDOCKED) {\r
+ /* We are about to be tractor beamed -- operation fails */\r
+ return 1;\r
+ }\r
+#endif\r
+// asave = future[FSNOVA];\r
+// future[FSNOVA] = 1e30; /* defer supernovas */\r
+ events(); /* Used to avoid if future[FSCMOVE] within time */\r
+// future[FSNOVA] = asave;\r
+ /*fails if game over, quadrant super-novas or we've moved to new quadrant*/\r
+ if (alldone || d.galaxy[quadx][quady] == 1000 || justin != 0) return 1;\r
+ return 0;\r
+}\r
+\r
+void preport(void) {\r
+ int iknow = 0, i;\r
+ skip(1);\r
+ chew();\r
+ prout("Spock- \"Planet report follows, Captain.\"");\r
+ skip(1);\r
+ for (i = 1; i <= inplan; i++) {\r
+ if (d.plnets[i].known\r
+#ifdef DEBUG\r
+ || ( idebug && d.plnets[i].x !=0)\r
+#endif\r
+ ) {\r
+ iknow = 1;\r
+#ifdef DEBUG\r
+ if (idebug && d.plnets[i].known==0) proutn("(Unknown) ");\r
+#endif\r
+ cramlc(1, d.plnets[i].x, d.plnets[i].y);\r
+ proutn(" class ");\r
+ proutn(classes[d.plnets[i].pclass]);\r
+ proutn(" ");\r
+ if (d.plnets[i].crystals == 0) proutn("no ");\r
+ prout("dilithium crystals present.");\r
+ if (d.plnets[i].known==2) \r
+ prout(" Shuttle Craft Galileo on surface.");\r
+ }\r
+ }\r
+ if (iknow==0) prout("No information available.");\r
+}\r
+\r
+void orbit(void) {\r
+ double asave;\r
+\r
+ skip(1);\r
+ chew();\r
+ ididit=0;\r
+ if (inorbit!=0) {\r
+ prout("Already in standard orbit.");\r
+ return;\r
+ }\r
+ if (damage[DWARPEN] != 0 && damage[DIMPULS] != 0) {\r
+ prout("Both warp and impulse engines damaged.");\r
+ return;\r
+ }\r
+ if (plnetx == 0 || abs(sectx-plnetx) > 1 || abs(secty-plnety) > 1) {\r
+ crmshp();\r
+ prout(" not adjacient to planet.\n");\r
+ return;\r
+ }\r
+ Time = 0.02+0.03*Rand();\r
+ prout("Helmsman Sulu- \"Entering standard orbit, Sir.\"");\r
+ newcnd();\r
+ if (consumeTime()) return;\r
+ proutn("Sulu- \"Entered orbit at altitude ");\r
+ cramf(height = (1400.+7200.*Rand()), 0, 2);\r
+ prout(" kilometers.\"");\r
+ inorbit = 1;\r
+ return;\r
+}\r
+\r
+void sensor(void) {\r
+ skip(1);\r
+ chew();\r
+ if (damage[DSRSENS] != 0.0) {\r
+ prout("Short range sensors damaged.");\r
+ return;\r
+ }\r
+ if (plnetx == 0) {\r
+ prout("No planet in this quadrant.");\r
+ return;\r
+ }\r
+ proutn("Spock- \"Sensor scan for");\r
+ cramlc(1, quadx, quady);\r
+ prout("-");\r
+ skip(1);\r
+ proutn(" Planet at");\r
+ cramlc(2, plnetx, plnety);\r
+ proutn(" is of class ");\r
+ proutn(classes[d.plnets[iplnet].pclass]);\r
+ prout(".");\r
+ if (d.plnets[iplnet].known==2) \r
+ prout(" Sensors show Galileo still on surface.");\r
+ proutn(" Readings indicate");\r
+ if (d.plnets[iplnet].crystals == 0) proutn(" no");\r
+ prout(" dilithium crystals present.\"");\r
+ if (d.plnets[iplnet].known == 0) d.plnets[iplnet].known = 1;\r
+ return;\r
+}\r
+\r
+void beam(void) {\r
+ chew();\r
+ skip(1);\r
+ if (damage[DTRANSP] != 0) {\r
+ prout("Transporter damaged.");\r
+ if (damage[DSHUTTL]==0 && (d.plnets[iplnet].known==2 || iscraft == 1)) {\r
+ skip(1);\r
+ prout("Spock- \"May I suggest the shuttle craft, Sir?\" ");\r
+ if (ja() != 0) shuttle();\r
+ }\r
+ return;\r
+ }\r
+ if (inorbit==0) {\r
+ crmshp();\r
+ prout(" not in standard orbit.");\r
+ return;\r
+ }\r
+ if (shldup!=0) {\r
+ prout("Impossible to transport through shields.");\r
+ return;\r
+ }\r
+ if (d.plnets[iplnet].known==0) {\r
+ prout("Spock- \"Captain, we have no information on this planet");\r
+ prout(" and Starfleet Regulations clearly state that in this situation");\r
+ prout(" you may not go down.\"");\r
+ return;\r
+ }\r
+ if (landed==1) {\r
+ /* Coming from planet */\r
+ if (d.plnets[iplnet].known==2) {\r
+ proutn("Spock- \"Wouldn't you rather take the Galileo?\" ");\r
+ if (ja() != 0) {\r
+ chew();\r
+ return;\r
+ }\r
+ prout("Your crew hides the Galileo to prevent capture by aliens.");\r
+ }\r
+ prout("Landing party assembled, ready to beam up.");\r
+ skip(1);\r
+ prout("Kirk whips out communicator...");\r
+ prouts("BEEP BEEP BEEP");\r
+ skip(2);\r
+ prout("\"Kirk to enterprise- Lock on coordinates...energize.\"");\r
+ }\r
+ else {\r
+ /* Going to planet */\r
+ if (d.plnets[iplnet].crystals==0) {\r
+ prout("Spock- \"Captain, I fail to see the logic in");\r
+ prout(" exploring a planet with no dilithium crystals.");\r
+ proutn(" Are you sure this is wise?\" ");\r
+ if (ja()==0) {\r
+ chew();\r
+ return;\r
+ }\r
+ }\r
+ prout("Scotty- \"Transporter room ready, Sir.\"");\r
+ skip(1);\r
+ prout("Kirk, and landing party prepare to beam down to planet surface.");\r
+ skip(1);\r
+ prout("Kirk- \"Energize.\"");\r
+ }\r
+ skip(1);\r
+ prouts("WWHOOOIIIIIRRRRREEEE.E.E. . . . . . .");\r
+ skip(2);\r
+ if (Rand() > 0.98) {\r
+ prouts("BOOOIIIOOOIIOOOOIIIOIING . . .");\r
+ skip(2);\r
+ prout("Scotty- \"Oh my God! I've lost them.\"");\r
+ finish(FLOST);\r
+ return;\r
+ }\r
+ prouts(". . . . . . .E.E.EEEERRRRRIIIIIOOOHWW");\r
+ skip(2);\r
+ prout("Transport complete.");\r
+ landed = -landed;\r
+ if (landed==1 && d.plnets[iplnet].known==2) {\r
+ prout("The shuttle craft Galileo is here!");\r
+ }\r
+ if (landed!=1 && imine==1) {\r
+ icrystl = 1;\r
+ cryprob = 0.05;\r
+ }\r
+ imine = 0;\r
+ return;\r
+}\r
+\r
+void mine(void) {\r
+\r
+ ididit = 0;\r
+ skip(1);\r
+ chew();\r
+ if (landed!= 1) {\r
+ prout("Mining party not on planet.");\r
+ return;\r
+ }\r
+ if (d.plnets[iplnet].crystals == 0) {\r
+ prout("No dilithium crystals on this planet.");\r
+ return;\r
+ }\r
+ if (imine == 1) {\r
+ prout("You've already mined enough crystals for this trip.");\r
+ return;\r
+ }\r
+ if (icrystl == 1 && cryprob == 0.05) {\r
+ proutn("With all those fresh crystals aboard the ");\r
+ crmshp();\r
+ skip(1);\r
+ prout("there's no reason to mine more at this time.");\r
+ return;\r
+ }\r
+ Time = (0.1+0.2*Rand())*d.plnets[iplnet].pclass;\r
+ if (consumeTime()) return;\r
+ prout("Mining operation complete.");\r
+ imine = 1;\r
+ return;\r
+}\r
+\r
+void usecrystals(void) {\r
+\r
+ skip(1);\r
+ chew();\r
+ if (icrystl!=1) {\r
+ prout("No dilithium crystals available.");\r
+ return;\r
+ }\r
+ if (energy >= 1000) {\r
+ prout("Spock- \"Captain, Starfleet Regulations prohibit such an operation");\r
+ prout(" except when condition Yellow exists.");\r
+ return;\r
+ }\r
+ prout("Spock- \"Captain, I must warn you that loading");\r
+ prout(" raw dilithium crystals into the ship's power");\r
+ prout(" system may risk a severe explosion.");\r
+ proutn(" Are you sure this is wise?\" ");\r
+ if (ja()==0) {\r
+ chew();\r
+ return;\r
+ }\r
+ skip(1);\r
+ prout("Engineering Officer Scott- \"(GULP) Aye Sir.");\r
+ prout(" Mr. Spock and I will try it.\"");\r
+ skip(1);\r
+ prout("Spock- \"Crystals in place, Sir.");\r
+ prout(" Ready to activate circuit.\"");\r
+ skip(1);\r
+ prouts("Scotty- \"Keep your fingers crossed, Sir!\"");\r
+ skip(1);\r
+ if (Rand() <= cryprob) {\r
+ prouts(" \"Activating now! - - No good! It's***");\r
+ skip(2);\r
+ prouts("***RED ALERT! RED A*L********************************");\r
+ skip(1);\r
+ stars();\r
+ prouts("****************** KA-BOOM!!!! *******************");\r
+ skip(1);\r
+ kaboom();\r
+ return;\r
+ }\r
+ energy += 5000.0*(1.0 + 0.9*Rand());\r
+ prouts(" \"Activating now! - - ");\r
+ prout("The instruments");\r
+ prout(" are going crazy, but I think it's");\r
+ prout(" going to work!! Congratulations, Sir!\"");\r
+ cryprob *= 2.0;\r
+ return;\r
+}\r
+\r
+void shuttle(void) {\r
+\r
+ chew();\r
+ skip(1);\r
+ ididit = 0;\r
+ if(damage[DSHUTTL] != 0.0) {\r
+ if (damage[DSHUTTL] == -1.0) {\r
+ if (inorbit && d.plnets[iplnet].known == 2)\r
+ prout("Ye Faerie Queene has no shuttle craft bay to dock it at.");\r
+ else\r
+ prout("Ye Faerie Queene had no shuttle craft.");\r
+ }\r
+ else if (damage[DSHUTTL] > 0)\r
+ prout("The Galileo is damaged.");\r
+ else prout("Shuttle craft is now serving Big Mac's.");\r
+ return;\r
+ }\r
+ if (inorbit==0) {\r
+ crmshp();\r
+ prout(" not in standard orbit.");\r
+ return;\r
+ }\r
+ if ((d.plnets[iplnet].known != 2) && iscraft != 1) {\r
+ prout("Shuttle craft not currently available.");\r
+ return;\r
+ }\r
+ if (landed==-1 && d.plnets[iplnet].known==2) {\r
+ prout("You will have to beam down to retrieve the shuttle craft.");\r
+ return;\r
+ }\r
+ if (shldup!=0 || condit == IHDOCKED) {\r
+ prout("Shuttle craft cannot pass through shields.");\r
+ return;\r
+ }\r
+ if (d.plnets[iplnet].known==0) {\r
+ prout("Spock- \"Captain, we have no information on this planet");\r
+ prout(" and Starfleet Regulations clearly state that in this situation");\r
+ prout(" you may not fly down.\"");\r
+ return;\r
+ }\r
+ Time = 3.0e-5*height;\r
+ if (Time >= 0.8*d.remtime) {\r
+ prout("First Officer Spock- \"Captain, I compute that such");\r
+ prout(" a maneuver would require aproximately ");\r
+ cramf(100*Time/d.remtime,0,4);\r
+ prout("% of our");\r
+ prout("remaining time.");\r
+ prout("Are you sure this is wise?\" ");\r
+ if (ja()==0) {\r
+ Time = 0.0;\r
+ return;\r
+ }\r
+ }\r
+ if (landed == 1) {\r
+ /* Kirk on planet */\r
+ if (iscraft==1) {\r
+ /* Galileo on ship! */\r
+ if (damage[DTRANSP]==0) {\r
+ proutn("Spock- \"Would you rather use the transporter?\" ");\r
+ if (ja() != 0) {\r
+ beam();\r
+ return;\r
+ }\r
+ proutn("Shuttle crew");\r
+ }\r
+ else\r
+ proutn("Rescue party");\r
+ prout(" boards Galileo and swoops toward planet surface.");\r
+ iscraft = 0;\r
+ skip(1);\r
+ if (consumeTime()) return;\r
+ d.plnets[iplnet].known=2;\r
+ prout("Trip complete.");\r
+ return;\r
+ }\r
+ else {\r
+ /* Ready to go back to ship */\r
+ prout("You and your mining party board the");\r
+ prout("shuttle craft for the trip back to the Enterprise.");\r
+ skip(1);\r
+ prout("The short hop begins . . .");\r
+ d.plnets[iplnet].known=1;\r
+ icraft = 1;\r
+ skip(1);\r
+ landed = -1;\r
+ if (consumeTime()) return;\r
+ iscraft = 1;\r
+ icraft = 0;\r
+ if (imine!=0) {\r
+ icrystl = 1;\r
+ cryprob = 0.05;\r
+ }\r
+ imine = 0;\r
+ prout("Trip complete.");\r
+ return;\r
+ }\r
+ }\r
+ else {\r
+ /* Kirk on ship */\r
+ /* and so is Galileo */\r
+ prout("Mining party assembles in the hangar deck,");\r
+ prout("ready to board the shuttle craft \"Galileo\".");\r
+ skip(1);\r
+ prouts("The hangar doors open; the trip begins.");\r
+ skip(1);\r
+ icraft = 1;\r
+ iscraft = 0;\r
+ if (consumeTime()) return;\r
+ d.plnets[iplnet].known = 2;\r
+ landed = 1;\r
+ icraft = 0;\r
+ prout("Trip complete");\r
+ return;\r
+ }\r
+}\r
+ \r
+\r
+void deathray(void) {\r
+ double r = Rand();\r
+ \r
+ ididit = 0;\r
+ skip(1);\r
+ chew();\r
+ if (ship != IHE) {\r
+ prout("Ye Faerie Queene has no death ray.");\r
+ return;\r
+ }\r
+ if (nenhere==0) {\r
+ prout("Sulu- \"But Sir, there are no enemies in this quadrant.\"");\r
+ return;\r
+ }\r
+ if (damage[DDRAY] > 0.0) {\r
+ prout("Death Ray is damaged.");\r
+ return;\r
+ }\r
+ prout("Spock- \"Captain, the 'Experimental Death Ray'");\r
+ prout(" is highly unpredictible. Considering the alternatives,");\r
+ prout(" are you sure this is wise?\" ");\r
+ if (ja()==0) return;\r
+ prout("Spock- \"Acknowledged.\"");\r
+ skip(1);\r
+ ididit=1;\r
+ prouts("WHOOEE ... WHOOEE ... WHOOEE ... WHOOEE");\r
+ skip(1);\r
+ prout("Crew scrambles in emergency preparation.");\r
+ prout("Spock and Scotty ready the death ray and");\r
+ prout("prepare to channel all ship's power to the device.");\r
+ skip(1);\r
+ prout("Spock- \"Preparations complete, sir.\"");\r
+ prout("Kirk- \"Engage!\"");\r
+ skip(1);\r
+ prouts("WHIRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR");\r
+ skip(1);\r
+ if (r > .30) {\r
+ prouts("Sulu- \"Captain! It's working!\"");\r
+ skip(2);\r
+ while (nenhere > 0)\r
+ deadkl(kx[1],ky[1],quad[kx[1]][ky[1]],kx[1],ky[1]);\r
+ prout("Ensign Chekov- \"Congratulations, Captain!\"");\r
+ if (d.remkl == 0) finish(FWON);\r
+ prout("Spock- \"Captain, I believe the `Experimental Death Ray'");\r
+ if (Rand() <= 0.05) {\r
+ prout(" is still operational.\"");\r
+ }\r
+ else {\r
+ prout(" has been rendered disfunctional.\"");\r
+ damage[DDRAY] = 39.95;\r
+ }\r
+ return;\r
+ }\r
+ r = Rand(); // Pick failure method \r
+ if (r <= .30) {\r
+ prouts("Sulu- \"Captain! It's working!\"");\r
+ skip(1);\r
+ prouts("***RED ALERT! RED ALERT!");\r
+ skip(1);\r
+ prout("***MATTER-ANTIMATTER IMPLOSION IMMINENT!");\r
+ skip(1);\r
+ prouts("***RED ALERT! RED A*L********************************");\r
+ skip(1);\r
+ stars();\r
+ prouts("****************** KA-BOOM!!!! *******************");\r
+ skip(1);\r
+ kaboom();\r
+ return;\r
+ }\r
+ if (r <= .55) {\r
+ prouts("Sulu- \"Captain! Yagabandaghangrapl, brachriigringlanbla!\"");\r
+ skip(1);\r
+ prout("Lt. Uhura- \"Graaeek! Graaeek!\"");\r
+ skip(1);\r
+ prout("Spock- \"Facinating! . . . All humans aboard");\r
+ prout(" have apparently been transformed into strange mutations.");\r
+ prout(" Vulcans do not seem to be affected.");\r
+ skip(1);\r
+ prout("Kirk- \"Raauch! Raauch!\"");\r
+ finish(FDRAY);\r
+ return;\r
+ }\r
+ if (r <= 0.75) {\r
+ int i,j;\r
+ prouts("Sulu- \"Captain! It's --WHAT?!?!\"");\r
+ skip(2);\r
+ proutn("Spock- \"I believe the word is");\r
+ prouts(" *ASTONISHING*");\r
+ prout(" Mr. Sulu.");\r
+ for (i=1; i<=10; i++)\r
+ for (j=1; j<=10; j++)\r
+ if (quad[i][j] == IHDOT) quad[i][j] = IHQUEST;\r
+ prout(" Captain, our quadrant is now infested with");\r
+ prouts(" - - - - - - *THINGS*.");\r
+ skip(1);\r
+ prout(" I have no logical explanation.\"");\r
+ return;\r
+ }\r
+ prouts("Sulu- \"Captain! The Death Ray is creating tribbles!\"");\r
+ skip(1);\r
+ prout("Scotty- \"There are so many tribbles down here");\r
+ prout(" in Engineering, we can't move for 'em, Captain.\"");\r
+ finish(FTRIBBLE);\r
+ return;\r
+}\r
--- /dev/null
+#include "sst.h"\r
+#include <math.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+\r
+void attakreport(void) {\r
+ if (future[FCDBAS] < 1e30) {\r
+ proutn("Starbase in ");\r
+ cramlc(1, batx, baty);\r
+ prout(" is currently under attack.");\r
+ proutn("It can hold out until Stardate ");\r
+ cramf(future[FCDBAS], 0,1);\r
+ prout(".");\r
+ }\r
+ if (isatb == 1) {\r
+ proutn("Starbase in ");\r
+ cramlc(1, d.isx, d.isy);\r
+ prout(" is under Super-commander attack.");\r
+ proutn("It can hold out until Stardate ");\r
+ cramf(future[FSCDBAS], 0, 1);\r
+ prout(".");\r
+ }\r
+}\r
+ \r
+\r
+void report(int f) {\r
+ char *s1,*s2,*s3;\r
+\r
+ chew();\r
+ s1 = (thawed?"thawed ":"");\r
+ switch (length) {\r
+ case 1: s2="short"; break;\r
+ case 2: s2="medium"; break;\r
+ case 4: s2="long"; break;\r
+ default: s2="unknown length"; break;\r
+ }\r
+ switch (skill) {\r
+ case 1: s3="novice"; break;\r
+ case 2: s3="fair"; break;\r
+ case 3: s3="good"; break;\r
+ case 4: s3="expert"; break;\r
+ case 5: s3="emeritus"; break;\r
+ default: s3="skilled"; break;\r
+ }\r
+ printf("\nYou %s playing a %s%s %s game.\n",\r
+ alldone? "were": "are now", s1, s2, s3);\r
+ if (skill>3 && thawed && !alldone) prout("No plaque is allowed.");\r
+ if (tourn) printf("This is tournament game %d.\n", tourn);\r
+ if (f) printf("Your secret password is \"%s\"\n",passwd);\r
+ printf("%d of %d Klingons have been killed",\r
+ d.killk+d.killc+d.nsckill, inkling);\r
+ if (d.killc) printf(", including %d Commander%s.\n", d.killc, d.killc==1?"":"s");\r
+ else if (d.killk+d.nsckill > 0) prout(", but no Commanders.");\r
+ else prout(".");\r
+ if (skill > 2) printf("The Super Commander has %sbeen destroyed.\n",\r
+ d.nscrem?"not ":"");\r
+ if (d.rembase != inbase) {\r
+ proutn("There ");\r
+ if (inbase-d.rembase==1) proutn("has been 1 base");\r
+ else {\r
+ proutn("have been ");\r
+ crami(inbase-d.rembase, 1);\r
+ proutn(" bases");\r
+ }\r
+ proutn(" destroyed, ");\r
+ crami(d.rembase, 1);\r
+ prout(" remaining.");\r
+ }\r
+ else printf("There are %d bases.\n", inbase);\r
+ if (damage[DRADIO] == 0.0 || condit == IHDOCKED || iseenit) {\r
+ /* Don't report this if not seen and\r
+ either the radio is dead or not at base! */\r
+ attakreport();\r
+ iseenit = 1;\r
+ }\r
+ if (casual) printf("%d casualt%s suffered so far.\n",\r
+ casual, casual==1? "y" : "ies");\r
+ if (nhelp) printf("There were %d call%s for help.\n",\r
+ nhelp, nhelp==1 ? "" : "s");\r
+ if (ship == IHE) {\r
+ proutn("You have ");\r
+ if (nprobes) crami(nprobes,1);\r
+ else proutn("no");\r
+ proutn(" deep space probe");\r
+ if (nprobes!=1) proutn("s");\r
+ prout(".");\r
+ }\r
+ if ((damage[DRADIO] == 0.0 || condit == IHDOCKED)&&\r
+ future[FDSPROB] != 1e30) {\r
+ if (isarmed) \r
+ proutn("An armed deep space probe is in");\r
+ else\r
+ proutn("A deep space probe is in");\r
+ cramlc(1, probecx, probecy);\r
+ prout(".");\r
+ }\r
+ if (icrystl) {\r
+ if (cryprob <= .05)\r
+ prout("Dilithium crystals aboard ship...not yet used.");\r
+ else {\r
+ int i=0;\r
+ double ai = 0.05;\r
+ while (cryprob > ai) {\r
+ ai *= 2.0;\r
+ i++;\r
+ }\r
+ printf("Dilithium crystals have been used %d time%s.\n",\r
+ i, i==1? "" : "s");\r
+ }\r
+ }\r
+ skip(1);\r
+}\r
+ \r
+void lrscan(void) {\r
+ int x, y;\r
+ chew();\r
+ if (damage[DLRSENS] != 0.0) {\r
+ /* Now allow base's sensors if docked */\r
+ if (condit != IHDOCKED) {\r
+ prout("LONG-RANGE SENSORS DAMAGED.");\r
+ return;\r
+ }\r
+ skip(1);\r
+ proutn("Starbase's long-range scan for");\r
+ }\r
+ else {\r
+ skip(1);\r
+ proutn("Long-range scan for");\r
+ }\r
+ cramlc(1, quadx, quady);\r
+ skip(1);\r
+ for (x = quadx-1; x <= quadx+1; x++) {\r
+ for (y = quady-1; y <= quady+1; y++) {\r
+ if (x == 0 || x > 8 || y == 0 || y > 8)\r
+ printf(" -1");\r
+ else {\r
+ printf("%5d", d.galaxy[x][y]);\r
+ starch[x][y] = damage[DRADIO] > 0 ? d.galaxy[x][y]+1000 :1;\r
+ }\r
+ }\r
+ putchar('\n');\r
+ }\r
+\r
+}\r
+\r
+void dreprt(void) {\r
+ int jdam = FALSE, i;\r
+ chew();\r
+\r
+ for (i = 1; i <= ndevice; i++) {\r
+ if (damage[i] > 0.0) {\r
+ if (!jdam) {\r
+ skip(1);\r
+ prout("DEVICE -REPAIR TIMES-");\r
+ prout(" IN FLIGHT DOCKED");\r
+ jdam = TRUE;\r
+ }\r
+ printf(" %16s ", device[i]);\r
+ cramf(damage[i]+0.05, 8, 2);\r
+ proutn(" ");\r
+ cramf(docfac*damage[i]+0.005, 8, 2);\r
+ skip(1);\r
+ }\r
+ }\r
+ if (!jdam) prout("All devices functional.");\r
+}\r
+\r
+void chart(int nn) {\r
+ int i,j;\r
+\r
+ chew();\r
+ skip(1);\r
+ if (stdamtim != 1e30 && stdamtim != d.date && condit == IHDOCKED) {\r
+ prout("Spock- \"I revised the Star Chart from the");\r
+ prout(" starbase's records.\"");\r
+ skip(1);\r
+ }\r
+ if (nn == 0) prout("STAR CHART FOR THE KNOWN GALAXY");\r
+ if (stdamtim != 1e30) {\r
+ if (co