/programs/games/sstartrek/en/ai.c |
---|
0,0 → 1,610 |
#include "sst.h" |
static int tryexit(int lookx, int looky, int ienm, int loccom, int irun) { |
int iqx, iqy, l; |
iqx = quadx+(lookx+9)/10 - 1; |
iqy = quady+(looky+9)/10 - 1; |
if (iqx < 1 || iqx > 8 || iqy < 1 || iqy > 8 || |
d.galaxy[iqx][iqy] > 899) |
return 0; /* no can do -- neg energy, supernovae, or >8 Klingons */ |
if (ienm == IHR) return 0; /* Romulans cannot escape! */ |
if (irun == 0) { |
/* avoid intruding on another commander's territory */ |
if (ienm == IHC) { |
for (l = 1; l <= d.remcom; l++) |
if (d.cx[l]==iqx && d.cy[l]==iqy) return 0; |
/* refuse to leave if currently attacking starbase */ |
if (batx==quadx && baty==quady) return 0; |
} |
/* don't leave if over 1000 units of energy */ |
if (kpower[loccom] > 1000.) return 0; |
} |
/* print escape message and move out of quadrant. |
We know this if either short or long range sensors are working */ |
if (damage[DSRSENS] == 0.0 || damage[DLRSENS] == 0.0 || |
condit == IHDOCKED) { |
proutn("***"); |
cramen(ienm); |
proutn(" escapes to"); |
cramlc(1, iqx, iqy); |
prout(" (and regains strength)."); |
} |
/* handle local matters related to escape */ |
kx[loccom] = kx[nenhere]; |
ky[loccom] = ky[nenhere]; |
kavgd[loccom] = kavgd[nenhere]; |
kpower[loccom] = kpower[nenhere]; |
kdist[loccom] = kdist[nenhere]; |
klhere--; |
nenhere--; |
if (condit != IHDOCKED) newcnd(); |
/* Handle global matters related to escape */ |
d.galaxy[quadx][quady] -= 100; |
d.galaxy[iqx][iqy] += 100; |
if (ienm==IHS) { |
ishere=0; |
iscate=0; |
ientesc=0; |
isatb=0; |
future[FSCMOVE]=0.2777+d.date; |
future[FSCDBAS]=1e30; |
d.isx=iqx; |
d.isy=iqy; |
} |
else { |
for (l=1; l<=d.remcom; l++) { |
if (d.cx[l]==quadx && d.cy[l]==quady) { |
d.cx[l]=iqx; |
d.cy[l]=iqy; |
break; |
} |
} |
comhere = 0; |
} |
return 1; /* success */ |
} |
static void movebaddy(int comx, int comy, int loccom, int ienm) { |
int motion, mdist, nsteps, mx, my, nextx, nexty, lookx, looky, ll; |
int irun = 0; |
int krawlx, krawly; |
int success; |
int attempts; |
/* This should probably be just comhere + ishere */ |
int nbaddys = skill > SGOOD ? |
(int)((comhere*2 + ishere*2+klhere*1.23+irhere*1.5)/2.0): |
(comhere + ishere); |
double dist1, forces; |
dist1 = kdist[loccom]; |
mdist = dist1 + 0.5; /* Nearest integer distance */ |
/* If SC, check with spy to see if should hi-tail it */ |
if (ienm==IHS && |
(kpower[loccom] <= 500.0 || (condit==IHDOCKED && damage[DPHOTON]==0))) { |
irun = 1; |
motion = -10; |
} |
else { |
/* decide whether to advance, retreat, or hold position */ |
/* Algorithm: |
* Enterprise has "force" based on condition of phaser and photon torpedoes. |
If both are operating full strength, force is 1000. If both are damaged, |
force is -1000. Having shields down subtracts an additional 1000. |
* Enemy has forces equal to the energy of the attacker plus |
100*(K+R) + 500*(C+S) - 400 for novice through good levels OR |
346*K + 400*R + 500*(C+S) - 400 for expert and emeritus. |
Attacker Initial energy levels (nominal): |
Klingon Romulan Commander Super-Commander |
Novice 400 700 1200 |
Fair 425 750 1250 |
Good 450 800 1300 1750 |
Expert 475 850 1350 1875 |
Emeritus 500 900 1400 2000 |
VARIANCE 75 200 200 200 |
Enemy vessels only move prior to their attack. In Novice - Good games |
only commanders move. In Expert games, all enemy vessels move if there |
is a commander present. In Emeritus games all enemy vessels move. |
* If Enterprise is not docked, an agressive action is taken if enemy |
forces are 1000 greater than Enterprise. |
Agressive action on average cuts the distance between the ship and |
the enemy to 1/4 the original. |
* At lower energy advantage, movement units are proportional to the |
advantage with a 650 advantage being to hold ground, 800 to move forward |
1, 950 for two, 150 for back 4, etc. Variance of 100. |
If docked, is reduced by roughly 1.75*skill, generally forcing a |
retreat, especially at high skill levels. |
* Motion is limited to skill level, except for SC hi-tailing it out. |
*/ |
forces = kpower[loccom]+100.0*nenhere+400*(nbaddys-1); |
if (shldup==0) forces += 1000; /* Good for enemy if shield is down! */ |
if (damage[DPHASER] == 0.0 || damage[DPHOTON] == 0.0) { |
if (damage[DPHASER] != 0) /* phasers damaged */ |
forces += 300.0; |
else |
forces -= 0.2*(energy - 2500.0); |
if (damage[DPHOTON] != 0) /* photon torpedoes damaged */ |
forces += 300.0; |
else |
forces -= 50.0*torps; |
} |
else { |
/* phasers and photon tubes both out! */ |
forces += 1000.0; |
} |
motion = 0; |
if (forces <= 1000.0 && condit != IHDOCKED) /* Typical situation */ |
motion = ((forces+200.0*Rand())/150.0) - 5.0; |
else { |
if (forces > 1000.0) /* Very strong -- move in for kill */ |
motion = (1.0-square(Rand()))*dist1 + 1.0; |
if (condit==IHDOCKED) /* protected by base -- back off ! */ |
motion -= skill*(2.0-square(Rand())); |
} |
#ifdef DEBUG |
if (idebug) { |
proutn("MOTION = "); |
cramf(motion, 1, 2); |
proutn(" FORCES = "); |
cramf(forces, 1, 2); |
skip(1); |
} |
#endif |
/* don't move if no motion */ |
if (motion==0) return; |
/* Limit motion according to skill */ |
if (abs(motion) > skill) motion = (motion < 0) ? -skill : skill; |
} |
/* calcuate preferred number of steps */ |
nsteps = motion < 0 ? -motion : motion; |
if (motion > 0 && nsteps > mdist) nsteps = mdist; /* don't overshoot */ |
if (nsteps > 10) nsteps = 10; /* This shouldn't be necessary */ |
if (nsteps < 1) nsteps = 1; /* This shouldn't be necessary */ |
#ifdef DEBUG |
if (idebug) { |
proutn("NSTEPS = "); |
crami(nsteps, 1); |
skip(1); |
} |
#endif |
/* Compute preferred values of delta X and Y */ |
mx = sectx - comx; |
my = secty - comy; |
if (2.0 * abs(mx) < abs(my)) mx = 0; |
if (2.0 * abs(my) < abs(sectx-comx)) my = 0; |
if (mx != 0) mx = mx*motion < 0 ? -1 : 1; |
if (my != 0) my = my*motion < 0 ? -1 : 1; |
nextx = comx; |
nexty = comy; |
quad[comx][comy] = IHDOT; |
/* main move loop */ |
for (ll = 1; ll <= nsteps; ll++) { |
#ifdef DEBUG |
if (idebug) { |
crami(ll,2); |
skip(1); |
} |
#endif |
/* Check if preferred position available */ |
lookx = nextx + mx; |
looky = nexty + my; |
krawlx = mx < 0 ? 1 : -1; |
krawly = my < 0 ? 1 : -1; |
success = 0; |
attempts = 0; /* Settle mysterious hang problem */ |
while (attempts++ < 20 && !success) { |
if (lookx < 1 || lookx > 10) { |
if (motion < 0 && tryexit(lookx, looky, ienm, loccom, irun)) |
return; |
if (krawlx == mx || my == 0) break; |
lookx = nextx + krawlx; |
krawlx = -krawlx; |
} |
else if (looky < 1 || looky > 10) { |
if (motion < 0 && tryexit(lookx, looky, ienm, loccom, irun)) |
return; |
if (krawly == my || mx == 0) break; |
looky = nexty + krawly; |
krawly = -krawly; |
} |
else if (quad[lookx][looky] != IHDOT) { |
/* See if we should ram ship */ |
if (quad[lookx][looky] == ship && |
(ienm == IHC || ienm == IHS)) { |
ram(1, ienm, comx, comy); |
return; |
} |
if (krawlx != mx && my != 0) { |
lookx = nextx + krawlx; |
krawlx = -krawlx; |
} |
else if (krawly != my && mx != 0) { |
looky = nexty + krawly; |
krawly = -krawly; |
} |
else break; /* we have failed */ |
} |
else success = 1; |
} |
if (success) { |
nextx = lookx; |
nexty = looky; |
#ifdef DEBUG |
if (idebug) { |
cramlc(0, nextx, nexty); |
skip(1); |
} |
#endif |
} |
else break; /* done early */ |
} |
/* Put commander in place within same quadrant */ |
quad[nextx][nexty] = ienm; |
if (nextx != comx || nexty != comy) { |
/* it moved */ |
kx[loccom] = nextx; |
ky[loccom] = nexty; |
kdist[loccom] = kavgd[loccom] = |
sqrt(square(sectx-nextx)+square(secty-nexty)); |
if (damage[DSRSENS] == 0 || condit == IHDOCKED) { |
proutn("***"); |
cramen(ienm); |
if (kdist[loccom] < dist1) proutn(" advances to"); |
else proutn(" retreats to"); |
cramlc(2, nextx, nexty); |
skip(1); |
} |
} |
} |
void movcom(void) { |
int ix, iy, i; |
#ifdef DEBUG |
if (idebug) prout("MOVCOM"); |
#endif |
/* Figure out which Klingon is the commander (or Supercommander) |
and do move */ |
if (comhere) for (i = 1; i <= nenhere; i++) { |
ix = kx[i]; |
iy = ky[i]; |
if (quad[ix][iy] == IHC) { |
movebaddy(ix, iy, i, IHC); |
break; |
} |
} |
if (ishere) for (i = 1; i <= nenhere; i++) { |
ix = kx[i]; |
iy = ky[i]; |
if (quad[ix][iy] == IHS) { |
movebaddy(ix, iy, i, IHS); |
break; |
} |
} |
/* if skill level is high, move other Klingons and Romulans too! |
Move these last so they can base their actions on what the |
commander(s) do. */ |
if (skill > SGOOD) for (i = 1; i <= nenhere; i++) { |
ix = kx[i]; |
iy = ky[i]; |
if (quad[ix][iy] == IHK || quad[ix][iy] == IHR) |
movebaddy(ix, iy, i, quad[ix][iy]); |
} |
sortkl(); |
} |
static int checkdest(int iqx, int iqy, int flag, int *ipage) { |
int i, j; |
if ((iqx==quadx && iqy==quady) || |
iqx < 1 || iqx > 8 || iqy < 1 || iqy > 8 || |
d.galaxy[iqx][iqy] > 899) return 1; |
if (flag) { |
/* Avoid quadrants with bases if we want to avoid Enterprise */ |
for (i = 1; i <= d.rembase; i++) |
if (d.baseqx[i]==iqx && d.baseqy[i]==iqy) return 1; |
} |
/* do the move */ |
d.galaxy[d.isx][d.isy] -= 100; |
d.isx = iqx; |
d.isy = iqy; |
d.galaxy[d.isx][d.isy] += 100; |
if (iscate) { |
/* SC has scooted, Remove him from current quadrant */ |
iscate=0; |
isatb=0; |
ishere=0; |
ientesc=0; |
future[FSCDBAS]=1e30; |
for (i = 1; i <= nenhere; i++) |
if (quad[kx[i]][ky[i]] == IHS) break; |
quad[kx[i]][ky[i]] = IHDOT; |
kx[i] = kx[nenhere]; |
ky[i] = ky[nenhere]; |
kdist[i] = kdist[nenhere]; |
kavgd[i] = kavgd[nenhere]; |
kpower[i] = kpower[nenhere]; |
klhere--; |
nenhere--; |
if (condit!=IHDOCKED) newcnd(); |
sortkl(); |
} |
/* check for a helpful planet */ |
for (i = 1; i <= inplan; i++) { |
if (d.plnets[i].x==d.isx && d.plnets[i].y==d.isy && |
d.plnets[i].crystals == 1) { |
/* destroy the planet */ |
d.plnets[i] = nulplanet; |
d.newstuf[d.isx][d.isy] -= 1; |
if (REPORTS) { |
if (*ipage==0) pause(1); |
*ipage = 1; |
prout("Lt. Uhura- \"Captain, Starfleet Intelligence reports"); |
proutn(" a planet in"); |
cramlc(1, d.isx, d.isy); |
prout(" has been destroyed"); |
prout(" by the Super-commander.\""); |
} |
break; |
} |
} |
return 0; /* looks good! */ |
} |
void scom(int *ipage) { |
int i, i2, j, ideltax, ideltay, ibqx, ibqy, sx, sy, ifindit, iwhichb; |
int iqx, iqy; |
int basetbl[6]; |
double bdist[6]; |
int flag; |
#ifdef DEBUG |
if (idebug) prout("SCOM"); |
#endif |
/* Decide on being active or passive */ |
flag = ((d.killc+d.killk)/(d.date+0.01-indate) < 0.1*skill*(skill+1.0) || |
(d.date-indate) < 3.0); |
if (iscate==0 && flag) { |
/* compute move away from Enterprise */ |
ideltax = d.isx-quadx; |
ideltay = d.isy-quady; |
if (sqrt(ideltax*(double)ideltax+ideltay*(double)ideltay) > 2.0) { |
/* circulate in space */ |
ideltax = d.isy-quady; |
ideltay = quadx-d.isx; |
} |
} |
else { |
/* compute distances to starbases */ |
if (d.rembase <= 0) { |
/* nothing left to do */ |
future[FSCMOVE] = 1e30; |
return; |
} |
sx = d.isx; |
sy = d.isy; |
for (i = 1; i <= d.rembase; i++) { |
basetbl[i] = i; |
ibqx = d.baseqx[i]; |
ibqy = d.baseqy[i]; |
bdist[i] = sqrt(square(ibqx-sx) + square(ibqy-sy)); |
} |
if (d.rembase > 1) { |
/* sort into nearest first order */ |
int iswitch; |
do { |
iswitch = 0; |
for (i=1; i < d.rembase-1; i++) { |
if (bdist[i] > bdist[i+1]) { |
int ti = basetbl[i]; |
double t = bdist[i]; |
bdist[i] = bdist[i+1]; |
bdist[i+1] = t; |
basetbl[i] = basetbl[i+1]; |
basetbl[i+1] =ti; |
iswitch = 1; |
} |
} |
} while (iswitch); |
} |
/* look for nearest base without a commander, no Enterprise, and |
without too many Klingons, and not already under attack. */ |
ifindit = iwhichb = 0; |
for (i2 = 1; i2 <= d.rembase; i2++) { |
i = basetbl[i2]; /* bug in original had it not finding nearest*/ |
ibqx = d.baseqx[i]; |
ibqy = d.baseqy[i]; |
if ((ibqx == quadx && ibqy == quady) || |
(ibqx == batx && ibqy == baty) || |
d.galaxy[ibqx][ibqy] > 899) continue; |
/* if there is a commander, an no other base is appropriate, |
we will take the one with the commander */ |
for (j = 1; j <= d.remcom; j++) { |
if (ibqx==d.cx[j] && ibqy==d.cy[j] && ifindit!= 2) { |
ifindit = 2; |
iwhichb = i; |
break; |
} |
} |
if (j > d.remcom) { /* no commander -- use this one */ |
ifindit = 1; |
iwhichb = i; |
break; |
} |
} |
if (ifindit==0) return; /* Nothing suitable -- wait until next time*/ |
ibqx = d.baseqx[iwhichb]; |
ibqy = d.baseqy[iwhichb]; |
/* decide how to move toward base */ |
ideltax = ibqx - d.isx; |
ideltay = ibqy - d.isy; |
} |
/* Maximum movement is 1 quadrant in either or both axis */ |
if (ideltax > 1) ideltax = 1; |
if (ideltax < -1) ideltax = -1; |
if (ideltay > 1) ideltay = 1; |
if (ideltay < -1) ideltay = -1; |
/* try moving in both x and y directions */ |
iqx = d.isx + ideltax; |
iqy = d.isy + ideltax; |
if (checkdest(iqx, iqy, flag, ipage)) { |
/* failed -- try some other maneuvers */ |
if (ideltax==0 || ideltay==0) { |
/* attempt angle move */ |
if (ideltax != 0) { |
iqy = d.isy + 1; |
if (checkdest(iqx, iqy, flag, ipage)) { |
iqy = d.isy - 1; |
checkdest(iqx, iqy, flag, ipage); |
} |
} |
else { |
iqx = d.isx + 1; |
if (checkdest(iqx, iqy, flag, ipage)) { |
iqx = d.isx - 1; |
checkdest(iqx, iqy, flag, ipage); |
} |
} |
} |
else { |
/* try moving just in x or y */ |
iqy = d.isy; |
if (checkdest(iqx, iqy, flag, ipage)) { |
iqy = d.isy + ideltay; |
iqx = d.isx; |
checkdest(iqx, iqy, flag, ipage); |
} |
} |
} |
/* check for a base */ |
if (d.rembase == 0) { |
future[FSCMOVE] = 1e30; |
} |
else for (i=1; i<=d.rembase; i++) { |
ibqx = d.baseqx[i]; |
ibqy = d.baseqy[i]; |
if (ibqx==d.isx && ibqy == d.isy && d.isx != batx && d.isy != baty) { |
/* attack the base */ |
if (flag) return; /* no, don't attack base! */ |
iseenit = 0; |
isatb=1; |
future[FSCDBAS] = d.date + 1.0 +2.0*Rand(); |
if (batx != 0) future[FSCDBAS] += future[FCDBAS]-d.date; |
if (!REPORTS) |
return; /* no warning */ |
iseenit = 1; |
if (*ipage == 0) pause(1); |
*ipage=1; |
proutn("Lt. Uhura- \"Captain, the starbase in"); |
cramlc(1, d.isx, d.isy); |
skip(1); |
prout(" reports that it is under attack from the Klingon Super-commander."); |
proutn(" It can survive until stardate "); |
cramf(future[FSCDBAS], 0, 1); |
prout(" .\""); |
if (resting==0) return; |
prout("Mr. Spock- \"Captain, shall we cancel the rest period?\""); |
if (ja()==0) return; |
resting = 0; |
Time = 0.0; /* actually finished */ |
return; |
} |
} |
/* Check for intelligence report */ |
if ( |
#ifdef DEBUG |
idebug==0 && |
#endif |
(Rand() > 0.2 || |
(!REPORTS) || |
starch[d.isx][d.isy] > 0)) |
return; |
if (*ipage==0) pause(1); |
*ipage = 1; |
prout("Lt. Uhura- \"Captain, Starfleet Intelligence reports"); |
proutn(" the Super-commander is in"); |
cramlc(1, d.isx, d.isy); |
prout(".\""); |
return; |
} |
void movetho(void) { |
int idx, idy, im, i, dum, my; |
/* Move the Tholean */ |
if (ithere==0 || justin == 1) return; |
if (ithx == 1 && ithy == 1) { |
idx = 1; idy = 10; |
} |
else if (ithx == 1 && ithy == 10) { |
idx = 10; idy = 10; |
} |
else if (ithx == 10 && ithy == 10) { |
idx = 10; idy = 1; |
} |
else if (ithx == 10 && ithy == 1) { |
idx = 1; idy = 1; |
} |
else { |
/* something is wrong! */ |
ithere = 0; |
return; |
} |
/* Do nothing if we are blocked */ |
if (quad[idx][idy]!= IHDOT && quad[idx][idy]!= IHWEB) return; |
quad[ithx][ithy] = IHWEB; |
if (ithx != idx) { |
/* move in x axis */ |
im = fabs((double)idx - ithx)/((double)idx - ithx); |
while (ithx != idx) { |
ithx += im; |
if (quad[ithx][ithy]==IHDOT) quad[ithx][ithy] = IHWEB; |
} |
} |
else if (ithy != idy) { |
/* move in y axis */ |
im = fabs((double)idy - ithy)/((double)idy - ithy); |
while (ithy != idy) { |
ithy += im; |
if (quad[ithx][ithy]==IHDOT) quad[ithx][ithy] = IHWEB; |
} |
} |
quad[ithx][ithy] = IHT; |
/* check to see if all holes plugged */ |
for (i = 1; i < 11; i++) { |
if (quad[1][i]!=IHWEB && quad[1][i]!=IHT) return; |
if (quad[10][i]!=IHWEB && quad[10][i]!=IHT) return; |
if (quad[i][1]!=IHWEB && quad[i][1]!=IHT) return; |
if (quad[i][10]!=IHWEB && quad[i][10]!=IHT) return; |
} |
/* All plugged up -- Tholian splits */ |
quad[ithx][ithy]=IHWEB; |
dropin(IHBLANK, &dum, &my); |
crmena(1,IHT, 2, ithx, ithy); |
prout(" completes web."); |
ithere = ithx = ithy = 0; |
return; |
} |
/programs/games/sstartrek/en/battle.c |
---|
0,0 → 1,1483 |
#include "sst.h" |
#ifdef CLOAKING |
void cloak(void) { |
int key; |
enum {NONE, CLON, CLOFF} action = NONE; |
if (ship == IHF) { |
prout("Ye Faerie Queene has no cloaking device."); |
return; |
} |
key = scan(); |
if (key == IHREAL) return; |
if (key == IHALPHA) { |
if (isit("on")) { |
if (iscloaked) { |
prout("The cloaking device has already been switched on."); |
return; |
} |
action = CLON; |
} |
else if (isit("off")) { |
if (!iscloaked) { |
prout("The cloaking device has already been switched off."); |
return; |
} |
action = CLOFF; |
} |
else { |
huh(); |
return; |
} |
} else { |
if (!iscloaked) { |
proutn("Switch cloaking device on?"); |
if (ja()==0) return; |
action = CLON; |
} |
if (iscloaked) { |
proutn("Switch cloaking device off?"); |
if (ja()==0) return; |
action = CLOFF; |
} |
if (action == NONE) return; |
} |
if (action==CLOFF) { |
if (irhere && d.date >= ALGERON && !isviolreported) { |
prout("Spock- \"Captain, the Treaty of Algeron is in effect.\n Are you sure this is wise?\""); |
if (ja() == 0) return; |
} |
prout("Engineer Scott- \"Aye, Sir.\""); |
iscloaked = FALSE; |
if (irhere && d.date >= ALGERON && !isviolreported) { |
prout("The Romulan ship discovers you are breaking the Treaty of Algeron!"); |
ncviol++; |
isviolreported = TRUE; |
} |
// if (neutz && d.date >= ALGERON) finish(FCLOAK); |
return; |
} |
if (damage[DCLOAK]!=0) { |
prout("Engineer Scott- \"The cloaking device is damaged, Sir.\""); |
return; |
} |
if (condit==IHDOCKED) { |
prout("You cannot cloak while docked."); |
return; |
} |
if (d.date >= ALGERON && !isviolreported) |
{ |
prout("Spock- \"Captain, using the cloaking device is be a violation"); |
prout(" of the Treaty of Algeron. Considering the alternatives,"); |
proutn(" are you sure this is wise?"); |
if (ja()==0) return; |
} |
prout("Engineer Scott- \"The cloaking device has been engaged, Sir.\""); |
iscloaking = TRUE; |
if (irhere && d.date >= ALGERON && !isviolreported) { |
prout("The Romulan ship discovers you are breaking the Treaty of Algeron!"); |
ncviol++; |
isviolreported = TRUE; |
} |
} |
#endif |
void sheild(int i) { |
int key; |
enum {NONE, SHUP, SHDN, NRG} action = NONE; |
ididit = 0; |
if (i == 2) action = SHUP; |
else { |
key = scan(); |
if (key == IHALPHA) { |
if (isit("transfer")) |
action = NRG; |
else { |
chew(); |
if (damage[DSHIELD]) { |
prout("Shields damaged and down."); |
return; |
} |
if (isit("up")) |
action = SHUP; |
else if (isit("down")) |
action = SHDN; |
} |
} |
if (action==NONE) { |
proutn("Do you wish to change shield energy? "); |
if (ja()) { |
proutn("Energy to transfer to shields- "); |
action = NRG; |
} |
else if (damage[DSHIELD]) { |
prout("Shields damaged and down."); |
return; |
} |
else if (shldup) { |
proutn("Shields are up. Do you want them down? "); |
if (ja()) action = SHDN; |
else { |
chew(); |
return; |
} |
} |
else { |
proutn("Shields are down. Do you want them up? "); |
if (ja()) action = SHUP; |
else { |
chew(); |
return; |
} |
} |
} |
} |
switch (action) { |
case SHUP: /* raise shields */ |
if (shldup) { |
prout("Shields already up."); |
return; |
} |
shldup = 1; |
shldchg = 1; |
if (condit != IHDOCKED) energy -= 50.0; |
prout("Shields raised."); |
if (energy <= 0) { |
skip(1); |
prout("Shields raising uses up last of energy."); |
finish(FNRG); |
return; |
} |
ididit=1; |
return; |
case SHDN: |
if (shldup==0) { |
prout("Shields already down."); |
return; |
} |
shldup=0; |
shldchg=1; |
prout("Shields lowered."); |
ididit=1; |
return; |
case NRG: |
while (scan() != IHREAL) { |
chew(); |
proutn("Energy to transfer to shields- "); |
} |
chew(); |
if (aaitem==0) return; |
if (aaitem > energy) { |
prout("Insufficient ship energy."); |
return; |
} |
ididit = 1; |
if (shield+aaitem >= inshld) { |
prout("Shield energy maximized."); |
if (shield+aaitem > inshld) { |
prout("Excess energy requested returned to ship energy"); |
} |
energy -= inshld-shield; |
shield = inshld; |
return; |
} |
if (aaitem < 0.0 && energy-aaitem > inenrg) { |
/* Prevent shield drain loophole */ |
skip(1); |
prout("Engineering to bridge--"); |
prout(" Scott here. Power circuit problem, Captain."); |
prout(" I can't drain the shields."); |
ididit = 0; |
return; |
} |
if (shield+aaitem < 0) { |
prout("All shield energy transferred to ship."); |
energy += shield; |
shield = 0.0; |
return; |
} |
proutn("Scotty- \""); |
if (aaitem > 0) |
prout("Transferring energy to shields.\""); |
else |
prout("Draining energy from shields.\""); |
shield += aaitem; |
energy -= aaitem; |
return; |
case NONE: break; |
} |
} |
void ram(int ibumpd, int ienm, int ix, int iy) { |
double type = 1.0, extradm; |
int icas, l; |
prouts("***RED ALERT! RED ALERT!"); |
skip(1); |
prout("***COLLISION IMMINENT."); |
skip(2); |
proutn("***"); |
crmshp(); |
switch (ienm) { |
case IHR: type = 1.5; break; |
case IHC: type = 2.0; break; |
case IHS: type = 2.5; break; |
case IHT: type = 0.5; break; |
} |
proutn(ibumpd ? " rammed by " : " rams "); |
crmena(0, ienm, 2, ix, iy); |
if (ibumpd) proutn(" (original position)"); |
skip(1); |
deadkl(ix, iy, ienm, sectx, secty); |
proutn("***"); |
crmshp(); |
prout(" heavily damaged."); |
icas = 10.0+20.0*Rand(); |
proutn("***Sickbay reports "); |
crami(icas, 1); |
prout(" casualties."); |
casual += icas; |
for (l=1; l <= ndevice; l++) { |
if (l == DDRAY) continue; // Don't damage deathray |
if (damage[l] < 0) continue; |
extradm = (10.0*type*Rand()+1.0)*damfac; |
damage[l] += Time + extradm; /* Damage for at least time of travel! */ |
} |
shldup = 0; |
if (d.remkl) { |
pause(2); |
dreprt(); |
} |
else finish(FWON); |
return; |
} |
void torpedo(double course, double r, int inx, int iny, double *hit) { |
int l, iquad, ix, iy, jx, jy, shoved=0, ll; |
double ac=course + 0.25*r; |
double angle = (15.0-ac)*0.5235988; |
double bullseye = (15.0 - course)*0.5235988; |
double deltax=-sin(angle), deltay=cos(angle), x=inx, y=iny, bigger; |
double ang, temp, xx, yy, kp, h1; |
bigger = fabs(deltax); |
if (fabs(deltay) > bigger) bigger = fabs(deltay); |
deltax /= bigger; |
deltay /= bigger; |
/* Loop to move a single torpedo */ |
for (l=1; l <= 15; l++) { |
x += deltax; |
ix = x + 0.5; |
if (ix < 1 || ix > 10) break; |
y += deltay; |
iy = y + 0.5; |
if (iy < 1 || iy > 10) break; |
if (l==4 || l==9) skip(1); |
cramf(x, 0, 1); |
proutn(" - "); |
cramf(y, 0, 1); |
proutn(" "); |
iquad=quad[ix][iy]; |
if (iquad==IHDOT) continue; |
/* hit something */ |
skip(1); |
switch(iquad) { |
case IHE: /* Hit our ship */ |
case IHF: |
skip(1); |
proutn("Torpedo hits "); |
crmshp(); |
prout("."); |
*hit = 700.0 + 100.0*Rand() - |
1000.0*sqrt(square(ix-inx)+square(iy-iny))* |
fabs(sin(bullseye-angle)); |
*hit = fabs(*hit); |
newcnd(); /* undock */ |
/* We may be displaced. */ |
if (landed==1) return; /* Cheat if on a planet */ |
ang = angle + 2.5*(Rand()-0.5); |
temp = fabs(sin(ang)); |
if (fabs(cos(ang)) > temp) temp = fabs(cos(ang)); |
xx = -sin(ang)/temp; |
yy = cos(ang)/temp; |
jx=ix+xx+0.5; |
jy=iy+yy+0.5; |
if (jx<1 || jx>10 || jy<1 ||jy > 10) return; |
if (quad[jx][jy]==IHBLANK) { |
finish(FHOLE); |
return; |
} |
if (quad[jx][jy]!=IHDOT) { |
/* can't move into object */ |
return; |
} |
sectx = jx; |
secty = jy; |
crmshp(); |
shoved = 1; |
break; |
case IHC: /* Hit a commander */ |
case IHS: |
if (Rand() <= 0.05) { |
crmena(1, iquad, 2, ix, iy); |
prout(" uses anti-photon device;"); |
prout(" torpedo neutralized."); |
return; |
} |
case IHR: /* Hit a regular enemy */ |
case IHK: |
/* find the enemy */ |
for (ll=1; ll <= nenhere; ll++) |
if (ix==kx[ll] && iy==ky[ll]) break; |
kp = fabs(kpower[ll]); |
h1 = 700.0 + 100.0*Rand() - |
1000.0*sqrt(square(ix-inx)+square(iy-iny))* |
fabs(sin(bullseye-angle)); |
h1 = fabs(h1); |
if (kp < h1) h1 = kp; |
kpower[ll] -= (kpower[ll]<0 ? -h1 : h1); |
if (kpower[ll] == 0) { |
deadkl(ix, iy, iquad, ix, iy); |
return; |
} |
crmena(1, iquad, 2, ix, iy); |
/* If enemy damaged but not destroyed, try to displace */ |
ang = angle + 2.5*(Rand()-0.5); |
temp = fabs(sin(ang)); |
if (fabs(cos(ang)) > temp) temp = fabs(cos(ang)); |
xx = -sin(ang)/temp; |
yy = cos(ang)/temp; |
jx=ix+xx+0.5; |
jy=iy+yy+0.5; |
if (jx<1 || jx>10 || jy<1 ||jy > 10) { |
prout(" damaged but not destroyed."); |
return; |
} |
if (quad[jx][jy]==IHBLANK) { |
prout(" buffeted into black hole."); |
deadkl(ix, iy, iquad, jx, jy); |
return; |
} |
if (quad[jx][jy]!=IHDOT) { |
/* can't move into object */ |
prout(" damaged but not destroyed."); |
return; |
} |
prout(" damaged--"); |
kx[ll] = jx; |
ky[ll] = jy; |
shoved = 1; |
break; |
case IHB: /* Hit a base */ |
prout("***STARBASE DESTROYED.."); |
if (starch[quadx][quady] < 0) starch[quadx][quady] = 0; |
for (ll=1; ll<=d.rembase; ll++) { |
if (d.baseqx[ll]==quadx && d.baseqy[ll]==quady) { |
d.baseqx[ll]=d.baseqx[d.rembase]; |
d.baseqy[ll]=d.baseqy[d.rembase]; |
break; |
} |
} |
quad[ix][iy]=IHDOT; |
d.rembase--; |
basex=basey=0; |
d.galaxy[quadx][quady] -= 10; |
d.basekl++; |
newcnd(); |
return; |
case IHP: /* Hit a planet */ |
crmena(1, iquad, 2, ix, iy); |
prout(" destroyed."); |
d.nplankl++; |
d.newstuf[quadx][quady] -= 1; |
d.plnets[iplnet] = nulplanet; |
iplnet = 0; |
plnetx = plnety = 0; |
quad[ix][iy] = IHDOT; |
if (landed==1) { |
/* captain parishes on planet */ |
finish(FDPLANET); |
} |
return; |
case IHSTAR: /* Hit a star */ |
if (Rand() > 0.10) { |
nova(ix, iy); |
return; |
} |
crmena(1, IHSTAR, 2, ix, iy); |
prout(" unaffected by photon blast."); |
return; |
case IHQUEST: /* Hit a thingy */ |
skip(1); |
prouts("AAAAIIIIEEEEEEEEAAAAAAAAUUUUUGGGGGHHHHHHHHHHHH!!!"); |
skip(1); |
prouts(" HACK! HACK! HACK! *CHOKE!* "); |
skip(1); |
proutn("Mr. Spock-"); |
prouts(" \"Facinating!\""); |
skip(1); |
quad[ix][iy] = IHDOT; |
return; |
case IHBLANK: /* Black hole */ |
skip(1); |
crmena(1, IHBLANK, 2, ix, iy); |
prout(" swallows torpedo."); |
return; |
case IHWEB: /* hit the web */ |
skip(1); |
prout("***Torpedo absorbed by Tholian web."); |
return; |
case IHT: /* Hit a Tholian */ |
skip(1); |
crmena(1, IHT, 2, ix, iy); |
h1 = 700.0 + 100.0*Rand() - |
1000.0*sqrt(square(ix-inx)+square(iy-iny))* |
fabs(sin(bullseye-angle)); |
h1 = fabs(h1); |
if (h1 >= 600) { |
prout(" destroyed."); |
quad[ix][iy] = IHDOT; |
ithere = 0; |
ithx = ithy = 0; |
return; |
} |
if (Rand() > 0.05) { |
prout(" survives photon blast."); |
return; |
} |
prout(" disappears."); |
quad[ix][iy] = IHWEB; |
ithere = ithx = ithy = 0; |
{ |
int dum, my; |
dropin(IHBLANK, &dum, &my); |
} |
return; |
default: /* Problem! */ |
skip(1); |
proutn("Don't know how to handle collision with "); |
crmena(1, iquad, 2, ix, iy); |
skip(1); |
return; |
} |
break; |
} |
if (shoved) { |
quad[jx][jy]=iquad; |
quad[ix][iy]=IHDOT; |
proutn(" displaced by blast to"); |
cramlc(2, jx, jy); |
skip(1); |
for (ll=1; ll<=nenhere; ll++) |
kdist[ll] = kavgd[ll] = sqrt(square(sectx-kx[ll])+square(secty-ky[ll])); |
sortkl(); |
return; |
} |
skip(1); |
prout("Torpedo missed."); |
return; |
} |
static void fry(double hit) { |
double ncrit, extradm; |
int ktr=1, l, ll, j, cdam[6], crptr; |
/* a critical hit occured */ |
if (hit < (275.0-25.0*skill)*(1.0+0.5*Rand())) return; |
ncrit = 1.0 + hit/(500.0+100.0*Rand()); |
proutn("***CRITICAL HIT--"); |
/* Select devices and cause damage */ |
for (l = 1; l <= ncrit; l++) { |
do { |
j = ndevice*Rand()+1.0; |
/* Cheat to prevent shuttle damage unless on ship */ |
} while (damage[j] < 0.0 || (j == DSHUTTL && iscraft != 1) || |
#ifdef CLOAKING |
(j == DCLOAK && ship != IHE) || |
#endif |
j == DDRAY); |
cdam[l] = j; |
extradm = (hit*damfac)/(ncrit*(75.0+25.0*Rand())); |
damage[j] += extradm; |
if (l > 1) { |
for (ll=2; ll<=l && j != cdam[ll-1]; ll++) ; |
if (ll<=l) continue; |
ktr += 1; |
if (ktr==3) skip(1); |
proutn(" and "); |
} |
proutn(device[j]); |
} |
prout(" damaged."); |
if (damage[DSHIELD] && shldup) { |
prout("***Shields knocked down."); |
shldup=0; |
} |
#ifdef CLOAKING |
if (damage[DCLOAK] && iscloaked) |
{ |
prout("***Cloaking device rendered inoperative."); |
iscloaked = FALSE; |
} |
#endif |
} |
void attack(int k) { |
/* k == 0 forces use of phasers in an attack */ |
int percent, ihurt=0, l, i=0, jx, jy, iquad, itflag; |
int atackd = 0, attempt = 0; |
double hit; |
double pfac, dustfac, hitmax=0.0, hittot=0.0, chgfac=1.0, r; |
#ifdef CLOAKING |
if (iscloaked && !iscloaking) return; // Nothing happens if we are cloaked |
#endif |
iattak = 1; |
if (alldone) return; |
#ifdef DEBUG |
if (idebug) prout("ATTACK!"); |
#endif |
if (ithere) movetho(); |
if (neutz) { /* The one chance not to be attacked */ |
neutz = 0; |
return; |
} |
if (((comhere || ishere) && (justin == 0)) || skill == SEMERITUS) movcom(); |
if (nenhere==0) return; |
pfac = 1.0/inshld; |
if (shldchg == 1) chgfac = 0.25+0.5*Rand(); |
skip(1); |
if (skill <= SFAIR) i = 2; |
for (l=1; l <= nenhere; l++) { |
if (kpower[l] < 0) continue; /* too weak to attack */ |
/* compute hit strength and diminsh shield power */ |
r = Rand(); |
/* Increase chance of photon torpedos if docked or enemy energy low */ |
if (condit == IHDOCKED) r *= 0.25; |
if (kpower[l] < 500) r *= 0.25; |
jx = kx[l]; |
jy = ky[l]; |
iquad = quad[jx][jy]; |
itflag = (iquad == IHK && r > 0.0005) || k == 0 || |
(iquad==IHC && r > 0.015) || |
(iquad==IHR && r > 0.3) || |
(iquad==IHS && r > 0.07); |
if (itflag) { |
/* Enemy uses phasers */ |
if (condit == IHDOCKED) continue; /* Don't waste the effort! */ |
attempt = 1; /* Attempt to attack */ |
dustfac = 0.8+0.05*Rand(); |
hit = kpower[l]*pow(dustfac,kavgd[l]); |
kpower[l] *= 0.75; |
} |
else { /* Enemy used photon torpedo */ |
double course = 1.90985*atan2((double)secty-jy, (double)jx-sectx); |
hit = 0; |
proutn("***TORPEDO INCOMING"); |
if (damage[DSRSENS] <= 0.0) { |
proutn(" From "); |
crmena(0, iquad, i, jx, jy); |
} |
attempt = 1; |
prout("--"); |
r = (Rand()+Rand())*0.5 -0.5; |
r += 0.002*kpower[l]*r; |
torpedo(course, r, jx, jy, &hit); |
if (d.remkl==0) finish(FWON); /* Klingons did themselves in! */ |
if (d.galaxy[quadx][quady] == 1000 || |
alldone) return; /* Supernova or finished */ |
if (hit == 0) continue; |
} |
if (shldup != 0 || shldchg != 0) { |
/* shields will take hits */ |
double absorb, hitsh, propor = pfac*shield; |
if(propor < 0.1) propor = 0.1; |
hitsh = propor*chgfac*hit+1.0; |
atackd=1; |
absorb = 0.8*hitsh; |
if (absorb > shield) absorb = shield; |
shield -= absorb; |
hit -= hitsh; |
if (propor > 0.1 && hit < 0.005*energy) continue; |
} |
/* It's a hit -- print out hit size */ |
atackd = 1; /* We weren't going to check casualties, etc. if |
shields were down for some strange reason. This |
doesn't make any sense, so I've fixed it */ |
ihurt = 1; |
cramf(hit, 0, 2); |
proutn(" unit hit"); |
if ((damage[DSRSENS] > 0 && itflag) || skill <= SFAIR) { |
proutn(" on the "); |
crmshp(); |
} |
if (damage[DSRSENS] <= 0.0 && itflag) { |
proutn(" from "); |
crmena(0, iquad, i, jx, jy); |
} |
skip(1); |
/* Decide if hit is critical */ |
if (hit > hitmax) hitmax = hit; |
hittot += hit; |
fry(hit); |
printf("Hit %g energy %g\n", hit, energy); |
energy -= hit; |
} |
if (energy <= 0) { |
/* Returning home upon your shield, not with it... */ |
finish(FBATTLE); |
return; |
} |
if (attempt == 0 && condit == IHDOCKED) |
prout("***Enemies decide against attacking your ship."); |
if (atackd == 0) return; |
percent = 100.0*pfac*shield+0.5; |
if (ihurt==0) { |
/* Shields fully protect ship */ |
proutn("Enemy attack reduces shield strength to "); |
} |
else { |
/* Print message if starship suffered hit(s) */ |
skip(1); |
proutn("Energy left "); |
cramf(energy, 0, 2); |
proutn(" shields "); |
if (shldup) proutn("up, "); |
else if (damage[DSHIELD] == 0) proutn("down, "); |
else proutn("damaged, "); |
} |
crami(percent, 1); |
proutn("% torpedoes left "); |
crami(torps, 1); |
skip(1); |
/* Check if anyone was hurt */ |
if (hitmax >= 200 || hittot >= 500) { |
int icas= hittot*Rand()*0.015; |
if (icas >= 2) { |
skip(1); |
proutn("Mc Coy- \"Sickbay to bridge. We suffered "); |
crami(icas, 1); |
prout(" casualties"); |
prout(" in that last attack.\""); |
casual += icas; |
} |
} |
/* After attack, reset average distance to enemies */ |
for (l = 1; l <= nenhere; l++) |
kavgd[l] = kdist[l]; |
sortkl(); |
return; |
} |
void deadkl(int ix, int iy, int type, int ixx, int iyy) { |
/* Added ixx and iyy allow enemy to "move" before dying */ |
int i,j; |
crmena(1, type, 2, ixx, iyy); |
/* Decide what kind of enemy it is and update approriately */ |
if (type == IHR) { |
/* chalk up a Romulan */ |
d.newstuf[quadx][quady] -= 10; |
irhere--; |
d.nromkl++; |
d.nromrem--; |
} |
else if (type == IHT) { |
/* Killed a Tholean */ |
ithere = 0; |
} |
else { |
/* Some type of a Klingon */ |
d.galaxy[quadx][quady] -= 100; |
klhere--; |
d.remkl--; |
switch (type) { |
case IHC: |
comhere = 0; |
for (i=1; i<=d.remcom; i++) |
if (d.cx[i]==quadx && d.cy[i]==quady) break; |
d.cx[i] = d.cx[d.remcom]; |
d.cy[i] = d.cy[d.remcom]; |
d.cx[d.remcom] = 0; |
d.cy[d.remcom] = 0; |
d.remcom--; |
future[FTBEAM] = 1e30; |
if (d.remcom != 0) |
future[FTBEAM] = d.date + expran(1.0*incom/d.remcom); |
d.killc++; |
break; |
case IHK: |
d.killk++; |
break; |
case IHS: |
d.nscrem = ishere = d.isx = d.isy = isatb = iscate = 0; |
d.nsckill = 1; |
future[FSCMOVE] = future[FSCDBAS] = 1e30; |
break; |
} |
} |
/* For each kind of enemy, finish message to player */ |
prout(" destroyed."); |
quad[ix][iy] = IHDOT; |
if (d.remkl==0) return; |
d.remtime = d.remres/(d.remkl + 4*d.remcom); |
if (type == IHT) return; |
/* Remove enemy ship from arrays describing local conditions */ |
for (i=1; i<=nenhere; i++) |
if (kx[i]==ix && ky[i]==iy) break; |
nenhere--; |
if (i <= nenhere) { |
for (j=i; j<=nenhere; j++) { |
kx[j] = kx[j+1]; |
ky[j] = ky[j+1]; |
kpower[j] = kpower[j+1]; |
kavgd[j] = kdist[j] = kdist[j+1]; |
} |
} |
kx[nenhere+1] = 0; |
ky[nenhere+1] = 0; |
kdist[nenhere+1] = 0; |
kavgd[nenhere+1] = 0; |
kpower[nenhere+1] = 0; |
return; |
} |
static int targetcheck(double x, double y, double *course) { |
double deltx, delty; |
/* Return TRUE if target is invalid */ |
if (x < 1.0 || x > 10.0 || y < 1.0 || y > 10.0) { |
huh(); |
return 1; |
} |
deltx = 0.1*(y - secty); |
delty = 0.1*(sectx - x); |
if (deltx==0 && delty== 0) { |
skip(1); |
prout("Spock- \"Bridge to sickbay. Dr. McCoy,"); |
prout(" I recommend an immediate review of"); |
prout(" the Captain's psychological profile."); |
chew(); |
return 1; |
} |
*course = 1.90985932*atan2(deltx, delty); |
return 0; |
} |
void photon(void) { |
double targ[4][3], course[4]; |
double r, dummy; |
int key, n, i, osuabor; |
ididit = 0; |
if (damage[DPHOTON]) { |
prout("Photon tubes damaged."); |
chew(); |
return; |
} |
if (torps == 0) { |
prout("No torpedoes left."); |
chew(); |
return; |
} |
key = scan(); |
for (;;) { |
if (key == IHALPHA) { |
huh(); |
return; |
} |
else if (key == IHEOL) { |
crami(torps,1); |
prout(" torpedoes left."); |
proutn("Number of torpedoes to fire- "); |
key = scan(); |
} |
else /* key == IHREAL */ { |
n = aaitem + 0.5; |
if (n <= 0) { /* abort command */ |
chew(); |
return; |
} |
if (n > 3) { |
prout("Maximum of 3 torpedoes per burst."); |
} else if (n <= torps) break; |
chew(); |
key = IHEOL; |
} |
} |
for (i = 1; i <= n; i++) { |
key = scan(); |
if (i==1 && key == IHEOL) { |
break; /* we will try prompting */ |
} |
if (i==2 && key == IHEOL) { |
/* direct all torpedoes at one target */ |
while (i <= n) { |
targ[i][1] = targ[1][1]; |
targ[i][2] = targ[1][2]; |
course[i] = course[1]; |
i++; |
} |
break; |
} |
if (key != IHREAL) { |
huh(); |
return; |
} |
targ[i][1] = aaitem; |
key = scan(); |
if (key != IHREAL) { |
huh(); |
return; |
} |
targ[i][2] = aaitem; |
if (targetcheck(targ[i][1], targ[i][2], &course[i])) return; |
} |
chew(); |
if (i == 1 && key == IHEOL) { |
/* prompt for each one */ |
for (i = 1; i <= n; i++) { |
proutn("Target sector for torpedo number"); |
crami(i, 2); |
proutn("- "); |
key = scan(); |
if (key != IHREAL) { |
huh(); |
return; |
} |
targ[i][1] = aaitem; |
key = scan(); |
if (key != IHREAL) { |
huh(); |
return; |
} |
targ[i][2] = aaitem; |
chew(); |
if (targetcheck(targ[i][1], targ[i][2], &course[i])) return; |
} |
} |
ididit = 1; |
/* Loop for moving <n> torpedoes */ |
osuabor = 0; |
for (i = 1; i <= n && !osuabor; i++) { |
if (condit != IHDOCKED) torps--; |
r = (Rand()+Rand())*0.5 -0.5; |
if (fabs(r) >= 0.47) { |
/* misfire! */ |
r = (Rand()+1.2) * r; |
if (n>1) { |
prouts("***TORPEDO NUMBER"); |
crami(i, 2); |
prouts(" MISFIRES."); |
} |
else prouts("***TORPEDO MISFIRES."); |
skip(1); |
if (i < n) |
prout(" Remainder of burst aborted."); |
osuabor=1; |
if (Rand() <= 0.2) { |
prout("***Photon tubes damaged by misfire."); |
damage[DPHOTON] = damfac*(1.0+2.0*Rand()); |
break; |
} |
} |
#ifdef CLOAKING |
if (iscloaked) r *= 1.2; /* Torpedoes are less accurate */ |
else |
#endif |
if (shldup != 0 || condit == IHDOCKED) r *= 1.0 + 0.0001*shield; /* Torpedos are less accurate */ |
if (n != 1) { |
skip(1); |
proutn("Track for torpedo number"); |
crami(i, 2); |
proutn("- "); |
} |
else { |
skip(1); |
proutn("Torpedo track- "); |
} |
torpedo(course[i], r, sectx, secty, &dummy); |
if (alldone || d.galaxy[quadx][quady]==1000) return; |
} |
if (d.remkl==0) finish(FWON); |
} |
static void overheat(double rpow) { |
if (rpow > 1500) { |
double chekbrn = (rpow-1500.)*0.00038; |
if (Rand() <= chekbrn) { |
prout("Weapons officer Sulu- \"Phasers overheated, sir.\""); |
damage[DPHASER] = damfac*(1.0 + Rand()) * (1.0+chekbrn); |
} |
} |
} |
static int checkshctrl(double rpow) { |
double hit; |
int icas; |
skip(1); |
if (Rand() < .998) { |
prout("Shields lowered."); |
return 0; |
} |
/* Something bad has happened */ |
prouts("***RED ALERT! RED ALERT!"); |
skip(2); |
hit = rpow*shield/inshld; |
energy -= rpow+hit*0.8; |
shield -= hit*0.2; |
if (energy <= 0.0) { |
prouts("Sulu- \"Captain! Shield malf***********************\""); |
skip(1); |
stars(); |
finish(FPHASER); |
return 1; |
} |
prouts("Sulu- \"Captain! Shield malfunction! Phaser fire contained!\""); |
skip(2); |
prout("Lt. Uhura- \"Sir, all decks reporting damage.\""); |
icas = hit*Rand()*0.012; |
skip(1); |
fry(0.8*hit); |
if (icas) { |
skip(1); |
prout("McCoy to bridge- \"Severe radiation burns, Jim."); |
proutn(" "); |
crami(icas, 1); |
prout(" casualties so far.\""); |
casual += icas; // Changed from -=, October 2013 |
} |
skip(1); |
prout("Phaser energy dispersed by shields."); |
prout("Enemy unaffected."); |
overheat(rpow); |
return 1; |
} |
void phasers(void) { |
double hits[21], rpow, extra, powrem, over, temp; |
int kz = 0, k=1, i; /* Cheating inhibitor */ |
int ifast=0, no=0, ipoop=1, msgflag = 1; |
enum {NOTSET, MANUAL, FORCEMAN, AUTOMATIC} automode = NOTSET; |
int key; |
skip(1); |
/* SR sensors and Computer */ |
if (damage[DSRSENS]+damage[DCOMPTR] > 0) ipoop = 0; |
if (condit == IHDOCKED) { |
prout("Phasers can't be fired through base shields."); |
chew(); |
return; |
} |
if (damage[DPHASER] != 0) { |
prout("Phaser control damaged."); |
chew(); |
return; |
} |
if (shldup) { |
if (damage[DSHCTRL]) { |
prout("High speed shield control damaged."); |
chew(); |
return; |
} |
if (energy <= 200.0) { |
prout("Insufficient energy to activate high-speed shield control."); |
chew(); |
return; |
} |
prout("Weapons Officer Sulu- \"High-speed shield control enabled, sir.\""); |
ifast = 1; |
} |
ididit = 1; |
/* Original code so convoluted, I re-did it all */ |
while (automode==NOTSET) { |
key=scan(); |
if (key == IHALPHA) { |
if (isit("manual")) { |
if (nenhere==0) { |
prout("There is no enemy present to select."); |
chew(); |
key = IHEOL; |
automode=AUTOMATIC; |
} |
else { |
automode = MANUAL; |
key = scan(); |
} |
} |
else if (isit("automatic")) { |
if ((!ipoop) && nenhere != 0) { |
automode = FORCEMAN; |
} |
else { |
if (nenhere==0) |
prout("Energy will be expended into space."); |
automode = AUTOMATIC; |
key = scan(); |
} |
} |
else if (isit("no")) { |
no = 1; |
} |
else { |
huh(); |
ididit = 0; |
return; |
} |
} |
else if (key == IHREAL) { |
if (nenhere==0) { |
prout("Energy will be expended into space."); |
automode = AUTOMATIC; |
} |
else if (!ipoop) |
automode = FORCEMAN; |
else |
automode = AUTOMATIC; |
} |
else { |
/* IHEOL */ |
if (nenhere==0) { |
prout("Energy will be expended into space."); |
automode = AUTOMATIC; |
} |
else if (!ipoop) |
automode = FORCEMAN; |
else |
proutn("Manual or automatic? "); |
} |
} |
switch (automode) { |
case AUTOMATIC: |
if (key == IHALPHA && isit("no")) { |
no = 1; |
key = scan(); |
} |
if (key != IHREAL && nenhere != 0) { |
proutn("Phasers locked on target. Energy available ="); |
cramf(ifast?energy-200.0:energy,1,2); |
skip(1); |
} |
do { |
while (key != IHREAL) { |
chew(); |
proutn("Units to fire="); |
key = scan(); |
} |
rpow = aaitem; |
if (rpow >= (ifast?energy-200:energy)) { |
proutn("Energy available= "); |
cramf(ifast?energy-200:energy, 1,2); |
skip(1); |
key = IHEOL; |
} |
} while (rpow >= (ifast?energy-200:energy)); |
if (rpow<=0) { |
/* chicken out */ |
ididit = 0; |
chew(); |
return; |
} |
if ((key=scan()) == IHALPHA && isit("no")) { |
no = 1; |
} |
if (ifast) { |
energy -= 200; /* Go and do it! */ |
if (checkshctrl(rpow)) return; |
} |
chew(); |
energy -= rpow; |
extra = rpow; |
if (nenhere) { |
extra = 0.0; |
powrem = rpow; |
for (i = 1; i <= nenhere; i++) { |
hits[i] = 0.0; |
if (powrem <= 0) continue; |
hits[i] = fabs(kpower[i])/(phasefac*pow(0.90,kdist[i])); |
over = (0.01 + 0.05*Rand())*hits[i]; |
temp = powrem; |
powrem -= hits[i] + over; |
if (powrem <= 0 && temp < hits[i]) hits[i] = temp; |
if (powrem <= 0) over = 0.0; |
extra += over; |
} |
if (powrem > 0.0) extra += powrem; |
hittem(hits); |
} |
if (extra > 0 && alldone == 0) { |
if (ithere) { |
proutn("*** Tholian web absorbs "); |
if (nenhere>0) proutn("excess "); |
prout("phaser energy."); |
} |
else { |
cramf(extra, 0, 2); |
prout(" expended on empty space."); |
} |
} |
break; |
case FORCEMAN: |
chew(); |
key = IHEOL; |
if (damage[DCOMPTR]!=0) |
prout("Battle computer damaged, manual file only."); |
else { |
skip(1); |
prouts("---WORKING---"); |
skip(1); |
prout("Short-range-sensors-damaged"); |
prout("Insufficient-data-for-automatic-phaser-fire"); |
prout("Manual-fire-must-be-used"); |
skip(1); |
} |
case MANUAL: |
rpow = 0.0; |
for (k = 1; k <= nenhere;) { |
int ii = kx[k], jj = ky[k]; |
int ienm = quad[ii][jj]; |
if (msgflag) { |
proutn("Energy available= "); |
cramf(energy-.006-(ifast?200:0), 0, 2); |
skip(1); |
msgflag = 0; |
rpow = 0.0; |
} |
if (damage[DSRSENS] && !(abs(sectx-ii) < 2 && abs(secty-jj) < 2) && |
(ienm == IHC || ienm == IHS)) { |
cramen(ienm); |
prout(" can't be located without short range scan."); |
chew(); |
key = IHEOL; |
hits[k] = 0; /* prevent overflow -- thanks to Alexei Voitenko */ |
k++; |
continue; |
} |
if (key == IHEOL) { |
chew(); |
if (ipoop && k > kz) { |
int irec=(fabs(kpower[k])/(phasefac*pow(0.9,kdist[k])))* |
(1.01+0.05*Rand()) + 1.0; |
kz = k; |
proutn("("); |
crami(irec, 1); |
proutn(") "); |
} |
proutn("units to fire at "); |
crmena(0, ienm, 2, ii, jj); |
proutn("- "); |
key = scan(); |
} |
if (key == IHALPHA && isit("no")) { |
no = 1; |
key = scan(); |
continue; |
} |
if (key == IHALPHA) { |
huh(); |
ididit = 0; |
return; |
} |
if (key == IHEOL) { |
if (k==1) { /* Let me say I'm baffled by this */ |
msgflag = 1; |
} |
continue; |
} |
if (aaitem < 0) { |
/* abort out */ |
ididit = 0; |
chew(); |
return; |
} |
hits[k] = aaitem; |
rpow += aaitem; |
/* If total requested is too much, inform and start over */ |
if (rpow >= (ifast?energy-200:energy)) { |
prout("Available energy exceeded -- try again."); |
chew(); |
key = IHEOL; |
k = 1; |
msgflag = 1; |
continue; |
} |
key = scan(); /* scan for next value */ |
k++; |
} |
if (rpow == 0.0) { |
/* zero energy -- abort */ |
ididit = 0; |
chew(); |
return; |
} |
if (key == IHALPHA && isit("no")) { |
no = 1; |
} |
energy -= rpow; |
chew(); |
if (ifast) { |
energy -= 200.0; |
if (checkshctrl(rpow)) return; |
} |
hittem(hits); |
ididit=1; |
break; |
case NOTSET: break; // cannot occur |
} |
/* Say shield raised or malfunction, if necessary */ |
if (alldone) return; |
if (ifast) { |
skip(1); |
if (no == 0) { |
if (Rand() >= 0.99) { |
prout("Sulu- \"Sir, the high-speed shield control has malfunctioned . . ."); |
prouts(" CLICK CLICK POP . . ."); |
prout(" No response, sir!"); |
shldup = 0; |
} |
else |
prout("Shields raised."); |
} |
else |
shldup = 0; |
} |
overheat(rpow); |
} |
void hittem(double *hits) { |
double kp, kpow, wham, hit, dustfac, kpini; |
int nenhr2=nenhere, k=1, kk=1, ii, jj, ienm; |
skip(1); |
for (; k <= nenhr2; k++, kk++) { |
if ((wham = hits[k])==0) continue; |
dustfac = 0.9 + 0.01*Rand(); |
hit = wham*pow(dustfac,kdist[kk]); |
kpini = kpower[kk]; |
kp = fabs(kpini); |
if (phasefac*hit < kp) kp = phasefac*hit; |
kpower[kk] -= (kpower[kk] < 0 ? -kp: kp); |
kpow = kpower[kk]; |
ii = kx[kk]; |
jj = ky[kk]; |
if (hit > 0.005) { |
cramf(hit, 0, 2); |
proutn(" unit hit on "); |
} |
else |
proutn("Very small hit on "); |
ienm = quad[ii][jj]; |
crmena(0,ienm,2,ii,jj); |
skip(1); |
if (kpow == 0) { |
deadkl(ii, jj, ienm, ii, jj); |
if (d.remkl==0) finish(FWON); |
if (alldone) return; |
kk--; /* don't do the increment */ |
} |
else /* decide whether or not to emasculate klingon */ |
if (kpow > 0 && Rand() >= 0.9 && |
kpow <= ((0.4 + 0.4*Rand())*kpini)) { |
proutn("***Mr. Spock- \"Captain, the vessel at"); |
cramlc(2,ii,jj); |
skip(1); |
prout(" has just lost its firepower.\""); |
kpower[kk] = -kpow; |
} |
} |
return; |
} |
#ifdef CAPTURE |
/* $NetBSD: capture.c,v 1.6 2003/08/07 09:37:50 agc Exp $ */ |
/* |
* Copyright (c) 1980, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
*/ |
/* |
** Ask a Klingon To Surrender |
** |
** (Fat chance) |
** |
** The Subspace Radio is needed to ask a Klingon if he will kindly |
** surrender. A random Klingon from the ones in the quadrant is |
** chosen. |
** |
** The Klingon is requested to surrender. The probability of this |
** is a function of that Klingon's remaining power, our power, |
** etc. |
*/ |
int selectklingon(void); |
void |
capture(void) |
{ |
int i; |
int k; |
double x; |
ididit = FALSE; // Nothing if we fail |
Time = 0.0; |
/* Make sure there is room in the brig */ |
if (brigfree == 0) |
{ |
printf("Security reports the brig is already full.\n"); |
return; |
} |
if (!REPORTS) { |
printf("Uhura- \"We have no subspace radio communication, sir.\"\n"); |
return; |
} |
if (damage[DTRANSP] != 0) { |
printf("Scotty- \"Transporter damaged, sir.\"\n"); |
return; |
} |
/* find out if there are any at all */ |
if (klhere < 1) |
{ |
printf("Uhura- \"Getting no response, sir.\"\n"); |
return; |
} |
/* if there is more than one Klingon, find out which one */ |
k = selectklingon(); |
Time = 0.05; // This action will take some time |
ididit = TRUE; // So any others can strike back |
/* check out that Klingon */ |
/* The algorithm isn't that great and could use some more |
* intelligent design */ |
// x = 300 + 25*skill; |
x = energy; |
x /= kpower[k] * nenhere; |
x *= 2.5; /* would originally have been equivalent of 1.4, but we want command to work more often, more humanely */ |
i = x; |
#ifdef DEBUG |
printf("Prob = %d (%.4f)\n", i, x); |
// i = 100; // For testing, of course! |
#endif |
if (i > 100*Rand()) |
{ |
/* guess what, he surrendered!!! */ |
printf("Klingon captain at %d,%d surrenders\n", kx[k], ky[k]); |
i = 200*Rand(); |
if ( i > 0 ) |
printf("%d Klingons commit suicide rather than be taken captive\n", 200 - i); |
if (i > brigfree) |
{ |
printf("%d Klingons die because there is no room for them in the brig.\n", i-brigfree); |
i = brigfree; |
} |
brigfree -= i; |
printf("%d captives taken\n", i); |
deadkl(kx[k], ky[k], quad[kx[k]][ky[k]], kx[k], ky[k]); |
if (d.remkl==0) finish(FWON); |
return; |
} |
/* big surprise, he refuses to surrender */ |
printf("Fat chance, captain\n"); |
return; |
} |
/* |
** SELECT A KLINGON |
** |
** Cruddy, just takes one at random. Should ask the captain. |
** Nah, just select the weakest one since it is most likely to |
** surrender (Tom Almy mod) |
*/ |
int selectklingon() |
{ |
int i; |
if (nenhere < 2) |
i = 1; |
else |
{ // Select the weakest one |
double pow = 1e6; |
int j; |
for (j=1; j <= nenhere; j++) |
{ |
if (quad[kx[j]][ky[j]] == IHR) continue; // No Romulans surrender |
if (kpower[j]< pow) |
{ |
pow = kpower[j]; |
i = j; |
} |
} |
} |
return i; |
} |
#endif |
/programs/games/sstartrek/en/buildforkolibri.bat |
---|
0,0 → 1,5 |
rem To build under Windows, execute |
SET TCC=D:\_bin\ktcc_26_161007 |
%TCC%\kos32-tcc -I%TCC%\INCLUDE -L%TCC%\LIB -DWINDOWS -DKOS32 sst.c ai.c battle.c events.c finish.c moving.c osx.c planets.c reports.c setup.c -lck -o SStarTrek -g |
/programs/games/sstartrek/en/buildforwindows.txt |
---|
0,0 → 1,2 |
To build under Windows, execute |
cl -DWINDOWS sst.c ai.c battle.c events.c finish.c moving.c osx.c planets.c reports.c setup.c |
/programs/games/sstartrek/en/events.c |
---|
0,0 → 1,783 |
#include "sst.h" |
#include <math.h> |
void events(void) { |
int ictbeam=0, ipage=0, istract=0, line, i, j, k, l, ixhold, iyhold; |
double fintim = d.date + Time, datemin, xtime, repair, yank; |
#ifdef DEBUG |
if (idebug) prout("EVENTS"); |
#endif |
if (stdamtim == 1e30 && !REPORTS) |
{ |
/* chart will no longer be updated because radio is dead */ |
stdamtim = d.date; |
for (i=1; i <= 8 ; i++) |
for (j=1; j <= 8; j++) |
if (starch[i][j] == 1) starch[i][j] = d.galaxy[i][j]+1000; |
} |
for (;;) { |
/* Select earliest extraneous event, line==0 if no events */ |
line = FSPY; |
if (alldone) return; |
datemin = fintim; |
for (l=1; l<=NEVENTS; l++) |
if (future[l] <= datemin) { |
line = l; |
datemin = future[l]; |
} |
xtime = datemin-d.date; |
#ifdef CLOAKING |
if (iscloaking) { |
energy -= xtime*500.0; |
if (energy <= 0.) { |
finish(FNRG); |
return; |
} |
} |
#endif |
d.date = datemin; |
/* Decrement Federation resources and recompute remaining time */ |
d.remres -= (d.remkl+4*d.remcom)*xtime; |
d.remtime = d.remres/(d.remkl+4*d.remcom); |
if (d.remtime <=0) { |
finish(FDEPLETE); |
return; |
} |
/* Is life support adequate? */ |
if (damage[DLIFSUP] && condit != IHDOCKED) { |
if (lsupres < xtime && damage[DLIFSUP] > lsupres) { |
finish(FLIFESUP); |
return; |
} |
lsupres -= xtime; |
if (damage[DLIFSUP] <= xtime) lsupres = inlsr; |
} |
/* Fix devices */ |
repair = xtime; |
if (condit == IHDOCKED) repair /= docfac; |
/* Don't fix Deathray here */ |
for (l=1; l<=ndevice; l++) |
if (damage[l] > 0.0 && l != DDRAY) |
damage[l] -= (damage[l]-repair > 0.0 ? repair : damage[l]); |
/* Fix Deathray if docked */ |
if (damage[DDRAY] > 0.0 && condit == IHDOCKED) |
damage[DDRAY] -= (damage[l] - xtime > 0.0 ? xtime : damage[DDRAY]); |
/* If radio repaired, update star chart and attack reports */ |
if (stdamtim != 1e30 && REPORTS) { |
stdamtim = 1e30; |
prout("Lt. Uhura- \"Captain, the sub-space radio is working and"); |
prout(" surveillance reports are coming in."); |
skip(1); |
for (i=1; i <= 8 ; i++) |
for (j=1; j <= 8; j++) |
if (starch[i][j] > 999) starch[i][j] = 1; |
if (iseenit==0) { |
attakreport(); |
iseenit = 1; |
} |
skip(1); |
prout(" The star chart is now up to date.\""); |
skip(1); |
} |
/* Cause extraneous event LINE to occur */ |
Time -= xtime; |
switch (line) { |
case FSNOVA: /* Supernova */ |
if (ipage==0) pause(1); |
ipage=1; |
snova(0,0); |
future[FSNOVA] = d.date + expran(0.5*intime); |
if (d.galaxy[quadx][quady] == 1000) return; |
break; |
case FSPY: /* Check with spy to see if S.C. should tractor beam */ |
if (d.nscrem == 0 || |
#ifdef CLOAKING |
iscloaked || /* Cannot tractor beam if we can't be seen! */ |
#endif |
ictbeam+istract > 0 || |
condit==IHDOCKED || isatb==1 || iscate==1) return; |
if (ientesc || |
(energy < 2000 && torps < 4 && shield < 1250) || |
(damage[DPHASER]>0 && (damage[DPHOTON]>0 || torps < 4)) || |
(damage[DSHIELD] > 0 && |
(energy < 2500 || damage[DPHASER] > 0) && |
(torps < 5 || damage[DPHOTON] > 0))) { |
/* Tractor-beam her! */ |
istract=1; |
yank = square(d.isx-quadx) + square(d.isy-quady); |
/*********TBEAM CODE***********/ |
} |
else return; |
case FTBEAM: /* Tractor beam */ |
if (line==FTBEAM) { |
if (d.remcom == 0) { |
future[FTBEAM] = 1e30; |
break; |
} |
i = Rand()*d.remcom+1.0; |
yank = square(d.cx[i]-quadx) + square(d.cy[i]-quady); |
if (istract || condit == IHDOCKED || |
#ifdef CLOAKING |
iscloaked || /* cannot tractor beam if we can't be seen */ |
#endif |
yank == 0) { |
/* Drats! Have to reschedule */ |
future[FTBEAM] = d.date + Time + |
expran(1.5*intime/d.remcom); |
break; |
} |
} |
/* tractor beaming cases merge here */ |
yank = sqrt(yank); |
if (ipage==0) pause(1); |
ipage=1; |
Time = (10.0/(7.5*7.5))*yank; /* 7.5 is yank rate (warp 7.5) */ |
ictbeam = 1; |
skip(1); |
proutn("***"); |
crmshp(); |
prout(" caught in long range tractor beam--"); |
/* If Kirk & Co. screwing around on planet, handle */ |
atover(1); /* atover(1) is Grab */ |
if (alldone) return; |
if (icraft == 1) { /* Caught in Galileo? */ |
finish(FSTRACTOR); |
return; |
} |
/* Check to see if shuttle is aboard */ |
if (iscraft==0) { |
skip(1); |
if (Rand() >0.5) { |
prout("Galileo, left on the planet surface, is captured"); |
prout("by aliens and made into a flying McDonald's."); |
damage[DSHUTTL] = -10; |
iscraft = -1; |
} |
else { |
prout("Galileo, left on the planet surface, is well hidden."); |
} |
} |
if (line==0) { |
quadx = d.isx; |
quady = d.isy; |
} |
else { |
quadx = d.cx[i]; |
quady = d.cy[i]; |
} |
iran10(§x, §y); |
crmshp(); |
proutn(" is pulled to"); |
cramlc(1, quadx, quady); |
proutn(", "); |
cramlc(2, sectx, secty); |
skip(1); |
if (resting) { |
prout("(Remainder of rest/repair period cancelled.)"); |
resting = 0; |
} |
if (shldup==0) { |
if (damage[DSHIELD]==0 && shield > 0) { |
sheild(2); /* Shldsup */ |
shldchg=0; |
} |
else prout("(Shields not currently useable.)"); |
} |
newqad(0); |
/* Adjust finish time to time of tractor beaming */ |
fintim = d.date+Time; |
if (d.remcom <= 0) future[FTBEAM] = 1e30; |
else future[FTBEAM] = d.date+Time+expran(1.5*intime/d.remcom); |
break; |
case FSNAP: /* Snapshot of the universe (for time warp) */ |
snapsht = d; |
d.snap = 1; |
future[FSNAP] = d.date + expran(0.5 * intime); |
break; |
case FBATTAK: /* Commander attacks starbase */ |
if (d.remcom==0 || d.rembase==0) { |
/* no can do */ |
future[FBATTAK] = future[FCDBAS] = 1e30; |
break; |
} |
i = 0; |
for (j=1; j<=d.rembase; j++) { |
for (k=1; k<=d.remcom; k++) |
if (d.baseqx[j]==d.cx[k] && d.baseqy[j]==d.cy[k] && |
(d.baseqx[j]!=quadx || d.baseqy[j]!=quady) && |
(d.baseqx[j]!=d.isx || d.baseqy[j]!=d.isy)) { |
i = 1; |
break; |
} |
if (i == 1) break; |
} |
if (j>d.rembase) { |
/* no match found -- try later */ |
future[FBATTAK] = d.date + expran(0.3*intime); |
future[FCDBAS] = 1e30; |
break; |
} |
/* commander + starbase combination found -- launch attack */ |
batx = d.baseqx[j]; |
baty = d.baseqy[j]; |
future[FCDBAS] = d.date+1.0+3.0*Rand(); |
if (isatb) /* extra time if SC already attacking */ |
future[FCDBAS] += future[FSCDBAS]-d.date; |
future[FBATTAK] = future[FCDBAS] +expran(0.3*intime); |
iseenit = 0; |
if (!REPORTS) |
break; /* No warning :-( */ |
iseenit = 1; |
if (ipage==0) pause(1); |
ipage = 1; |
skip(1); |
proutn("Lt. Uhura- \"Captain, the starbase in"); |
cramlc(1, batx, baty); |
skip(1); |
prout(" reports that it is under atttack and that it can"); |
proutn(" hold out only until stardate "); |
cramf(future[FCDBAS],1,1); |
prout(".\""); |
if (resting) { |
skip(1); |
proutn("Mr. Spock- \"Captain, shall we cancel the rest period?\""); |
if (ja()) { |
resting = 0; |
Time = 0.0; |
return; |
} |
} |
break; |
case FSCDBAS: /* Supercommander destroys base */ |
future[FSCDBAS] = 1e30; |
isatb = 2; |
if (d.galaxy[d.isx][d.isy]%100 < 10) break; /* WAS RETURN! */ |
ixhold = batx; |
iyhold = baty; |
batx = d.isx; |
baty = d.isy; |
case FCDBAS: /* Commander succeeds in destroying base */ |
if (line==FCDBAS) { |
future[FCDBAS] = 1e30; |
/* find the lucky pair */ |
for (i = 1; i <= d.remcom; i++) |
if (d.cx[i]==batx && d.cy[i]==baty) break; |
if (i > d.remcom || d.rembase == 0 || |
d.galaxy[batx][baty] % 100 < 10) { |
/* No action to take after all */ |
batx = baty = 0; |
break; |
} |
} |
/* Code merges here for any commander destroying base */ |
/* Not perfect, but will have to do */ |
if (starch[batx][baty] == -1) starch[batx][baty] = 0; |
/* Handle case where base is in same quadrant as starship */ |
if (batx==quadx && baty==quady) { |
if (starch[batx][baty] > 999) starch[batx][baty] -= 10; |
quad[basex][basey]= IHDOT; |
basex=basey=0; |
newcnd(); |
skip(1); |
prout("Spock- \"Captain, I believe the starbase has been destroyed.\""); |
} |
else if (d.rembase != 1 && REPORTS) { |
/* Get word via subspace radio */ |
if (ipage==0) pause(1); |
ipage = 1; |
skip(1); |
prout("Lt. Uhura- \"Captain, Starfleet Command reports that"); |
proutn(" the starbase in"); |
cramlc(1, batx, baty); |
prout(" has been destroyed by"); |
if (isatb==2) prout("the Klingon Super-Commander"); |
else prout("a Klingon Commander"); |
} |
/* Remove Starbase from galaxy */ |
d.galaxy[batx][baty] -= 10; |
for (i=1; i <= d.rembase; i++) |
if (d.baseqx[i]==batx && d.baseqy[i]==baty) { |
d.baseqx[i]=d.baseqx[d.rembase]; |
d.baseqy[i]=d.baseqy[d.rembase]; |
} |
d.rembase--; |
if (isatb == 2) { |
/* reinstate a commander's base attack */ |
batx = ixhold; |
baty = iyhold; |
isatb = 0; |
} |
else { |
batx = baty = 0; |
} |
break; |
case FSCMOVE: /* Supercommander moves */ |
future[FSCMOVE] = d.date+0.2777; |
if (ientesc+istract==0 && |
isatb!=1 && |
(iscate!=1 || justin==1)) scom(&ipage); |
break; |
case FDSPROB: /* Move deep space probe */ |
future[FDSPROB] = d.date + 0.01; |
probex += probeinx; |
probey += probeiny; |
i = (int)(probex/10 +0.05); |
j = (int)(probey/10 + 0.05); |
if (probecx != i || probecy != j) { |
probecx = i; |
probecy = j; |
if (i < 1 || i > 8 || j < 1 || j > 8 || |
d.galaxy[probecx][probecy] == 1000) { |
// Left galaxy or ran into supernova |
if (REPORTS) { |
if (ipage==0) pause(1); |
ipage = 1; |
skip(1); |
proutn("Lt. Uhura- \"The deep space probe "); |
if (i < 1 ||i > 8 || j < 1 || j > 8) |
proutn("has left the galaxy"); |
else |
proutn("is no longer transmitting"); |
prout(".\""); |
} |
future[FDSPROB] = 1e30; |
break; |
} |
if (REPORTS) { |
if (ipage==0) pause(1); |
ipage = 1; |
skip(1); |
proutn("Lt. Uhura- \"The deep space probe is now in "); |
cramlc(1, probecx, probecy); |
prout(".\""); |
} |
} |
/* Update star chart if Radio is working or have access to |
radio. */ |
if (REPORTS) |
starch[probecx][probecy] = damage[DRADIO] > 0.0 ? |
d.galaxy[probecx][probecy]+1000 : 1; |
proben--; // One less to travel |
if (proben == 0 && isarmed && |
d.galaxy[probecx][probecy] % 10 > 0) { |
/* lets blow the sucker! */ |
snova(1,0); |
future[FDSPROB] = 1e30; |
if (d.galaxy[quadx][quady] == 1000) return; |
} |
break; |
} |
} |
} |
void waiting(void) { |
int key; |
double temp, delay, origTime; |
ididit = 0; |
for (;;) { |
key = scan(); |
if (key != IHEOL) break; |
proutn("How long? "); |
} |
chew(); |
if (key != IHREAL) { |
huh(); |
return; |
} |
origTime = delay = aaitem; |
if (delay <= 0.0) return; |
if (delay >= d.remtime || nenhere != 0) { |
prout("Are you sure? "); |
if (ja() == 0) return; |
} |
/* Alternate resting periods (events) with attacks */ |
resting = 1; |
do { |
if (delay <= 0) resting = 0; |
if (resting == 0) { |
cramf(d.remtime, 0, 2); |
prout(" stardates left."); |
return; |
} |
temp = Time = delay; |
if (nenhere) { |
double rtime = 1.0 + Rand(); |
if (rtime < temp) temp = rtime; |
Time = temp; |
} |
if (Time < delay) attack(0); |
if (nenhere==0) movetho(); |
if (alldone) return; |
events(); |
ididit = 1; |
if (alldone) return; |
delay -= temp; |
} while (d.galaxy[quadx][quady] != 1000); // leave if quadrant supernovas |
resting = 0; |
Time = 0; |
} |
void nova(int ix, int iy) { |
static double course[] = |
{0.0, 10.5, 12.0, 1.5, 9.0, 0.0, 3.0, 7.5, 6.0, 4.5}; |
int bot, top, top2, burst, hits[11][3], kount, icx, icy, mm, nn, j; |
int iquad, iquad1, i, ll, newcx, newcy, ii, jj; |
if (Rand() < 0.05) { |
/* Wow! We've supernova'ed */ |
snova(ix, iy); |
return; |
} |
/* handle initial nova */ |
quad[ix][iy] = IHDOT; |
crmena(1, IHSTAR, 2, ix, iy); |
prout(" novas."); |
d.galaxy[quadx][quady] -= 1; |
d.starkl++; |
/* Set up stack to recursively trigger adjacent stars */ |
bot = top = top2 = 1; |
kount = 0; |
icx = icy = 0; |
hits[1][1] = ix; |
hits[1][2] = iy; |
while (1) { |
for (mm = bot; mm <= top; mm++) |
for (nn = 1; nn <= 3; nn++) /* nn,j represents coordinates around current */ |
for (j = 1; j <= 3; j++) { |
if (j==2 && nn== 2) continue; |
ii = hits[mm][1]+nn-2; |
jj = hits[mm][2]+j-2; |
if (ii < 1 || ii > 10 || jj < 1 || jj > 10) continue; |
iquad = quad[ii][jj]; |
switch (iquad) { |
// case IHDOT: /* Empty space ends reaction |
// case IHQUEST: |
// case IHBLANK: |
// case IHT: |
// case IHWEB: |
default: |
break; |
case IHSTAR: /* Affect another star */ |
if (Rand() < 0.05) { |
/* This star supernovas */ |
snova(ii,jj); |
return; |
} |
top2++; |
hits[top2][1]=ii; |
hits[top2][2]=jj; |
d.galaxy[quadx][quady] -= 1; |
d.starkl++; |
crmena(1, IHSTAR, 2, ii, jj); |
prout(" novas."); |
quad[ii][jj] = IHDOT; |
break; |
case IHP: /* Destroy planet */ |
d.newstuf[quadx][quady] -= 1; |
d.nplankl++; |
crmena(1, IHP, 2, ii, jj); |
prout(" destroyed."); |
d.plnets[iplnet] = nulplanet; |
iplnet = plnetx = plnety = 0; |
if (landed == 1) { |
finish(FPNOVA); |
return; |
} |
quad[ii][jj] = IHDOT; |
break; |
case IHB: /* Destroy base */ |
d.galaxy[quadx][quady] -= 10; |
for (i = 1; i <= d.rembase; i++) |
if (d.baseqx[i]==quadx && d.baseqy[i]==quady) break; |
d.baseqx[i] = d.baseqx[d.rembase]; |
d.baseqy[i] = d.baseqy[d.rembase]; |
d.rembase--; |
basex = basey = 0; |
d.basekl++; |
newcnd(); |
crmena(1, IHB, 2, ii, jj); |
prout(" destroyed."); |
quad[ii][jj] = IHDOT; |
break; |
case IHE: /* Buffet ship */ |
case IHF: |
prout("***Starship buffeted by nova."); |
if (shldup) { |
if (shield >= 2000.0) shield -= 2000.0; |
else { |
double diff = 2000.0 - shield; |
energy -= diff; |
shield = 0.0; |
shldup = 0; |
prout("***Shields knocked out."); |
damage[DSHIELD] += 0.005*damfac*Rand()*diff; |
} |
} |
else energy -= 2000.0; |
if (energy <= 0) { |
finish(FNOVA); |
return; |
} |
/* add in course nova contributes to kicking starship*/ |
icx += sectx-hits[mm][1]; |
icy += secty-hits[mm][2]; |
kount++; |
break; |
case IHK: /* kill klingon */ |
deadkl(ii,jj,iquad, ii, jj); |
break; |
case IHC: /* Damage/destroy big enemies */ |
case IHS: |
case IHR: |
for (ll = 1; ll <= nenhere; ll++) |
if (kx[ll]==ii && ky[ll]==jj) break; |
kpower[ll] -= 800.0; /* If firepower is lost, die */ |
if (kpower[ll] <= 0.0) { |
deadkl(ii, jj, iquad, ii, jj); |
break; |
} |
newcx = ii + ii - hits[mm][1]; |
newcy = jj + jj - hits[mm][2]; |
crmena(1, iquad, 2, ii, jj); |
proutn(" damaged"); |
if (newcx<1 || newcx>10 || newcy<1 || newcy>10) { |
/* can't leave quadrant */ |
skip(1); |
break; |
} |
iquad1 = quad[newcx][newcy]; |
if (iquad1 == IHBLANK) { |
proutn(", blasted into "); |
crmena(0, IHBLANK, 2, newcx, newcy); |
skip(1); |
deadkl(ii, jj, iquad, newcx, newcy); |
break; |
} |
if (iquad1 != IHDOT) { |
/* can't move into something else */ |
skip(1); |
break; |
} |
proutn(", buffeted to"); |
cramlc(2, newcx, newcy); |
quad[ii][jj] = IHDOT; |
quad[newcx][newcy] = iquad; |
kx[ll] = newcx; |
ky[ll] = newcy; |
kavgd[ll] = sqrt(square(sectx-newcx)+square(secty-newcy)); |
kdist[ll] = kavgd[ll]; |
skip(1); |
break; |
} |
} |
if (top == top2) break; |
bot = top + 1; |
top = top2; |
} |
if (kount==0) return; |
/* Starship affected by nova -- kick it away. */ |
dist = kount*0.1; |
if (icx) icx = (icx < 0 ? -1 : 1); |
if (icy) icy = (icy < 0 ? -1 : 1); |
direc = course[3*(icx+1)+icy+2]; |
if (direc == 0.0) dist = 0.0; |
if (dist == 0.0) return; |
Time = 10.0*dist/16.0; |
skip(1); |
prout("Force of nova displaces starship."); |
iattak=2; /* Eliminates recursion problem */ |
lmove(); |
Time = 10.0*dist/16.0; |
return; |
} |
void snova(int insx, int insy) { |
int comdead, nqx, nqy, nsx, nsy, num, kldead, iscdead; |
int nrmdead, npdead; |
int insipient=0; |
nsx = insx; |
nsy = insy; |
if (insy== 0) { |
if (insx == 1) { |
/* NOVAMAX being used */ |
nqx = probecx; |
nqy = probecy; |
} |
else { |
int stars = 0; |
/* Scheduled supernova -- select star */ |
/* logic changed here so that we won't favor quadrants in top |
left of universe */ |
for (nqx = 1; nqx<=8; nqx++) { |
for (nqy = 1; nqy<=8; nqy++) { |
stars += d.galaxy[nqx][nqy] % 10; |
} |
} |
if (stars == 0) return; /* nothing to supernova exists */ |
num = Rand()*stars + 1; |
for (nqx = 1; nqx<=8; nqx++) { |
for (nqy = 1; nqy<=8; nqy++) { |
num -= d.galaxy[nqx][nqy] % 10; |
if (num <= 0) break; |
} |
if (num <=0) break; |
} |
#ifdef DEBUG |
if (idebug) { |
proutn("Super nova here?"); |
if (ja()==1) { |
nqx = quadx; |
nqy = quady; |
} |
} |
#endif |
} |
if (nqx != quady || nqy != quady || justin != 0) { |
/* it isn't here, or we just entered (treat as inroute) */ |
if (REPORTS) { |
skip(1); |
proutn("Message from Starfleet Command Stardate "); |
cramf(d.date, 0, 1); |
skip(1); |
proutn(" Supernova in"); |
cramlc(1, nqx, nqy); |
prout("; caution advised."); |
} |
} |
else { |
/* we are in the quadrant! */ |
insipient = 1; |
num = Rand()* (d.galaxy[nqx][nqy]%10) + 1; |
for (nsx=1; nsx < 10; nsx++) { |
for (nsy=1; nsy < 10; nsy++) { |
if (quad[nsx][nsy]==IHSTAR) { |
num--; |
if (num==0) break; |
} |
} |
if (num==0) break; |
} |
} |
} |
else { |
insipient = 1; |
} |
if (insipient) { |
skip(1); |
prouts("***RED ALERT! RED ALERT!"); |
skip(1); |
proutn("***Incipient supernova detected at"); |
cramlc(2, nsx, nsy); |
skip(1); |
nqx = quadx; |
nqy = quady; |
if (square(nsx-sectx) + square(nsy-secty) <= 2.1) { |
proutn("Emergency override attempts t"); |
prouts("***************"); |
skip(1); |
stars(); |
alldone=1; |
} |
} |
/* destroy any Klingons in supernovaed quadrant */ |
num=d.galaxy[nqx][nqy]; |
kldead = num/100; |
d.remkl -= kldead; // Moved here to correctly set remaining Klingon count |
comdead = iscdead = 0; |
if (nqx==d.isx && nqy == d.isy) { |
/* did in the Supercommander! */ |
d.nscrem = d.isx = d.isy = isatb = iscate = 0; |
iscdead = 1; |
kldead--; /* Get proper kill credit */ |
future[FSCMOVE] = future[FSCDBAS] = 1e30; |
} |
if (d.remcom) { |
int maxloop = d.remcom, l; |
for (l = 1; l <= maxloop; l++) { |
if (d.cx[l] == nqx && d.cy[l] == nqy) { |
d.cx[l] = d.cx[d.remcom]; |
d.cy[l] = d.cy[d.remcom]; |
d.cx[d.remcom] = d.cy[d.remcom] = 0; |
d.remcom--; |
kldead--; |
comdead++; |
if (d.remcom==0) future[FTBEAM] = 1e30; |
break; |
} |
} |
} |
/* destroy Romulans and planets in supernovaed quadrant */ |
num = d.newstuf[nqx][nqy]; |
d.newstuf[nqx][nqy] = 0; |
nrmdead = num/10; |
d.nromrem -= nrmdead; |
npdead = num - nrmdead*10; |
if (npdead) { |
int l; |
for (l = 1; l <= inplan; l++) |
if (d.plnets[l].x == nqx && d.plnets[l].y == nqy) { |
d.plnets[l] = nulplanet; |
} |
} |
/* Destroy any base in supernovaed quadrant */ |
if (d.rembase) { |
int maxloop = d.rembase, l; |
for (l = 1; l <= maxloop; l++) |
if (d.baseqx[l]==nqx && d.baseqy[l]==nqy) { |
d.baseqx[l] = d.baseqx[d.rembase]; |
d.baseqy[l] = d.baseqy[d.rembase]; |
d.baseqx[d.rembase] = d.baseqy[d.rembase] = 0; |
d.rembase--; |
break; |
} |
} |
/* If starship caused supernova, tally up destruction */ |
if (insx) { |
num = d.galaxy[nqx][nqy] % 100; |
d.starkl += num % 10; |
d.basekl += num/10; |
d.killk += kldead; |
d.killc += comdead; |
d.nromkl += nrmdead; |
d.nplankl += npdead; |
d.nsckill += iscdead; |
} |
/* mark supernova in galaxy and in star chart */ |
if ((quadx == nqx && quady == nqy) || REPORTS) |
starch[nqx][nqy] = 1; |
d.galaxy[nqx][nqy] = 1000; |
/* If supernova destroys last klingons give special message */ |
if (d.remkl==0 && (nqx != quadx || nqy != quady)) { |
skip(2); |
if (insx == 0) prout("Lucky you!"); |
proutn("A supernova in"); |
cramlc(1, nqx, nqy); |
prout(" has just destroyed the last Klingons."); |
finish(FWON); |
return; |
} |
/* if some Klingons remain, continue or die in supernova */ |
if (alldone) finish(FSNOVAED); |
return; |
} |
/programs/games/sstartrek/en/finish.c |
---|
0,0 → 1,513 |
#include "sst.h" |
#include <string.h> |
#ifndef KOS32 |
#include <time.h> |
#else |
#include <kolibrisys.h> |
#endif |
void dstrct() { |
/* Finish with a BANG! */ |
chew(); |
if (damage[DCOMPTR] != 0.0) { |
prout("Computer damaged; cannot execute destruct sequence."); |
return; |
} |
skip(1); |
prouts("---WORKING---"); skip(1); |
prout("SELF-DESTRUCT-SEQUENCE-ACTIVATED"); |
prouts(" 10"); skip(1); |
prouts(" 9"); skip(1); |
prouts(" 8"); skip(1); |
prouts(" 7"); skip(1); |
prouts(" 6"); skip(1); |
prout("ENTER-CORRECT-PASSWORD-TO-CONTINUE-"); |
prout("SELF-DESTRUCT-SEQUENCE-OTHERWISE-"); |
prout("SELF-DESTRUCT-SEQUENCE-WILL-BE-ABORTED"); |
scan(); |
chew(); |
if (strcmp(passwd, citem) != 0) { |
prouts("PASSWORD-REJECTED;"); skip(1); |
prout("CONTINUITY-EFFECTED"); |
skip(1); |
return; |
} |
prouts("PASSWORD-ACCEPTED"); skip(1); |
prouts(" 5"); skip(1); |
prouts(" 4"); skip(1); |
prouts(" 3"); skip(1); |
prouts(" 2"); skip(1); |
prouts(" 1"); skip(1); |
if (Rand() < 0.15) { |
prouts("GOODBYE-CRUEL-WORLD"); |
skip(1); |
} |
skip(2); |
kaboom(); |
} |
void kaboom(void) { |
stars(); |
if (ship==IHE) prouts("***"); |
prouts("********* Entropy of "); |
crmshp(); |
prouts(" maximized *********"); |
skip(1); |
stars(); |
skip(1); |
if (nenhere != 0) { |
double whammo = 25.0 * energy; |
int l=1; |
while (l <= nenhere) { |
if (kpower[l]*kdist[l] <= whammo) |
deadkl(kx[l],ky[l], quad[kx[l]][ky[l]], kx[l], ky[l]); |
l++; |
} |
} |
finish(FDILITHIUM); |
} |
void finish(FINTYPE ifin) { |
int igotit = 0; |
alldone = 1; |
skip(3); |
printf("It is stardate %.1f .\n\n", d.date); |
switch (ifin) { |
case FWON: // Game has been won |
if (d.nromrem != 0) |
printf("The remaining %d Romulans surrender to Starfleet Command.\n", |
d.nromrem); |
prout("You have smashed the Klingon invasion fleet and saved"); |
prout("the Federation."); |
#ifdef CAPTURE |
if (alive && brigcapacity-brigfree > 0) { // captured Klingon crew will get transfered to starbase |
kcaptured += brigcapacity-brigfree; |
printf("The %d captured Klingons are transferred to Star Fleet Command.\n", |
brigcapacity-brigfree); |
} |
#endif |
gamewon=1; |
if (alive) { |
double badpt; |
badpt = 5.*d.starkl + casual + 10.*d.nplankl + |
45.*nhelp+100.*d.basekl; |
if (ship == IHF) badpt += 100.0; |
else if (ship == 0) badpt += 200.0; |
if (badpt < 100.0) badpt = 0.0; // Close enough! |
if (d.date-indate < 5.0 || |
// killsPerDate >= RateMax |
(d.killk+d.killc+d.nsckill)/(d.date-indate) >= |
0.1*skill*(skill+1.0) + 0.1 + 0.008*badpt) { |
skip(1); |
prout("In fact, you have done so well that Starfleet Command"); |
switch (skill) { |
case SNOVICE: |
prout("promotes you one step in rank from \"Novice\" to \"Fair\"."); |
break; |
case SFAIR: |
prout("promotes you one step in rank from \"Fair\" to \"Good\"."); |
break; |
case SGOOD: |
prout("promotes you one step in rank from \"Good\" to \"Expert\"."); |
break; |
case SEXPERT: |
prout("promotes you to Commodore Emeritus."); |
skip(1); |
prout("Now that you think you're really good, try playing"); |
prout("the \"Emeritus\" game. It will splatter your ego."); |
break; |
case SEMERITUS: |
skip(1); |
prout("Computer- ERROR-ERROR-ERROR-ERROR"); |
skip(1); |
prout(" YOUR-SKILL-HAS-EXCEEDED-THE-CAPACITY-OF-THIS-PROGRAM"); |
prout(" THIS-PROGRAM-MUST-SURVIVE"); |
prout(" THIS-PROGRAM-MUST-SURVIVE"); |
prout(" THIS-PROGRAM-MUST-SURVIVE"); |
prout(" THIS-PROGRAM-MUST?- MUST ? - SUR? ? -? VI"); |
skip(1); |
prout("Now you can retire and write your own Star Trek game!"); |
skip(1); |
break; |
} |
if (skill > SGOOD) { |
if (thawed |
#ifdef DEBUG |
&& !idebug |
#endif |
) |
prout("You cannot get a citation, so..."); |
else { |
prout("Do you want your Commodore Emeritus Citation printed?"); |
proutn("(You need a 132 column printer.)"); |
chew(); |
if (ja()) { |
igotit = 1; |
} |
} |
} |
} |
// Only grant long life if alive (original didn't!) |
skip(1); |
prout("LIVE LONG AND PROSPER."); |
} |
score(0); |
if (igotit != 0) plaque(); |
return; |
case FDEPLETE: // Federation Resources Depleted |
prout("Your time has run out and the Federation has been"); |
prout("conquered. Your starship is now Klingon property,"); |
prout("and you are put on trial as a war criminal. On the"); |
proutn("basis of your record, you are "); |
if (d.remkl*3.0 > inkling) { |
prout("aquitted."); |
skip(1); |
prout("LIVE LONG AND PROSPER."); |
} |
else { |
prout("found guilty and"); |
prout("sentenced to death by slow torture."); |
alive = 0; |
} |
score(0); |
return; |
case FLIFESUP: |
prout("Your life support reserves have run out, and"); |
prout("you die of thirst, starvation, and asphyxiation."); |
prout("Your starship is a derelict in space."); |
break; |
case FNRG: |
prout("Your energy supply is exhausted."); |
skip(1); |
prout("Your starship is a derelict in space."); |
break; |
case FBATTLE: |
proutn("The "); |
crmshp(); |
prout("has been destroyed in battle."); |
skip(1); |
prout("Dulce et decorum est pro patria mori."); |
break; |
case FNEG3: |
prout("You have made three attempts to cross the negative energy"); |
prout("barrier which surrounds the galaxy."); |
skip(1); |
prout("Your navigation is abominable."); |
score(0); |
return; |
case FNOVA: |
prout("Your starship has been destroyed by a nova."); |
prout("That was a great shot."); |
skip(1); |
break; |
case FSNOVAED: |
proutn("The "); |
crmshp(); |
prout(" has been fried by a supernova."); |
prout("...Not even cinders remain..."); |
break; |
case FABANDN: |
prout("You have been captured by the Klingons. If you still"); |
prout("had a starbase to be returned to, you would have been"); |
prout("repatriated and given another chance. Since you have"); |
prout("no starbases, you will be mercilessly tortured to death."); |
break; |
case FDILITHIUM: |
prout("Your starship is now an expanding cloud of subatomic particles"); |
break; |
case FMATERIALIZE: |
prout("Starbase was unable to re-materialize your starship."); |
prout("Sic transit gloria muntdi"); |
break; |
case FPHASER: |
proutn("The "); |
crmshp(); |
prout(" has been cremated by its own phasers."); |
break; |
case FLOST: |
prout("You and your landing party have been"); |
prout("converted to energy, dissipating through space."); |
break; |
case FMINING: |
prout("You are left with your landing party on"); |
prout("a wild jungle planet inhabited by primitive cannibals."); |
skip(1); |
prout("They are very fond of \"Captain Kirk\" soup."); |
skip(1); |
proutn("Without your leadership, the "); |
crmshp(); |
prout(" is destroyed."); |
break; |
case FDPLANET: |
prout("You and your mining party perish."); |
skip(1); |
prout("That was a great shot."); |
skip(1); |
break; |
case FSSC: |
prout("The Galileo is instantly annihilated by the supernova."); |
// no break; |
case FPNOVA: |
prout("You and your mining party are atomized."); |
skip(1); |
proutn("Mr. Spock takes command of the "); |
crmshp(); |
prout(" and"); |
prout("joins the Romulans, reigning terror on the Federation."); |
break; |
case FSTRACTOR: |
prout("The shuttle craft Galileo is also caught,"); |
prout("and breaks up under the strain."); |
skip(1); |
prout("Your debris is scattered for millions of miles."); |
proutn("Without your leadership, the "); |
crmshp(); |
prout(" is destroyed."); |
break; |
case FDRAY: |
prout("The mutants attack and kill Spock."); |
prout("Your ship is captured by Klingons, and"); |
prout("your crew is put on display in a Klingon zoo."); |
break; |
case FTRIBBLE: |
prout("Tribbles consume all remaining water,"); |
prout("food, and oxygen on your ship."); |
skip(1); |
prout("You die of thirst, starvation, and asphyxiation."); |
prout("Your starship is a derelict in space."); |
break; |
case FHOLE: |
prout("Your ship is drawn to the center of the black hole."); |
prout("You are crushed into extremely dense matter."); |
break; |
#ifdef CLOAKING |
case FCLOAK: |
ncviol++; |
prout("You have violated the Treaty of Algeron."); |
prout("The Romulan Empire can never trust you again."); |
break; |
#endif |
} |
#ifdef CLOAKING |
if (ifin!=FWON && ifin!=FCLOAK && iscloaked!=0) { |
prout("Your ship was cloaked so your subspace radio did not receive anything."); |
prout("You may have missed some warning messages."); |
skip(1); |
} |
#endif |
if (ship==IHF) ship= 0; |
else if (ship == IHE) ship = IHF; |
alive = 0; |
if (d.remkl != 0) { |
double goodies = d.remres/inresor; |
double baddies = (d.remkl + 2.0*d.remcom)/(inkling+2.0*incom); |
if (goodies/baddies >= 1.0+0.5*Rand()) { |
prout("As a result of your actions, a treaty with the Klingon"); |
prout("Empire has been signed. The terms of the treaty are"); |
if (goodies/baddies >= 3.0+Rand()) { |
prout("favorable to the Federation."); |
skip(1); |
prout("Congratulations!"); |
} |
else |
prout("highly unfavorable to the Federation."); |
} |
else |
prout("The Federation will be destroyed."); |
} |
else { |
prout("Since you took the last Klingon with you, you are a"); |
prout("martyr and a hero. Someday maybe they'll erect a"); |
prout("statue in your memory. Rest in peace, and try not"); |
prout("to think about pigeons."); |
gamewon = 1; |
} |
score(0); |
} |
void score(int inGame) { |
double timused = d.date - indate; |
int ithperd, iwon, klship; |
int dnromrem = d.nromrem; // Leave global value alone |
if (!inGame) pause(0); |
iskill = skill; |
if ((timused == 0 || d.remkl != 0) && timused < 5.0) timused = 5.0; |
perdate = (d.killc + d.killk + d.nsckill)/timused; |
ithperd = 500*perdate + 0.5; |
iwon = 0; |
if (gamewon) iwon = 100*skill; |
if (ship == IHE) klship = 0; |
else if (ship == IHF) klship = 1; |
else klship = 2; |
if (gamewon == 0 || inGame) dnromrem = 0; // None captured if no win or if still in the game |
iscore = 10*d.killk + 50*d.killc + ithperd + iwon |
- 100*d.basekl - 100*klship - 45*nhelp -5*d.starkl - casual |
+ 20*d.nromkl + 200*d.nsckill - 10*d.nplankl + dnromrem; |
#ifdef CLOAKING |
iscore -= 100*ncviol; |
#endif |
#ifdef CAPTURE |
iscore += 3*kcaptured; |
#endif |
if (alive == 0) iscore -= 200; |
skip(2); |
if (inGame) prout("Your score so far --"); |
else prout("Your score --"); |
if (d.nromkl) |
printf(d.nromkl> 1 ? "%6d Romulan ships destroyed %5d\n" : "%6d Romulan ship destroyed %5d\n", |
d.nromkl, 20*d.nromkl); |
if (dnromrem) |
printf(dnromrem > 1 ? "%6d Romulan ships captured %5d\n" : "%6d Romulan ship captured %5d\n", |
dnromrem, dnromrem); |
if (d.killk) |
printf(d.killk > 1 ? "%6d ordinary Klingon ships destroyed %5d\n" : "%6d ordinary Klingon ship destroyed %5d\n", |
d.killk, 10*d.killk); |
if (d.killc) |
printf(d.killc > 1 ? "%6d Klingon Commander ships destroyed %5d\n" : "%6d Klingon Commander ship destroyed %5d\n", |
d.killc, 50*d.killc); |
if (d.nsckill) |
printf("%6d Super-Commander ship destroyed %5d\n", |
d.nsckill, 200*d.nsckill); |
if (ithperd) |
printf("%6.2f Klingons per stardate %5d\n", |
perdate, ithperd); |
#ifdef CAPTURE |
if (kcaptured) |
printf(kcaptured > 1 ? "%6d Klingons captured %5d\n" : "%6d Klingon captured %5d\n", |
kcaptured, 3*kcaptured); |
#endif |
if (d.starkl) |
printf(d.starkl > 1 ? "%6d stars destroyed by your action %5d\n" : "%6d star destroyed by your action %5d\n", |
d.starkl, -5*d.starkl); |
if (d.nplankl) |
printf(d.nplankl > 1 ? "%6d planets destroyed by your action %5d\n" : "%6d planet destroyed by your action %5d\n", |
d.nplankl, -10*d.nplankl); |
if (d.basekl) |
printf(d.basekl > 1 ? "%6d bases destroyed by your action %5d\n" : "%6d base destroyed by your action %5d\n", |
d.basekl, -100*d.basekl); |
if (nhelp) |
printf(nhelp > 1 ? "%6d calls for help from starbase %5d\n" : "%6d call for help from starbase %5d\n", |
nhelp, -45*nhelp); |
if (casual) |
printf(casual > 1 ? "%6d casualties incurred %5d\n" : "%6d casualty incurred %5d\n", |
casual, -casual); |
if (klship) |
printf(klship > 1 ? "%6d ships lost or destroyed %5d\n" : "%6d ship lost or destroyed %5d\n", |
klship, -100*klship); |
#ifdef CLOAKING |
if (ncviol>0) |
printf(ncviol > 1 ? "%6d Treaty of Algeron violations %5d\n" : "%6d Treaty of Algeron violation %5d\n", |
ncviol, -100*ncviol); |
#endif |
if (alive==0) |
prout("Penalty for getting yourself killed -200"); |
if (gamewon) { |
skip(1); |
proutn("Bonus for winning "); |
switch (skill) { |
case SNOVICE: proutn("Novice game "); break; |
case SFAIR: proutn("Fair game "); break; |
case SGOOD: proutn("Good game "); break; |
case SEXPERT: proutn("Expert game "); break; |
case SEMERITUS: proutn("Emeritus game"); break; |
} |
printf(" %5d\n", iwon); |
} |
skip(2); |
printf("TOTAL SCORE %5d\n", iscore); |
if (inGame && skill < SGOOD) printf("REMEMBER--The score doesn't really matter until the mission is accomplished!\n"); |
} |
void plaque(void) { |
FILE *fp=NULL; |
#ifndef KOS32 |
time_t t; |
#else |
int kos_date, kos_time; |
#endif |
char *timestring; |
int nskip; |
char winner[128]; |
skip(2); |
while (fp == NULL) { |
printf("File or device name for your plaque:"); |
#ifndef KOS32 |
fgets(winner, 128, stdin); |
#else |
gets(winner); |
#endif |
winner[strlen(winner)-1] = '\0'; |
fp = fopen(winner, "w"); |
if (fp==NULL) { |
printf("Invalid name.\n"); |
} |
} |
printf("Enter name to go on plaque (up to 30 characters):"); |
#ifndef KOS32 |
fgets(winner, 128, stdin); |
#else |
gets(winner); |
#endif winner[strlen(winner)-1] = '\0'; |
winner[30] = '\0'; |
nskip = 64 - strlen(winner)/2; |
fprintf(fp,"\n\n\n\n"); |
/* --------DRAW ENTERPRISE PICTURE. */ |
fprintf(fp, " EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n" ); |
fprintf(fp, " EEE E : : : E\n" ); |
fprintf(fp, " EE EEE E : : NCC-1701 : E\n"); |
fprintf(fp, " EEEEEEEEEEEEEEEE EEEEEEEEEEEEEEE E : : : E\n"); |
fprintf(fp, " E E EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n"); |
fprintf(fp, " EEEEEEEEE EEEEEEEEEEEEE E E\n"); |
fprintf(fp, " EEEEEEE EEEEE E E E E\n"); |
fprintf(fp, " EEE E E E E\n"); |
fprintf(fp, " E E E E\n"); |
fprintf(fp, " EEEEEEEEEEEEE E E\n"); |
fprintf(fp, " EEE : EEEEEEE EEEEEEEE\n"); |
fprintf(fp, " :E : EEEE E\n"); |
fprintf(fp, " .-E -:----- E\n"); |
fprintf(fp, " :E : E\n"); |
fprintf(fp, " EE : EEEEEEEE\n"); |
fprintf(fp, " EEEEEEEEEEEEEEEEEEEEEEE\n"); |
fprintf(fp, "\n\n\n"); |
fprintf(fp, " U. S. S. ENTERPRISE\n"); |
fprintf(fp, "\n\n\n\n"); |
fprintf(fp, " For demonstrating outstanding ability as a starship captain\n"); |
fprintf(fp, "\n"); |
fprintf(fp, " Starfleet Command bestows to you\n"); |
fprintf(fp, "\n"); |
fprintf(fp,"%*s%s\n\n", nskip, "", winner); |
fprintf(fp, " the rank of\n\n"); |
fprintf(fp, " \"Commodore Emeritus\"\n\n"); |
fprintf(fp, " "); |
switch (iskill) { |
case SEXPERT: fprintf(fp," Expert level\n\n"); break; |
case SEMERITUS: fprintf(fp,"Emeritus level\n\n"); break; |
default: fprintf(fp," Cheat level\n\n"); break; |
} |
#ifndef KOS32 |
t = time(NULL); |
timestring = ctime(&t); |
fprintf(fp, " This day of %.6s %.4s, %.8s\n\n", |
timestring+4, timestring+20, timestring+11); |
#else |
kos_date = _ksys_get_date(); |
kos_time = _ksys_get_system_clock(); |
fprintf(fp, " This day of %02i/%02i/%02i %02i:%02i:%02i\n\n", |
kos_date >> 16, (kos_date & 0xFF00) >> 8, (kos_date & 0xFF) + 2000, |
kos_time & 0xFF, (kos_time & 0xFF00) >> 8, kos_time >> 16 ); |
#endif |
fprintf(fp," Your score: %d\n\n", iscore); |
fprintf(fp," Klingons per stardate: %.2f\n", perdate); |
fclose(fp); |
} |
/programs/games/sstartrek/en/makefile |
---|
0,0 → 1,19 |
# CFLAGS= -O -DSCORE -DCAPTURE -DCLOAKING -Wno-unused-result |
CFLAGS= -O -Wno-unused-result -DWINDOWS |
CC=gcc |
.c.o: |
$(CC) $(CFLAGS) -c $< |
OFILES= sst.o finish.o reports.o setup.o osx.o moving.o battle.o events.o ai.o planets.o |
HFILES= sst.h |
sst: $(OFILES) |
gcc -o sst $(OFILES) -lm |
clean: |
rm $(OFILES) |
$(OFILES): $(HFILES) |
/programs/games/sstartrek/en/moving.c |
---|
0,0 → 1,1017 |
#include "sst.h" |
static void getcd(int, int); |
void lmove(void) { |
double angle, deltax, deltay, bigger, x, y, |
finald, finalx, finaly, stopegy; |
int oldquadx, oldquady; |
int trbeam = 0, n, l, ix, iy, kink, kinks, iquad; |
if (inorbit) { |
prout("SULU- \"Leaving standard orbit.\""); |
inorbit = 0; |
} |
angle = ((15.0 - direc) * 0.5235988); |
deltax = -sin(angle); |
deltay = cos(angle); |
if (fabs(deltax) > fabs(deltay)) |
bigger = fabs(deltax); |
else |
bigger = fabs(deltay); |
deltay /= bigger; |
deltax /= bigger; |
#ifdef CLOAKING |
if (iscloaked && d.date+Time >= future[FTBEAM]) |
{ /* We can't be tracto beamed if cloaked, so move the event into the future */ |
future[FTBEAM] = d.date + Time + |
expran(1.5*intime/d.remcom); |
} |
#endif |
/* If tractor beam is to occur, don't move full distance */ |
if (d.date+Time >= future[FTBEAM]) { |
trbeam = 1; |
condit = IHRED; |
dist = dist*(future[FTBEAM]-d.date)/Time + 0.1; |
Time = future[FTBEAM] - d.date + 1e-5; |
} |
/* Move within the quadrant */ |
quad[sectx][secty] = IHDOT; |
x = sectx; |
y = secty; |
n = 10.0*dist*bigger+0.5; |
if (n > 0) { |
for (l = 1; l <= n; l++) { |
ix = (x += deltax) + 0.5; |
iy = (y += deltay) + 0.5; |
if (ix < 1 || ix > 10 || iy < 1 || iy > 10) { |
/* Leaving quadrant -- allow final enemy attack */ |
/* Don't do it if being pushed by Nova */ |
if (nenhere != 0 && iattak != 2 |
#ifdef CLOAKING |
&& !iscloaked |
#endif |
) { |
newcnd(); |
for (l = 1; l <= nenhere; l++) { |
finald = sqrt((ix-kx[l])*(double)(ix-kx[l]) + |
(iy-ky[l])*(double)(iy-ky[l])); |
kavgd[l] = 0.5 * (finald+kdist[l]); |
} |
if (d.galaxy[quadx][quady] != 1000) attack(0); |
if (alldone) return; |
} |
/* compute final position -- new quadrant and sector */ |
x = 10*(quadx-1)+sectx; |
y = 10*(quady-1)+secty; |
ix = x+10.0*dist*bigger*deltax+0.5; |
iy = y+10.0*dist*bigger*deltay+0.5; |
/* check for edge of galaxy */ |
kinks = FALSE; |
do { |
kink = 0; |
if (ix <= 0) { |
ix = -ix + 1; |
kink = 1; |
} |
if (iy <= 0) { |
iy = -iy + 1; |
kink = 1; |
} |
if (ix > 80) { |
ix = 161 - ix; |
kink = 1; |
} |
if (iy > 80) { |
iy = 161 - iy; |
kink = 1; |
} |
if (kink) kinks = TRUE; |
} while (kink); |
if (kinks) { |
nkinks += 1; |
if (nkinks == 3) { |
/* Three strikes -- you're out! */ |
finish(FNEG3); |
return; |
} |
prout("\nYOU HAVE ATTEMPTED TO CROSS THE NEGATIVE ENERGY BARRIER\n" |
"AT THE EDGE OF THE GALAXY. THE THIRD TIME YOU TRY THIS,\n" |
"YOU WILL BE DESTROYED.\n"); |
} |
/* Compute final position in new quadrant */ |
if (trbeam) return; /* Don't bother if we are to be beamed */ |
oldquadx = quadx; |
oldquady = quady; |
quadx = (ix+9)/10; |
quady = (iy+9)/10; |
sectx = ix - 10*(quadx-1); |
secty = iy - 10*(quady-1); |
if (quadx != oldquadx || quady != oldquady) { |
proutn("\nEntering"); |
cramlc(1, quadx, quady); |
} else { |
prout("(Negative energy barrier disturbs quadrant.)"); |
} |
skip(1); |
quad[sectx][secty] = ship; |
newqad(0); |
return; |
} |
iquad = quad[ix][iy]; |
if (iquad != IHDOT) { |
/* object encountered in flight path */ |
stopegy = 50.0*dist/Time; |
dist=0.1*sqrt((sectx-ix)*(double)(sectx-ix) + |
(secty-iy)*(double)(secty-iy)); |
switch (iquad) { |
case IHT: /* Ram a Tholean */ |
case IHK: /* Ram enemy ship */ |
case IHC: |
case IHS: |
case IHR: |
sectx = ix; |
secty = iy; |
ram(0, iquad, sectx, secty); |
finalx = sectx; |
finaly = secty; |
break; |
case IHBLANK: |
skip(1); |
prouts("***RED ALERT! RED ALERT!"); |
skip(1); |
proutn("***"); |
crmshp(); |
proutn(" pulled into black hole at"); |
cramlc(2, ix, iy); |
skip(1); |
finish(FHOLE); |
return; |
default: |
/* something else */ |
skip(1); |
crmshp(); |
if (iquad == IHWEB) |
proutn(" encounters Tholian web at"); |
else |
proutn(" blocked by object at"); |
cramlc(2, ix,iy); |
prout(";"); |
proutn("Emergency stop required "); |
cramf(stopegy, 0, 2); |
prout(" units of energy."); |
energy -= stopegy; |
finalx = x-deltax+0.5; |
sectx = finalx; |
finaly = y-deltay+0.5; |
secty = finaly; |
if (energy <= 0) { |
finish(FNRG); |
return; |
} |
break; |
} |
goto label100; /* sorry! */ /* ACTUALLY BREAK SHOULD WORK HERE */ |
} |
} |
dist = 0.1*sqrt((sectx-ix)*(double)(sectx-ix) + |
(secty-iy)*(double)(secty-iy)); |
sectx = ix; |
secty = iy; |
} |
finalx = sectx; /* THESE STATEMENTS DO NOTHING USEFUL */ |
finaly = secty; |
label100: |
/* No quadrant change -- compute new avg enemy distances */ |
quad[sectx][secty] = ship; |
if (nenhere) { |
for (l = 1; l <= nenhere; l++) { |
finald = sqrt((ix-kx[l])*(double)(ix-kx[l]) + |
(iy-ky[l])*(double)(iy-ky[l])); |
kavgd[l] = 0.5 * (finald+kdist[l]); |
kdist[l] = finald; |
} |
sortkl(); |
if (d.galaxy[quadx][quady] != 1000 && iattak == 0) |
attack(0); |
for (l = 1 ; l <= nenhere; l++) kavgd[l] = kdist[l]; |
} |
newcnd(); |
iattak = 0; |
return; |
} |
void dock(void) { |
chew(); |
if (condit == IHDOCKED) { |
prout("Already docked."); |
return; |
} |
if (inorbit) { |
prout("You must first leave standard orbit."); |
return; |
} |
if (basex==0 || abs(sectx-basex) > 1 || abs(secty-basey) > 1) { |
crmshp(); |
prout(" not adjacent to base."); |
return; |
} |
#ifdef CLOAKING |
if (iscloaked) { |
prout("You cannot dock while cloaked."); |
return; |
} |
#endif |
condit = IHDOCKED; |
prout("Docked."); |
if (energy < inenrg) energy = inenrg; |
shield = inshld; |
torps = intorps; |
lsupres = inlsr; |
#ifdef CAPTURE |
if (brigcapacity-brigfree > 0) |
{ |
printf("%d captured Klingons transferred to base.\n", brigcapacity-brigfree); |
kcaptured += brigcapacity-brigfree; |
brigfree = brigcapacity; |
} |
#endif |
if (stdamtim != 1e30 && |
(future[FCDBAS] < 1e30 || isatb == 1) && iseenit == 0) { |
/* get attack report from base */ |
prout("Lt. Uhura- \"Captain, an important message from the starbase:\""); |
attakreport(); |
iseenit = 1; |
} |
} |
static void getcd(int isprobe, int akey) { |
/* This program originally required input in terms of a (clock) |
direction and distance. Somewhere in history, it was changed to |
cartesian coordinates. So we need to convert. I think |
"manual" input should still be done this way -- it's a real |
pain if the computer isn't working! Manual mode is still confusing |
because it involves giving x and y motions, yet the coordinates |
are always displayed y - x, where +y is downward! */ |
int irowq=quadx, icolq=quady, irows, icols, itemp=0, iprompt=0, key; |
double xi, xj, xk, xl; |
double deltax, deltay; |
int automatic = -1; |
/* Get course direction and distance. If user types bad values, return |
with DIREC = -1.0. */ |
direc = -1.0; |
if (landed == 1 && !isprobe) { |
prout("Dummy! You can't leave standard orbit until you"); |
proutn("are back aboard the "); |
crmshp(); |
prout("."); |
chew(); |
return; |
} |
while (automatic == -1) { |
if (damage[DCOMPTR]) { |
if (isprobe) |
prout("Computer damaged; manual navigation only"); |
else |
prout("Computer damaged; manual movement only"); |
chew(); |
automatic = 0; |
key = IHEOL; |
break; |
} |
if (isprobe && akey != -1) { |
/* For probe launch, use pre-scaned value first time */ |
key = akey; |
akey = -1; |
} |
else |
key = scan(); |
if (key == IHEOL) { |
proutn("Manual or automatic- "); |
iprompt = 1; |
chew(); |
} |
else if (key == IHALPHA) { |
if (isit("manual")) { |
automatic =0; |
key = scan(); |
break; |
} |
else if (isit("automatic")) { |
automatic = 1; |
key = scan(); |
break; |
} |
else { |
huh(); |
chew(); |
return; |
} |
} |
else { /* numeric */ |
if (isprobe) |
prout("(Manual navigation assumed.)"); |
else |
prout("(Manual movement assumed.)"); |
automatic = 0; |
break; |
} |
} |
if (automatic) { |
while (key == IHEOL) { |
if (isprobe) |
proutn("Target quadrant or quadrant§or- "); |
else |
proutn("Destination sector or quadrant§or- "); |
chew(); |
iprompt = 1; |
key = scan(); |
} |
if (key != IHREAL) { |
huh(); |
return; |
} |
xi = aaitem; |
key = scan(); |
if (key != IHREAL){ |
huh(); |
return; |
} |
xj = aaitem; |
key = scan(); |
if (key == IHREAL) { |
/* both quadrant and sector specified */ |
xk = aaitem; |
key = scan(); |
if (key != IHREAL) { |
huh(); |
return; |
} |
xl = aaitem; |
irowq = xi + 0.5; |
icolq = xj + 0.5; |
irows = xk + 0.5; |
icols = xl + 0.5; |
} |
else { |
if (isprobe) { |
/* only quadrant specified -- go to center of dest quad */ |
irowq = xi + 0.5; |
icolq = xj + 0.5; |
irows = icols = 5; |
} |
else { |
irows = xi + 0.5; |
icols = xj + 0.5; |
} |
itemp = 1; |
} |
if (irowq<1 || irowq > 8 || icolq<1 || icolq > 8 || |
irows<1 || irows > 10 || icols<1 || icols > 10) { |
huh(); |
return; |
} |
skip(1); |
if (!isprobe) { |
if (itemp) { |
if (iprompt) { |
proutn("Helmsman Sulu- \"Course locked in for"); |
cramlc(2, irows, icols); |
prout(".\""); |
} |
} |
else prout("Ensign Chekov- \"Course laid in, Captain.\""); |
} |
deltax = icolq - quady + 0.1*(icols-secty); |
deltay = quadx - irowq + 0.1*(sectx-irows); |
} |
else { /* manual */ |
while (key == IHEOL) { |
proutn("X and Y displacements- "); |
chew(); |
iprompt = 1; |
key = scan(); |
} |
itemp = 2; |
if (key != IHREAL) { |
huh(); |
return; |
} |
deltax = aaitem; |
key = scan(); |
if (key == IHEOL) { |
deltay = 0.0; |
} else if (key != IHREAL) { |
huh(); |
return; |
} else { |
deltay = aaitem; |
} |
if (coordfixed) { |
double temp = deltax; |
deltax = deltay; |
deltay = -temp; |
} |
} |
/* Check for zero movement */ |
if (deltax == 0 && deltay == 0) { |
chew(); |
return; |
} |
if (itemp == 2 && !isprobe) { |
skip(1); |
prout("Helmsman Sulu- \"Aye, Sir.\""); |
} |
dist = sqrt(deltax*deltax + deltay*deltay); |
direc = atan2(deltax, deltay)*1.90985932; |
if (direc < 0.0) direc += 12.0; |
chew(); |
return; |
} |
void impuls(void) { |
double power; |
ididit = 0; |
if (damage[DIMPULS]) { |
chew(); |
skip(1); |
prout("Engineer Scott- \"The impulse engines are damaged, Sir.\""); |
return; |
} |
if (energy > 30.0) { |
getcd(FALSE, 0); |
if (direc == -1.0) return; |
power = 20.0 + 100.0*dist; |
} |
else |
power = 30.0; |
if (power >= energy) { |
/* Insufficient power for trip */ |
skip(1); |
prout("First Officer Spock- \"Captain, the impulse engines"); |
prout("require 20.0 units to engage, plus 100.0 units per"); |
if (energy > 30) { |
proutn("quadrant. We can go, therefore, a maximum of "); |
cramf(0.01 * (energy-20.0)-0.05, 0, 1); |
prout(" quadrants.\""); |
} |
else { |
prout("quadrant. They are, therefore, useless.\""); |
} |
chew(); |
return; |
} |
/* Make sure enough time is left for the trip */ |
Time = dist/0.095; |
if (Time >= d.remtime) { |
prout("First Officer Spock- \"Captain, our speed under impulse"); |
prout("power is only 0.95 sectors per stardate. Are you sure"); |
prout("we dare spend the time?\""); |
if (ja() == 0) { Time = 0.0; return;} |
} |
/* Activate impulse engines and pay the cost */ |
lmove(); |
ididit = 1; |
if (alldone) return; |
power = 20.0 + 100.0*dist; |
energy -= power; |
// Time = dist/0.095; Don't recalculate because lmove may have |
// adjusted it for tractor beaming |
if (energy <= 0) finish(FNRG); |
return; |
} |
void warp(int i) { |
int blooey=0, twarp=0, iwarp; |
double power; |
if (i!=2) { /* Not WARPX entry */ |
ididit = 0; |
#ifdef CLOAKING |
if (iscloaked) { |
chew(); |
skip(1); |
prout("Engineer Scott- \"The warp engines can better not be used while cloaked, Sir.\""); |
return; |
} |
#endif |
if (damage[DWARPEN] > 10.0) { |
chew(); |
skip(1); |
prout("Engineer Scott- \"The warp engines are damaged, Sir.\""); // Was "Impulse" 10/2013 |
return; |
} |
if (damage[DWARPEN] > 0.0 && warpfac > 4.0) { |
chew(); |
skip(1); |
prout("Engineer Scott- \"Sorry, Captain. Until this damage"); |
prout(" is repaired, I can only give you warp 4.\""); |
return; |
} |
/* Read in course and distance */ |
getcd(FALSE, 0); |
if (direc == -1.0) return; |
/* Make sure starship has enough energy for the trip */ |
power = (dist+0.05)*warpfac*warpfac*warpfac*(shldup+1); |
if (power >= energy) { |
/* Insufficient power for trip */ |
ididit = 0; |
skip(1); |
prout("Engineering to bridge--"); |
if (shldup==0 || 0.5*power > energy) { |
iwarp = pow((energy/(dist+0.05)), 0.333333333); |
if (iwarp <= 0) { |
prout("We can't do it, Captain. We haven't the energy."); |
} |
else { |
proutn("We haven't the energy, but we could do it at warp "); |
crami(iwarp, 1); |
if (shldup) |
prout(",\nif you'll lower the shields."); |
else |
prout("."); |
} |
} |
else |
prout("We haven't the energy to go that far with the shields up."); |
return; |
} |
/* Make sure enough time is left for the trip */ |
Time = 10.0*dist/wfacsq; |
if (Time >= 0.8*d.remtime) { |
skip(1); |
prout("First Officer Spock- \"Captain, I compute that such"); |
proutn(" a trip would require approximately "); |
cramf(100.0*Time/d.remtime, 0, 2); |
prout(" percent of our"); |
prout(" remaining time. Are you sure this is wise?\""); |
if (ja() == 0) { Time = 0.0; return;} |
} |
} |
/* Entry WARPX */ |
if (warpfac > 6.0) { |
/* Decide if engine damage will occur */ |
double prob = dist*(6.0-warpfac)*(6.0-warpfac)/66.666666666; |
if (prob > Rand()) { |
blooey = 1; |
dist = Rand()*dist; |
} |
/* Decide if time warp will occur */ |
if (0.5*dist*pow(7.0,warpfac-10.0) > Rand()) twarp=1; |
#ifdef DEBUG |
if (idebug &&warpfac==10 && twarp==0) { |
blooey=0; |
proutn("Force time warp? "); |
if (ja()==1) twarp=1; |
} |
#endif |
if (blooey || twarp) { |
/* If time warp or engine damage, check path */ |
/* If it is obstructed, don't do warp or damage */ |
double angle = ((15.0-direc)*0.5235998); |
double deltax = -sin(angle); |
double deltay = cos(angle); |
double bigger, x, y; |
int n, l, ix, iy; |
if (fabs(deltax) > fabs(deltay)) |
bigger = fabs(deltax); |
else |
bigger = fabs(deltay); |
deltax /= bigger; |
deltay /= bigger; |
n = 10.0 * dist * bigger +0.5; |
x = sectx; |
y = secty; |
for (l = 1; l <= n; l++) { |
x += deltax; |
ix = x + 0.5; |
if (ix < 1 || ix > 10) break; |
y += deltay; |
iy = y +0.5; |
if (iy < 1 || iy > 10) break; |
if (quad[ix][iy] != IHDOT) { |
blooey = 0; |
twarp = 0; |
} |
} |
} |
} |
/* Activate Warp Engines and pay the cost */ |
lmove(); |
if (alldone) return; |
energy -= dist*warpfac*warpfac*warpfac*(shldup+1); |
if (energy <= 0) finish(FNRG); |
Time = 10.0*dist/wfacsq; |
if (twarp) timwrp(); |
if (blooey) { |
damage[DWARPEN] = damfac*(3.0*Rand()+1.0); |
skip(1); |
prout("Engineering to bridge--"); |
prout(" Scott here. The warp engines are damaged."); |
prout(" We'll have to reduce speed to warp 4."); |
} |
ididit = 1; |
return; |
} |
void setwrp(void) { |
int key; |
double oldfac; |
while ((key=scan()) == IHEOL) { |
chew(); |
proutn("Warp factor-"); |
} |
chew(); |
if (key != IHREAL) { |
huh(); |
return; |
} |
if (damage[DWARPEN] > 10.0) { |
prout("Warp engines inoperative."); |
return; |
} |
if (damage[DWARPEN] > 0.0 && aaitem > 4.0) { |
prout("Engineer Scott- \"I'm doing my best, Captain,\n" |
" but right now we can only go warp 4.\""); |
return; |
} |
if (aaitem > 10.0) { |
prout("Helmsman Sulu- \"Our top speed is warp 10, Captain.\""); |
return; |
} |
if (aaitem < 1.0) { |
prout("Helmsman Sulu- \"We can't go below warp 1, Captain.\""); |
return; |
} |
oldfac = warpfac; |
warpfac = aaitem; |
wfacsq=warpfac*warpfac; |
if (warpfac <= oldfac || warpfac <= 6.0) { |
proutn("Helmsman Sulu- \"Warp factor "); |
cramf(warpfac, 0, 1); |
prout(", Captain.\""); |
return; |
} |
if (warpfac < 8.00) { |
prout("Engineer Scott- \"Aye, but our maximum safe speed is warp 6.\""); |
return; |
} |
if (warpfac == 10.0) { |
prout("Engineer Scott- \"Aye, Captain, we'll try it.\""); |
return; |
} |
prout("Engineer Scott- \"Aye, Captain, but our engines may not take it.\""); |
return; |
} |
void atover(int igrab) { |
double power, distreq; |
chew(); |
/* is captain on planet? */ |
if (landed==1) { |
if (damage[DTRANSP]) { |
finish(FPNOVA); |
return; |
} |
prout("Scotty rushes to the transporter controls."); |
if (shldup) { |
prout("But with the shields up it's hopeless."); |
finish(FPNOVA); |
} |
prouts("His desperate attempt to rescue you . . ."); |
if (Rand() <= 0.5) { |
prout("fails."); |
finish(FPNOVA); |
return; |
} |
prout("SUCCEEDS!"); |
if (imine) { |
imine = 0; |
proutn("The crystals mined were "); |
if (Rand() <= 0.25) { |
prout("lost."); |
} |
else { |
prout("saved."); |
icrystl = 1; |
} |
} |
} |
if (igrab) return; |
/* Check to see if captain in shuttle craft */ |
if (icraft) finish(FSTRACTOR); |
if (alldone) return; |
/* Inform captain of attempt to reach safety */ |
skip(1); |
do { |
if (justin) { |
prouts("***RED ALERT! RED ALERT!"); |
skip(1); |
proutn("The "); |
crmshp(); |
prout(" has stopped in a quadrant containing"); |
prouts(" a supernova."); |
skip(2); |
} |
proutn("***Emergency automatic override attempts to hurl "); |
crmshp(); |
skip(1); |
prout("safely out of quadrant."); |
starch[quadx][quady] = damage[DRADIO] > 0.0 ? d.galaxy[quadx][quady]+1000:1; |
/* Try to use warp engines */ |
if (damage[DWARPEN]) { |
skip(1); |
prout("Warp engines damaged."); |
finish(FSNOVAED); |
return; |
} |
warpfac = 6.0+2.0*Rand(); |
wfacsq = warpfac * warpfac; |
proutn("Warp factor set to "); |
cramf(warpfac, 1, 1); |
skip(1); |
power = 0.75*energy; |
dist = power/(warpfac*warpfac*warpfac*(shldup+1)); |
distreq = 1.4142+Rand(); |
if (distreq < dist) dist = distreq; |
Time = 10.0*dist/wfacsq; |
direc = 12.0*Rand(); /* How dumb! */ |
justin = 0; |
inorbit = 0; |
warp(2); |
if (justin == 0) { |
/* This is bad news, we didn't leave quadrant. */ |
if (alldone) return; |
skip(1); |
prout("Insufficient energy to leave quadrant."); |
finish(FSNOVAED); |
return; |
} |
/* Repeat if another snova */ |
} while (d.galaxy[quadx][quady] == 1000); |
if (d.remkl==0) finish(FWON); /* Snova killed remaining enemy. */ |
} |
void timwrp() { |
int l, ll, gotit; |
prout("***TIME WARP ENTERED."); |
if (d.snap && Rand() < 0.5) { |
/* Go back in time */ |
proutn("You are traveling backwards in time "); |
cramf(d.date-snapsht.date, 0, 2); |
prout(" stardates."); |
d = snapsht; |
d.snap = 0; |
if (d.remcom) { |
future[FTBEAM] = d.date + expran(intime/d.remcom); |
future[FBATTAK] = d.date + expran(0.3*intime); |
} |
future[FSNOVA] = d.date + expran(0.5*intime); |
future[FSNAP] = d.date +expran(0.25*d.remtime); /* next snapshot will |
be sooner */ |
if (d.nscrem) future[FSCMOVE] = 0.2777; |
isatb = 0; |
future[FCDBAS] = future[FSCDBAS] = 1e30; |
batx = baty = 0; |
/* Make sure Galileo is consistant -- Snapshot may have been taken |
when on planet, which would give us two Galileos! */ |
gotit = 0; |
for (l = 1; l <= inplan; l++) { |
if (d.plnets[l].known == 2) { |
gotit = 1; |
if (iscraft==1 && ship==IHE) { |
prout("Checkov- \"Security reports the Galileo has disappeared, Sir!"); |
iscraft = 0; |
} |
} |
} |
/* Likewise, if in the original time the Galileo was abandoned, but |
was on ship earlier, it would have vanished -- lets restore it */ |
if (iscraft==0 && gotit==0 && damage[DSHUTTL] >= 0.0) { |
prout("Checkov- \"Security reports the Galileo has reappeared in the dock!\""); |
iscraft = 1; |
} |
/* Revert star chart to earlier era, if it was known then*/ |
if (damage[DRADIO]==0.0 || stdamtim > d.date) { |
for (l = 1; l <= 8; l++) |
for (ll = 1; ll <= 8; ll++) |
if (starch[l][ll] > 1) |
starch[l][ll]=damage[DRADIO]>0.0 ? d.galaxy[l][ll]+1000 :1; |
prout("Spock has reconstructed a correct star chart from memory"); |
if (damage[DRADIO] > 0.0) stdamtim = d.date; |
} |
} |
else { |
/* Go forward in time */ |
Time = -0.5*intime*log(Rand()); |
proutn("You are traveling forward in time "); |
cramf(Time, 1, 2); |
prout(" stardates."); |
/* cheat to make sure no tractor beams occur during time warp */ |
future[FTBEAM] += Time; |
damage[DRADIO] += Time; |
} |
newqad(0); |
} |
void probe(void) { |
double angle, bigger; |
int key; |
/* New code to launch a deep space probe */ |
if (nprobes == 0) { |
chew(); |
skip(1); |
if (ship == IHE) |
prout("Engineer Scott- \"We have no more deep space probes, Sir.\""); |
else |
prout("Ye Faerie Queene has no deep space probes."); |
return; |
} |
if (damage[DDSP] != 0.0) { |
chew(); |
skip(1); |
prout("Engineer Scott- \"The probe launcher is damaged, Sir.\""); |
return; |
} |
if (future[FDSPROB] != 1e30) { |
chew(); |
skip(1); |
if (REPORTS) { |
prout("Uhura- \"The previous probe is still reporting data, Sir.\""); |
} else { |
prout("Spock- \"Records show the previous probe has not yet"); |
prout(" reached its destination.\""); |
} |
return; |
} |
key = scan(); |
if (key == IHEOL) { |
/* slow mode, so let Kirk know how many probes there are left */ |
crami(nprobes,1); |
prout(nprobes==1 ? " probe left." : " probes left."); |
proutn("Are you sure you want to fire a probe? "); |
if (ja()==0) return; |
} |
isarmed = FALSE; |
if (key == IHALPHA && strcmp(citem,"armed") == 0) { |
isarmed = TRUE; |
key = scan(); |
} |
else if (key == IHEOL) { |
proutn("Arm NOVAMAX warhead?"); |
isarmed = ja(); |
} |
getcd(TRUE, key); |
if (direc == -1.0) return; |
nprobes--; |
angle = ((15.0 - direc) * 0.5235988); |
probeinx = -sin(angle); |
probeiny = cos(angle); |
if (fabs(probeinx) > fabs(probeiny)) |
bigger = fabs(probeinx); |
else |
bigger = fabs(probeiny); |
probeiny /= bigger; |
probeinx /= bigger; |
proben = 10.0*dist*bigger +0.5; |
probex = quadx*10 + sectx - 1; // We will use better packing than original |
probey = quady*10 + secty - 1; |
probecx = quadx; |
probecy = quady; |
future[FDSPROB] = d.date + 0.01; // Time to move one sector |
prout("Ensign Chekov- \"The deep space probe is launched, Captain.\""); |
return; |
} |
void help(void) { |
/* There's more than one way to move in this game! */ |
double ddist, xdist, probf; |
int line, l, ix, iy; |
chew(); |
/* Test for conditions which prevent calling for help */ |
if (condit == IHDOCKED) { |
prout("Lt. Uhura- \"But Captain, we're already docked.\""); |
return; |
} |
if (damage[DRADIO] != 0) { |
prout("Subspace radio damaged."); |
return; |
} |
if (d.rembase==0) { |
prout("Lt. Uhura- \"Captain, I'm not getting any response from Starbase.\""); |
return; |
} |
if (landed == 1) { |
proutn("You must be aboard the "); |
crmshp(); |
prout("."); |
return; |
} |
/* OK -- call for help from nearest starbase */ |
nhelp++; |
if (basex!=0) { |
/* There's one in this quadrant */ |
ddist = sqrt(square(basex-sectx)+square(basey-secty)); |
} |
else { |
ddist = 1e30; |
for (l = 1; l <= d.rembase; l++) { |
xdist=10.0*sqrt(square(d.baseqx[l]-quadx)+square(d.baseqy[l]-quady)); |
if (xdist < ddist) { |
ddist = xdist; |
line = l; |
} |
} |
/* Since starbase not in quadrant, set up new quadrant */ |
quadx = d.baseqx[line]; |
quady = d.baseqy[line]; |
newqad(1); |
} |
/* dematerialize starship */ |
quad[sectx][secty]=IHDOT; |
proutn("Starbase in"); |
cramlc(1, quadx, quady); |
proutn(" responds--"); |
crmshp(); |
prout(" dematerializes."); |
/* Give starbase three chances to rematerialize starship */ |
probf = pow((1.0 - pow(0.98,ddist)), 0.33333333); |
for (l = 1; l <= 3; l++) { |
switch (l) { |
case 1: proutn("1st"); break; |
case 2: proutn("2nd"); break; |
case 3: proutn("3rd"); break; |
} |
proutn(" attempt to re-materialize "); |
crmshp(); |
prouts(" . . . . . "); |
if (Rand() > probf) break; |
prout("fails."); |
} |
if (l > 3) { |
finish(FMATERIALIZE); |
return; |
} |
/* Rematerialization attempt should succeed if can get adj to base */ |
for (l = 1; l <= 5; l++) { |
ix = basex+3.0*Rand()-1; |
iy = basey+3.0*Rand()-1; |
if (ix>=1 && ix<=10 && iy>=1 && iy<=10 && quad[ix][iy]==IHDOT) { |
/* found one -- finish up */ |
prout("succeeds."); |
sectx=ix; |
secty=iy; |
quad[ix][iy]=ship; |
dock(); |
skip(1); |
prout("Lt. Uhura- \"Captain, we made it!\""); |
return; |
} |
} |
finish(FMATERIALIZE); |
return; |
} |
/programs/games/sstartrek/en/osx.c |
---|
0,0 → 1,48 |
#include <stdlib.h> |
#include <stdio.h> |
#ifndef KOS32 |
#include <time.h> |
#else |
#include <kos32sys1.h> |
#endif |
#ifndef WINDOWS |
#include <sys/ioctl.h> |
#include <termios.h> |
#include <unistd.h> |
#endif |
void randomize(void) { |
#ifndef KOS32 |
srand((int)time(NULL)); |
#else |
srand(get_tick_count()); |
#endif |
} |
///#ifndef WINDOWS |
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; |
} |
#ifndef WINDOWS |
int // <editor-fold defaultstate="collapsed" desc="comment"> |
getch// </editor-fold> |
(void) { |
char chbuf[1]; |
struct termios oldstate, newstate; |
fflush(stdout); |
tcgetattr(0, &oldstate); |
newstate = oldstate; |
newstate.c_lflag &= ~ICANON; |
newstate.c_lflag &= ~ECHO; |
tcsetattr(0, TCSANOW, &newstate); |
read(0, &chbuf, 1); |
tcsetattr(0, TCSANOW, &oldstate); |
return chbuf[0]; |
} |
#endif |
/programs/games/sstartrek/en/planets.c |
---|
0,0 → 1,505 |
#include "sst.h" |
static char classes[4][2]={"","M","N","O"}; |
static int height; |
static int consumeTime(void) { |
/* I think most of this avoidance was caused by overlay scheme. |
Let's see what happens if all events can occur here */ |
// double asave; |
ididit = 1; |
#if 0 |
/* Don't wory about this */ |
if (future[FTBEAM] <= d.date+Time && d.remcom != 0 && condit != IHDOCKED) { |
/* We are about to be tractor beamed -- operation fails */ |
return 1; |
} |
#endif |
// asave = future[FSNOVA]; |
// future[FSNOVA] = 1e30; /* defer supernovas */ |
events(); /* Used to avoid if future[FSCMOVE] within time */ |
// future[FSNOVA] = asave; |
/*fails if game over, quadrant super-novas or we've moved to new quadrant*/ |
if (alldone || d.galaxy[quadx][quady] == 1000 || justin != 0) return 1; |
return 0; |
} |
void preport(void) { |
int iknow = 0, i; |
skip(1); |
chew(); |
prout("Spock- \"Planet report follows, Captain.\""); |
skip(1); |
for (i = 1; i <= inplan; i++) { |
if (d.plnets[i].known |
#ifdef DEBUG |
|| ( idebug && d.plnets[i].x !=0) |
#endif |
) { |
iknow = 1; |
#ifdef DEBUG |
if (idebug && d.plnets[i].known==0) proutn("(Unknown) "); |
#endif |
cramlc(1, d.plnets[i].x, d.plnets[i].y); |
proutn(" class "); |
proutn(classes[d.plnets[i].pclass]); |
proutn(" "); |
if (d.plnets[i].crystals == 0) proutn("no "); |
prout("dilithium crystals present."); |
if (d.plnets[i].known==2) |
prout(" Shuttle Craft Galileo on surface."); |
} |
} |
if (iknow==0) prout("No information available."); |
} |
void orbit(void) { |
double asave; |
skip(1); |
chew(); |
ididit=0; |
if (inorbit!=0) { |
prout("Already in standard orbit."); |
return; |
} |
if (damage[DWARPEN] != 0 && damage[DIMPULS] != 0) { |
prout("Both warp and impulse engines damaged."); |
return; |
} |
if (plnetx == 0 || abs(sectx-plnetx) > 1 || abs(secty-plnety) > 1) { |
crmshp(); |
prout(" not adjacent to planet.\n"); |
return; |
} |
Time = 0.02+0.03*Rand(); |
prout("Helmsman Sulu- \"Entering standard orbit, Sir.\""); |
newcnd(); |
if (consumeTime()) return; |
proutn("Sulu- \"Entered orbit at altitude "); |
cramf(height = (1400.+7200.*Rand()), 0, 2); |
prout(" kilometers.\""); |
inorbit = 1; |
return; |
} |
void sensor(void) { |
skip(1); |
chew(); |
if (damage[DSRSENS] != 0.0) { |
prout("Short range sensors damaged."); |
return; |
} |
if (plnetx == 0) { |
prout("No planet in this quadrant."); |
return; |
} |
proutn("Spock- \"Sensor scan for"); |
cramlc(1, quadx, quady); |
prout("-"); |
skip(1); |
proutn(" Planet at"); |
cramlc(2, plnetx, plnety); |
proutn(" is of class "); |
proutn(classes[d.plnets[iplnet].pclass]); |
prout("."); |
if (d.plnets[iplnet].known==2) |
prout(" Sensors show Galileo still on surface."); |
proutn(" Readings indicate"); |
if (d.plnets[iplnet].crystals == 0) proutn(" no"); |
prout(" dilithium crystals present.\""); |
if (d.plnets[iplnet].known == 0) d.plnets[iplnet].known = 1; |
return; |
} |
void beam(void) { |
chew(); |
skip(1); |
if (damage[DTRANSP] != 0) { |
prout("Transporter damaged."); |
if (damage[DSHUTTL]==0 && (d.plnets[iplnet].known==2 || iscraft == 1)) { |
skip(1); |
prout("Spock- \"May I suggest the shuttle craft, Sir?\" "); |
if (ja() != 0) shuttle(); |
} |
return; |
} |
if (inorbit==0) { |
crmshp(); |
prout(" not in standard orbit."); |
return; |
} |
if (shldup!=0) { |
prout("Impossible to transport through shields."); |
return; |
} |
if (d.plnets[iplnet].known==0) { |
prout("Spock- \"Captain, we have no information on this planet"); |
prout(" and Starfleet Regulations clearly state that in this situation"); |
prout(" you may not go down.\""); |
return; |
} |
if (landed==1) { |
/* Coming from planet */ |
if (d.plnets[iplnet].known==2) { |
proutn("Spock- \"Wouldn't you rather take the Galileo?\" "); |
if (ja() != 0) { |
chew(); |
return; |
} |
prout("Your crew hides the Galileo to prevent capture by aliens."); |
} |
prout("Landing party assembled, ready to beam up."); |
skip(1); |
prout("Kirk whips out communicator..."); |
prouts("BEEP BEEP BEEP"); |
skip(2); |
prout("\"Kirk to enterprise- Lock on coordinates...energize.\""); |
} |
else { |
/* Going to planet */ |
if (d.plnets[iplnet].crystals==0) { |
prout("Spock- \"Captain, I fail to see the logic in"); |
prout(" exploring a planet with no dilithium crystals."); |
proutn(" Are you sure this is wise?\" "); |
if (ja()==0) { |
chew(); |
return; |
} |
} |
prout("Scotty- \"Transporter room ready, Sir.\""); |
skip(1); |
prout("Kirk, and landing party prepare to beam down to planet surface."); |
skip(1); |
prout("Kirk- \"Energize.\""); |
} |
skip(1); |
prouts("WWHOOOIIIIIRRRRREEEE.E.E. . . . . . ."); |
skip(2); |
if (Rand() > 0.98) { |
prouts("BOOOIIIOOOIIOOOOIIIOIING . . ."); |
skip(2); |
prout("Scotty- \"Oh my God! I've lost them.\""); |
finish(FLOST); |
return; |
} |
prouts(". . . . . . .E.E.EEEERRRRRIIIIIOOOHWW"); |
skip(2); |
prout("Transport complete."); |
landed = -landed; |
if (landed==1 && d.plnets[iplnet].known==2) { |
prout("The shuttle craft Galileo is here!"); |
} |
if (landed!=1 && imine==1) { |
icrystl = 1; |
cryprob = 0.05; |
} |
imine = 0; |
return; |
} |
void mine(void) { |
ididit = 0; |
skip(1); |
chew(); |
if (landed!= 1) { |
prout("Mining party not on planet."); |
return; |
} |
if (d.plnets[iplnet].crystals == 0) { |
prout("No dilithium crystals on this planet."); |
return; |
} |
if (imine == 1) { |
prout("You've already mined enough crystals for this trip."); |
return; |
} |
if (icrystl == 1 && cryprob == 0.05) { |
proutn("With all those fresh crystals aboard the "); |
crmshp(); |
skip(1); |
prout("there's no reason to mine more at this time."); |
return; |
} |
Time = (0.1+0.2*Rand())*d.plnets[iplnet].pclass; |
if (consumeTime()) return; |
prout("Mining operation complete."); |
imine = 1; |
return; |
} |
void usecrystals(void) { |
skip(1); |
chew(); |
if (icrystl!=1) { |
prout("No dilithium crystals available."); |
return; |
} |
if (energy >= 1000) { |
prout("Spock- \"Captain, Starfleet Regulations prohibit such an operation"); |
prout(" except when condition Yellow exists."); |
return; |
} |
prout("Spock- \"Captain, I must warn you that loading"); |
prout(" raw dilithium crystals into the ship's power"); |
prout(" system may risk a severe explosion."); |
proutn(" Are you sure this is wise?\" "); |
if (ja()==0) { |
chew(); |
return; |
} |
skip(1); |
prout("Engineering Officer Scott- \"(GULP) Aye Sir."); |
prout(" Mr. Spock and I will try it.\""); |
skip(1); |
prout("Spock- \"Crystals in place, Sir."); |
prout(" Ready to activate circuit.\""); |
skip(1); |
prouts("Scotty- \"Keep your fingers crossed, Sir!\""); |
skip(1); |
if (Rand() <= cryprob) { |
prouts(" \"Activating now! - - No good! It's***"); |
skip(2); |
prouts("***RED ALERT! RED A*L********************************"); |
skip(1); |
stars(); |
prouts("****************** KA-BOOM!!!! *******************"); |
skip(1); |
kaboom(); |
return; |
} |
energy += 5000.0*(1.0 + 0.9*Rand()); |
prouts(" \"Activating now! - - "); |
prout("The instruments"); |
prout(" are going crazy, but I think it's"); |
prout(" going to work!! Congratulations, Sir!\""); |
cryprob *= 2.0; |
return; |
} |
void shuttle(void) { |
chew(); |
skip(1); |
ididit = 0; |
if(damage[DSHUTTL] != 0.0) { |
if (damage[DSHUTTL] == -1.0) { |
if (inorbit && d.plnets[iplnet].known == 2) |
prout("Ye Faerie Queene has no shuttle craft bay to dock it at."); |
else |
prout("Ye Faerie Queene had no shuttle craft."); |
} |
else if (damage[DSHUTTL] > 0) |
prout("The Galileo is damaged."); |
else prout("Shuttle craft is now serving Big Mac's."); |
return; |
} |
if (inorbit==0) { |
crmshp(); |
prout(" not in standard orbit."); |
return; |
} |
if ((d.plnets[iplnet].known != 2) && iscraft != 1) { |
prout("Shuttle craft not currently available."); |
return; |
} |
if (landed==-1 && d.plnets[iplnet].known==2) { |
prout("You will have to beam down to retrieve the shuttle craft."); |
return; |
} |
if (shldup!=0 || condit == IHDOCKED) { |
prout("Shuttle craft cannot pass through shields."); |
return; |
} |
if (d.plnets[iplnet].known==0) { |
prout("Spock- \"Captain, we have no information on this planet"); |
prout(" and Starfleet Regulations clearly state that in this situation"); |
prout(" you may not fly down.\""); |
return; |
} |
Time = 3.0e-5*height; |
if (Time >= 0.8*d.remtime) { |
prout("First Officer Spock- \"Captain, I compute that such"); |
prout(" a maneuver would require approximately "); |
cramf(100*Time/d.remtime,0,4); |
prout("% of our"); |
prout("remaining time."); |
prout("Are you sure this is wise?\" "); |
if (ja()==0) { |
Time = 0.0; |
return; |
} |
} |
if (landed == 1) { |
/* Kirk on planet */ |
if (iscraft==1) { |
/* Galileo on ship! */ |
if (damage[DTRANSP]==0) { |
proutn("Spock- \"Would you rather use the transporter?\" "); |
if (ja() != 0) { |
beam(); |
return; |
} |
proutn("Shuttle crew"); |
} |
else |
proutn("Rescue party"); |
prout(" boards Galileo and swoops toward planet surface."); |
iscraft = 0; |
skip(1); |
if (consumeTime()) return; |
d.plnets[iplnet].known=2; |
prout("Trip complete."); |
return; |
} |
else { |
/* Ready to go back to ship */ |
prout("You and your mining party board the"); |
prout("shuttle craft for the trip back to the Enterprise."); |
skip(1); |
prout("The short hop begins . . ."); |
d.plnets[iplnet].known=1; |
icraft = 1; |
skip(1); |
landed = -1; |
if (consumeTime()) return; |
iscraft = 1; |
icraft = 0; |
if (imine!=0) { |
icrystl = 1; |
cryprob = 0.05; |
} |
imine = 0; |
prout("Trip complete."); |
return; |
} |
} |
else { |
/* Kirk on ship */ |
/* and so is Galileo */ |
prout("Mining party assembles in the hangar deck,"); |
prout("ready to board the shuttle craft \"Galileo\"."); |
skip(1); |
prouts("The hangar doors open; the trip begins."); |
skip(1); |
icraft = 1; |
iscraft = 0; |
if (consumeTime()) return; |
d.plnets[iplnet].known = 2; |
landed = 1; |
icraft = 0; |
prout("Trip complete"); |
return; |
} |
} |
void deathray(void) { |
double r = Rand(); |
ididit = 0; |
skip(1); |
chew(); |
if (ship != IHE) { |
prout("Ye Faerie Queene has no death ray."); |
return; |
} |
if (nenhere==0) { |
prout("Sulu- \"But Sir, there are no enemies in this quadrant.\""); |
return; |
} |
if (damage[DDRAY] > 0.0) { |
prout("Death Ray is damaged."); |
return; |
} |
prout("Spock- \"Captain, the 'Experimental Death Ray'"); |
prout(" is highly unpredictable. Considering the alternatives,"); |
prout(" are you sure this is wise?\" "); |
if (ja()==0) return; |
prout("Spock- \"Acknowledged.\""); |
skip(1); |
ididit=1; |
prouts("WHOOEE ... WHOOEE ... WHOOEE ... WHOOEE"); |
skip(1); |
prout("Crew scrambles in emergency preparation."); |
prout("Spock and Scotty ready the death ray and"); |
prout("prepare to channel all ship's power to the device."); |
skip(1); |
prout("Spock- \"Preparations complete, sir.\""); |
prout("Kirk- \"Engage!\""); |
skip(1); |
prouts("WHIRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR"); |
skip(1); |
if (r > .30) { |
prouts("Sulu- \"Captain! It's working!\""); |
skip(2); |
while (nenhere > 0) { |
deadkl(kx[1],ky[1],quad[kx[1]][ky[1]],kx[1],ky[1]); |
} |
prout("Ensign Chekov- \"Congratulations, Captain!\""); |
if (d.remkl == 0) finish(FWON); |
prout("Spock- \"Captain, I believe the `Experimental Death Ray'"); |
if (Rand() <= 0.05) { |
prout(" is still operational.\""); |
} |
else { |
prout(" has been rendered dysfunctional.\""); |
damage[DDRAY] = 39.95; |
} |
return; |
} |
r = Rand(); // Pick failure method |
if (r <= .30) { |
prouts("Sulu- \"Captain! It's working!\""); |
skip(1); |
prouts("***RED ALERT! RED ALERT!"); |
skip(1); |
prout("***MATTER-ANTIMATTER IMPLOSION IMMINENT!"); |
skip(1); |
prouts("***RED ALERT! RED A*L********************************"); |
skip(1); |
stars(); |
prouts("****************** KA-BOOM!!!! *******************"); |
skip(1); |
kaboom(); |
return; |
} |
if (r <= .55) { |
prouts("Sulu- \"Captain! Yagabandaghangrapl, brachriigringlanbla!\""); |
skip(1); |
prout("Lt. Uhura- \"Graaeek! Graaeek!\""); |
skip(1); |
prout("Spock- \"Fascinating! . . . All humans aboard"); |
prout(" have apparently been transformed into strange mutations."); |
prout(" Vulcans do not seem to be affected."); |
skip(1); |
prout("Kirk- \"Raauch! Raauch!\""); |
finish(FDRAY); |
return; |
} |
if (r <= 0.75) { |
int i,j; |
prouts("Sulu- \"Captain! It's --WHAT?!?!\""); |
skip(2); |
proutn("Spock- \"I believe the word is"); |
prouts(" *ASTONISHING*"); |
prout(" Mr. Sulu."); |
for (i=1; i<=10; i++) |
for (j=1; j<=10; j++) |
if (quad[i][j] == IHDOT) quad[i][j] = IHQUEST; |
prout(" Captain, our quadrant is now infested with"); |
prouts(" - - - - - - *THINGS*."); |
skip(1); |
prout(" I have no logical explanation.\""); |
return; |
} |
prouts("Sulu- \"Captain! The Death Ray is creating tribbles!\""); |
skip(1); |
prout("Scotty- \"There are so many tribbles down here"); |
prout(" in Engineering, we can't move for 'em, Captain.\""); |
finish(FTRIBBLE); |
return; |
} |
/programs/games/sstartrek/en/reports.c |
---|
0,0 → 1,552 |
#include "sst.h" |
#include <math.h> |
#include <stdlib.h> |
#include <string.h> |
void attakreport(void) { |
if (future[FCDBAS] < 1e30) { |
proutn("Starbase in "); |
cramlc(1, batx, baty); |
prout(" is currently under attack."); |
proutn("It can hold out until Stardate "); |
cramf(future[FCDBAS], 0,1); |
prout("."); |
} |
if (isatb == 1) { |
proutn("Starbase in "); |
cramlc(1, d.isx, d.isy); |
prout(" is under Super-commander attack."); |
proutn("It can hold out until Stardate "); |
cramf(future[FSCDBAS], 0, 1); |
prout("."); |
} |
} |
void report(int f) { |
char *s1,*s2,*s3; |
chew(); |
s1 = (thawed?"thawed ":""); |
switch (length) { |
case 1: s2="short"; break; |
case 2: s2="medium"; break; |
case 4: s2="long"; break; |
default: s2="unknown length"; break; |
} |
switch (skill) { |
case SNOVICE: s3="novice"; break; |
case SFAIR: s3="fair"; break; |
case SGOOD: s3="good"; break; |
case SEXPERT: s3="expert"; break; |
case SEMERITUS: s3="emeritus"; break; |
default: s3="skilled"; break; |
} |
printf("\nYou %s playing a %s%s %s game.\n", |
alldone? "were": "are now", s1, s2, s3); |
if (skill>SGOOD && thawed && !alldone) prout("No plaque is allowed."); |
if (tourn) printf("This is tournament game %d.\n", tourn); |
if (f) printf("Your secret password is \"%s\"\n",passwd); |
printf("%d of %d Klingon ships have been destroyed", |
d.killk+d.killc+d.nsckill, inkling); |
if (d.killc) printf(", including %d Commander%s.\n", d.killc, d.killc==1?"":"s"); |
else if (d.killk+d.nsckill > 0) prout(", but no Commanders."); |
else prout("."); |
if (skill > SFAIR) printf("The Super Commander has %sbeen destroyed.\n", |
d.nscrem?"not ":""); |
if (d.rembase != inbase) { |
proutn("There "); |
if (inbase-d.rembase==1) proutn("has been 1 base"); |
else { |
proutn("have been "); |
crami(inbase-d.rembase, 1); |
proutn(" bases"); |
} |
proutn(" destroyed, "); |
crami(d.rembase, 1); |
prout(" remaining."); |
} |
else printf("There are %d bases.\n", inbase); |
if (REPORTS || iseenit) { |
/* Don't report this if not seen and |
either the radio is dead or not at base! */ |
attakreport(); |
iseenit = 1; |
} |
if (casual) printf("%d casualt%s suffered so far.\n", |
casual, casual==1? "y" : "ies"); |
#ifdef CAPTURE |
if (brigcapacity != brigfree) printf("%d Klingon%s in brig.\n", |
brigcapacity-brigfree, brigcapacity-brigfree>1 ? "s" : ""); |
if (kcaptured > 0) printf("%d captured Klingon%s turned in to Star Fleet.\n", |
kcaptured, kcaptured>1 ? "s" : ""); |
#endif |
if (nhelp) printf("There were %d call%s for help.\n", |
nhelp, nhelp==1 ? "" : "s"); |
if (ship == IHE) { |
proutn("You have "); |
if (nprobes) crami(nprobes,1); |
else proutn("no"); |
proutn(" deep space probe"); |
if (nprobes!=1) proutn("s"); |
prout("."); |
} |
if (REPORTS && future[FDSPROB] != 1e30) { |
if (isarmed) |
proutn("An armed deep space probe is in"); |
else |
proutn("A deep space probe is in"); |
cramlc(1, probecx, probecy); |
prout("."); |
} |
if (icrystl) { |
if (cryprob <= .05) |
prout("Dilithium crystals aboard ship...not yet used."); |
else { |
int i=0; |
double ai = 0.05; |
while (cryprob > ai) { |
ai *= 2.0; |
i++; |
} |
printf("Dilithium crystals have been used %d time%s.\n", |
i, i==1? "" : "s"); |
} |
} |
skip(1); |
} |
void lrscan(void) { |
int x, y; |
chew(); |
if (damage[DLRSENS] != 0.0) { |
/* Now allow base's sensors if docked */ |
if (condit != IHDOCKED) { |
prout("LONG-RANGE SENSORS DAMAGED."); |
return; |
} |
skip(1); |
proutn("Starbase's long-range scan for"); |
} |
else { |
skip(1); |
proutn("Long-range scan for"); |
} |
cramlc(1, quadx, quady); |
skip(1); |
if (coordfixed) |
for (y = quady+1; y >= quady-1; y--) { |
for (x = quadx-1; x <= quadx+1; x++) { |
if (x == 0 || x > 8 || y == 0 || y > 8) |
printf(" -1"); |
else { |
printf("%5d", d.galaxy[x][y]); |
// If radio works, mark star chart so |
// it will show current information. |
// Otherwise mark with current |
// value which is fixed. |
starch[x][y] = damage[DRADIO] > 0 ? d.galaxy[x][y]+1000 :1; |
} |
} |
putchar('\n'); |
} |
else |
for (x = quadx-1; x <= quadx+1; x++) { |
for (y = quady-1; y <= quady+1; y++) { |
if (x == 0 || x > 8 || y == 0 || y > 8) |
printf(" -1"); |
else { |
printf("%5d", d.galaxy[x][y]); |
// If radio works, mark star chart so |
// it will show current information. |
// Otherwise mark with current |
// value which is fixed. |
starch[x][y] = damage[DRADIO] > 0 ? d.galaxy[x][y]+1000 :1; |
} |
} |
putchar('\n'); |
} |
} |
void dreprt(void) { |
int jdam = FALSE, i; |
chew(); |
for (i = 1; i <= ndevice; i++) { |
if (damage[i] > 0.0) { |
if (!jdam) { |
skip(1); |
prout("DEVICE -REPAIR TIMES-"); |
prout(" IN FLIGHT DOCKED"); |
jdam = TRUE; |
} |
printf(" %16s ", device[i]); |
cramf(damage[i]+0.05, 8, 2); |
proutn(" "); |
cramf(docfac*damage[i]+0.005, 8, 2); |
skip(1); |
} |
} |
if (!jdam) prout("All devices functional."); |
} |
void chart(int nn) { |
int i,j; |
chew(); |
skip(1); |
if (stdamtim != 1e30 && stdamtim != d.date && condit == IHDOCKED) { |
prout("Spock- \"I revised the Star Chart from the"); |
prout(" starbase's records.\""); |
skip(1); |
} |
if (nn == 0) prout("STAR CHART FOR THE KNOWN GALAXY"); |
if (stdamtim != 1e30) { |
if (condit == IHDOCKED) { |
/* We are docked, so restore chart from base information -- these values won't update! */ |
stdamtim = d.date; |
for (i=1; i <= 8 ; i++) |
for (j=1; j <= 8; j++) |
if (starch[i][j] == 1) starch[i][j] = d.galaxy[i][j]+1000; |
} |
else { |
proutn("(Last surveillance update "); |
cramf(d.date-stdamtim, 0, 1); |
prout(" stardates ago.)"); |
} |
} |
if (nn ==0) skip(1); |
prout(" 1 2 3 4 5 6 7 8"); |
prout(" ----------------------------------------"); |
if (nn==0) prout(" -"); |
if (coordfixed) |
for (j = 8; j >= 1; j--) { |
printf("%d -", j); |
for (i = 1; i <= 8; i++) { |
if (starch[i][j] < 0) // We know only about the bases |
printf(" .1."); |
else if (starch[i][j] == 0) // Unknown |
printf(" ..."); |
else if (starch[i][j] > 999) // Memorized value |
printf("%5d", starch[i][j]-1000); |
else |
printf("%5d", d.galaxy[i][j]); // What is actually there (happens when value is 1) |
} |
prout(" -"); |
} |
else |
for (i = 1; i <= 8; i++) { |
printf("%d -", i); |
for (j = 1; j <= 8; j++) { |
if (starch[i][j] < 0) // We know only about the bases |
printf(" .1."); |
else if (starch[i][j] == 0) // Unknown |
printf(" ..."); |
else if (starch[i][j] > 999) // Memorized value |
printf("%5d", starch[i][j]-1000); |
else |
printf("%5d", d.galaxy[i][j]); // What is actually there (happens when value is 1) |
} |
prout(" -"); |
} |
if (nn == 0) { |
skip(1); |
crmshp(); |
proutn(" is currently in"); |
cramlc(1, quadx, quady); |
skip(1); |
} |
} |
void srscan(int l) { |
static char requests[][3] = |
{"","da","co","po","ls","wa","en","to","sh","kl","ti"}; |
char *cp; |
int leftside=TRUE, rightside=TRUE, i, j, jj, k=0, nn=FALSE; |
int goodScan=TRUE; |
switch (l) { |
case 1: // SRSCAN |
if (damage[DSRSENS] != 0) { |
/* Allow base's sensors if docked */ |
if (condit != IHDOCKED) { |
prout("SHORT-RANGE SENSORS DAMAGED"); |
goodScan=FALSE; |
} |
else |
prout("[Using starbase's sensors]"); |
} |
if (goodScan) |
starch[quadx][quady] = damage[DRADIO]>0.0 ? |
d.galaxy[quadx][quady]+1000:1; |
scan(); |
if (isit("chart")) nn = TRUE; |
if (isit("no")) rightside = FALSE; |
chew(); |
prout("\n 1 2 3 4 5 6 7 8 9 10"); |
break; |
case 2: // REQUEST |
while (scan() == IHEOL) |
printf("Information desired? "); |
chew(); |
for (k = 1; k <= 10; k++) |
if (strncmp(citem,requests[k],min(2,strlen(citem)))==0) |
break; |
if (k > 10) { |
prout("UNRECOGNIZED REQUEST. Legal requests are:\n" |
" date, condition, position, lsupport, warpfactor,\n" |
" energy, torpedoes, shields, klingons, time."); |
return; |
} |
// no "break" |
case 3: // STATUS |
chew(); |
leftside = FALSE; |
skip(1); |
} |
for (i = 1; i <= 10; i++) { |
int jj = (k!=0 ? k : i); |
if (leftside) { |
if (coordfixed) { |
printf("%2d ", 11-i); |
for (j = 1; j <= 10; j++) { |
if (goodScan || (abs((11-i)-secty)<= 1 && abs(j-sectx) <= 1)) |
printf("%c ",quad[j][11-i]); |
else |
printf("- "); |
} |
} else { |
printf("%2d ", i); |
for (j = 1; j <= 10; j++) { |
if (goodScan || (abs(i-sectx)<= 1 && abs(j-secty) <= 1)) |
printf("%c ",quad[i][j]); |
else |
printf("- "); |
} |
} |
} |
if (rightside) { |
switch (jj) { |
case 1: |
printf(" Stardate %.1f", d.date); |
break; |
case 2: |
if (condit != IHDOCKED) newcnd(); |
switch (condit) { |
case IHRED: cp = "RED"; break; |
case IHGREEN: cp = "GREEN"; break; |
case IHYELLOW: cp = "YELLOW"; break; |
case IHDOCKED: cp = "DOCKED"; break; |
} |
printf(" Condition %s", cp); |
#ifdef CLOAKING |
if (iscloaked) printf(", CLOAKED"); |
#endif |
break; |
case 3: |
printf(" Position "); |
cramlc(0, quadx, quady); |
putchar(','); |
cramlc(0, sectx, secty); |
break; |
case 4: |
printf(" Life Support "); |
if (damage[DLIFSUP] != 0.0) { |
if (condit == IHDOCKED) |
printf("DAMAGED, supported by starbase"); |
else |
printf("DAMAGED, reserves=%4.2f", lsupres); |
} |
else |
printf("ACTIVE"); |
break; |
case 5: |
printf(" Warp Factor %.1f", warpfac); |
break; |
case 6: |
printf(" Energy %.2f", energy); |
break; |
case 7: |
printf(" Torpedoes %d", torps); |
break; |
case 8: |
printf(" Shields "); |
if (damage[DSHIELD] != 0) |
printf("DAMAGED,"); |
else if (shldup) |
printf("UP,"); |
else |
printf("DOWN,"); |
printf(" %d%% %.1f units", |
(int)((100.0*shield)/inshld + 0.5), shield); |
break; |
case 9: |
printf(" Klingons Left %d", d.remkl); |
break; |
case 10: |
printf(" Time Left %.2f", d.remtime); |
break; |
} |
} |
skip(1); |
if (k!=0) return; |
} |
if (nn) chart(1); |
} |
void eta(void) { |
int key, ix1, ix2, iy1, iy2, prompt=FALSE; |
int wfl; |
double ttime, twarp, tpower; |
if (damage[DCOMPTR] != 0.0) { |
prout("COMPUTER DAMAGED, USE A POCKET CALCULATOR."); |
skip(1); |
return; |
} |
if (scan() != IHREAL) { |
prompt = TRUE; |
chew(); |
proutn("Destination quadrant and/or sector? "); |
if (scan()!=IHREAL) { |
huh(); |
return; |
} |
} |
iy1 = aaitem +0.5; |
if (scan() != IHREAL) { |
huh(); |
return; |
} |
ix1 = aaitem + 0.5; |
if (scan() == IHREAL) { |
iy2 = aaitem + 0.5; |
if (scan() != IHREAL) { |
huh(); |
return; |
} |
ix2 = aaitem + 0.5; |
} |
else { // same quadrant |
ix2 = ix1; |
iy2 = iy1; |
ix1 = quady; // ya got me why x and y are reversed! |
iy1 = quadx; |
} |
if (ix1 > 8 || ix1 < 1 || iy1 > 8 || iy1 < 1 || |
ix2 > 10 || ix2 < 1 || iy2 > 10 || iy2 < 1) { |
huh(); |
return; |
} |
dist = sqrt(square(iy1-quadx+0.1*(iy2-sectx))+ |
square(ix1-quady+0.1*(ix2-secty))); |
wfl = FALSE; |
if (prompt) prout("Answer \"no\" if you don't know the value:"); |
while (TRUE) { |
chew(); |
proutn("Time or arrival date? "); |
if (scan()==IHREAL) { |
ttime = aaitem; |
if (ttime > d.date) ttime -= d.date; // Actually a star date |
if (ttime <= 1e-10 || |
(twarp=(floor(sqrt((10.0*dist)/ttime)*10.0)+1.0)/10.0) > 10) { |
prout("We'll never make it, sir."); |
chew(); |
return; |
} |
if (twarp < 1.0) twarp = 1.0; |
break; |
} |
chew(); |
proutn("Warp factor? "); |
if (scan()== IHREAL) { |
wfl = TRUE; |
twarp = aaitem; |
if (twarp<1.0 || twarp > 10.0) { |
huh(); |
return; |
} |
break; |
} |
prout("Captain, certainly you can give me one of these."); |
} |
while (TRUE) { |
chew(); |
ttime = (10.0*dist)/square(twarp); |
tpower = dist*twarp*twarp*twarp*(shldup+1); |
if (tpower >= energy) { // Suggestion from Ethan Staffin -- give amount needed |
prout("Insufficient energy, sir: we would need "); |
cramf(tpower, 1, 1); |
proutn (" units."); |
if (shldup==0 || tpower > energy*2.0) { |
if (!wfl) return; |
proutn("New warp factor to try? "); |
if (scan() == IHREAL) { |
wfl = TRUE; |
twarp = aaitem; |
if (twarp<1.0 || twarp > 10.0) { |
huh(); |
return; |
} |
continue; |
} |
else { |
chew(); |
skip(1); |
return; |
} |
} |
prout("But if you lower your shields,"); |
proutn("remaining"); |
tpower /= 2; |
} |
else |
proutn("Remaining"); |
proutn(" energy will be "); |
cramf(energy-tpower, 1, 1); |
prout("."); |
if (wfl) { |
proutn("And we will arrive at stardate "); |
cramf(d.date+ttime, 1, 1); |
prout("."); |
} |
else if (twarp==1.0) |
prout("Any warp speed is adequate."); |
else { |
proutn("Minimum warp needed is "); |
cramf(twarp, 1, 2); |
skip(1); |
proutn("and we will arrive at stardate "); |
cramf(d.date+ttime, 1, 2); |
prout("."); |
} |
if (d.remtime < ttime) |
prout("Unfortunately, the Federation will be destroyed by then."); |
if (twarp > 6.0) |
prout("You'll be taking risks at that speed, Captain"); |
if ((isatb==1 && d.isy == ix1 && d.isx == iy1 && |
future[FSCDBAS]< ttime+d.date)|| |
(future[FCDBAS]<ttime+d.date && baty==ix1 && batx == iy1)) |
prout("The starbase there will be destroyed by then."); |
proutn("New warp factor to try? "); |
if (scan() == IHREAL) { |
wfl = TRUE; |
twarp = aaitem; |
if (twarp<1.0 || twarp > 10.0) { |
huh(); |
return; |
} |
} |
else { |
chew(); |
skip(1); |
return; |
} |
} |
} |
/programs/games/sstartrek/en/setup.c |
---|
0,0 → 1,725 |
#ifndef KOS32 |
#include <time.h> |
#endif |
#include "sst.h" |
void prelim(void) { |
skip(2); |
prout("-SUPER- STAR TREK"); |
skip(1); |
prout("Latest update-21 Sept 78"); |
skip(1); |
} |
void freeze(int boss) { |
char *x, *y; |
FILE *fp; |
int key; |
if (boss) { |
strcpy(citem, "emsave.trk"); |
} |
else { |
if ((key = scan()) == IHEOL) { |
proutn("File name(9 characters maximum): "); |
key = scan(); |
} |
if (key != IHALPHA) { |
huh(); |
return; |
} |
chew(); |
if (strchr(citem, '.') == NULL) { |
strcat(citem, ".trk"); |
} |
} |
if ((fp = fopen(citem, "wb")) == NULL) { |
proutn("Can't freeze game as file "); |
proutn(citem); |
skip(1); |
return; |
} |
fwrite(&d, sizeof(d), 1, fp); |
fwrite(&snapsht, sizeof(snapsht), 1, fp); |
fwrite(quad, sizeof(quad), 1, fp); |
fwrite(kx, sizeof(kx), 1, fp); |
fwrite(ky, sizeof(ky), 1, fp); |
fwrite(starch, sizeof(starch), 1, fp); |
fwrite(kpower, sizeof(kpower), 1, fp); |
fwrite(kdist, sizeof(kdist), 1, fp); |
fwrite(kavgd, sizeof(kavgd), 1, fp); |
fwrite(damage, sizeof(damage), 1, fp); |
fwrite(future, sizeof(future), 1, fp); |
fwrite(&a, sizeof(a), 1, fp); |
fwrite(passwd, sizeof(passwd), 1, fp); |
fclose(fp); |
/* I hope that's enough! */ |
} |
void thaw(void) { |
char *x, *y; |
FILE *fp; |
int key; |
passwd[0] = '\0'; |
if ((key = scan()) == IHEOL) { |
proutn("File name: "); |
key = scan(); |
} |
if (key != IHALPHA) { |
huh(); |
return; |
} |
chew(); |
if (strchr(citem, '.') == NULL) { |
strcat(citem, ".trk"); |
} |
if ((fp = fopen(citem, "rb")) == NULL) { |
proutn("Can't find game file "); |
proutn(citem); |
skip(1); |
return; |
} |
fread(&d, sizeof(d), 1, fp); |
fread(&snapsht, sizeof(snapsht), 1, fp); |
fread(quad, sizeof(quad), 1, fp); |
fread(kx, sizeof(kx), 1, fp); |
fread(ky, sizeof(ky), 1, fp); |
fread(starch, sizeof(starch), 1, fp); |
fread(kpower, sizeof(kpower), 1, fp); |
fread(kdist, sizeof(kdist), 1, fp); |
fread(kavgd, sizeof(kavgd), 1, fp); |
fread(damage, sizeof(damage), 1, fp); |
fread(future, sizeof(future), 1, fp); |
fread(&a, sizeof(a), 1, fp); |
fread(passwd, sizeof(passwd), 1, fp); |
fclose(fp); |
/* I hope that's enough! */ |
} |
void abandn(void) { |
int nb, l; |
chew(); |
if (condit==IHDOCKED) { |
if (ship!=IHE) { |
prout("You cannot abandon Ye Faerie Queene."); |
return; |
} |
} |
else { |
/* Must take shuttle craft to exit */ |
if (damage[DSHUTTL]==-1) { |
prout("Ye Faerie Queene has no shuttle craft."); |
return; |
} |
if (damage[DSHUTTL]<0) { |
prout("Shuttle craft now serving Big Mac's."); |
return; |
} |
if (damage[DSHUTTL]>0) { |
prout("Shuttle craft damaged."); |
return; |
} |
if (landed==1) { |
prout("You must be aboard the Enterprise."); |
return; |
} |
if (iscraft!=1) { |
prout("Shuttle craft not currently available."); |
return; |
} |
/* Print abandon ship messages */ |
skip(1); |
prouts("***ABANDON SHIP! ABANDON SHIP!"); |
skip(1); |
prouts("***ALL HANDS ABANDON SHIP!"); |
skip(2); |
prout("Captain and crew escape in shuttle craft."); |
prout("Remainder of ship's complement beam down"); |
prout("to nearest habitable planet."); |
if (d.rembase==0) { |
/* Ops! no place to go... */ |
finish(FABANDN); |
return; |
} |
/* If at least one base left, give 'em the Faerie Queene */ |
skip(1); |
icrystl = 0; /* crystals are lost */ |
nprobes = 0; /* No probes */ |
prout("You are captured by Klingons and released to"); |
prout("the Federation in a prisoner-of-war exchange."); |
nb = Rand()*d.rembase+1; |
/* Set up quadrant and position FQ adjacient to base */ |
if (quadx!=d.baseqx[nb] || quady!=d.baseqy[nb]) { |
quadx = d.baseqx[nb]; |
quady = d.baseqy[nb]; |
sectx = secty = 5; |
newqad(1); |
} |
for (;;) { |
/* position next to base by trial and error */ |
quad[sectx][secty] = IHDOT; |
for (l = 1; l <= 10; l++) { |
sectx = 3.0*Rand() - 1.0 + basex; |
secty = 3.0*Rand() - 1.0 + basey; |
if (sectx >= 1 && sectx <= 10 && |
secty >= 1 && secty <= 10 && |
quad[sectx][secty] == IHDOT) break; |
} |
if (l < 11) break; /* found a spot */ |
sectx=5; |
secty=5; |
newqad(1); |
} |
} |
/* Get new commission */ |
quad[sectx][secty] = ship = IHF; |
prout("Starfleet puts you in command of another ship,"); |
prout("the Faerie Queene, which is antiquated but,"); |
prout("still useable."); |
if (icrystl!=0) prout("The dilithium crystals have been moved."); |
imine=0; |
iscraft=0; /* Gallileo disappears */ |
#ifdef CAPTURE |
brigcapacity = 300; // Less capacity now |
brigfree = brigcapacity; |
#endif |
#ifdef CLOAKING |
iscloaked = iscloaking = FALSE; |
#endif |
/* Resupply ship */ |
condit=IHDOCKED; |
for (l = 1; l <= ndevice; l++) damage[l] = 0.0; |
damage[DSHUTTL] = -1; |
energy = inenrg = 3000.0; |
shield = inshld = 1250.0; |
torps = intorps = 6; |
lsupres=inlsr=3.0; |
shldup=0; |
warpfac=5.0; |
wfacsq=25.0; |
return; |
} |
void setup(void) { |
int i,j, krem, klumper; |
int ix, iy; |
alldone = gamewon = 0; |
#ifdef DEBUG |
idebug = 0; |
#endif |
// Decide how many of everything |
if (choose()) return; // frozen game |
// Prepare the Enterprise |
ship = IHE; |
energy = inenrg = 5000.0; |
shield = inshld = 2500.0; |
shldchg = shldup = 0; |
inlsr = 4.0; |
lsupres = 4.0; |
iran8(&quadx, &quady); |
iran10(§x, §y); |
torps = intorps = 10; |
nprobes = (int)(3.0*Rand() + 2.0); /* Give them 2-4 of these wonders */ |
warpfac = 5.0; |
wfacsq = warpfac * warpfac; |
for (i=0; i <= ndevice; i++) damage[i] = 0.0; |
// Set up assorted game parameters |
batx = baty = 0; |
d.date = indate = 100.0*(int)(31.0*Rand()+20.0); |
d.killk = d.killc = nkinks = nhelp = resting = casual = d.nromkl = 0; |
// Added d.starkl=0 6/2015 |
isatb = iscate = imine = icrystl = icraft = d.nsckill = d.nplankl = d.starkl = 0; |
iscraft = 1; |
landed = -1; |
alive = 1; |
docfac = 0.25; |
for (i = 1; i <= 8; i++) |
for (j = 1; j <= 8; j++) d.newstuf[i][j] = starch[i][j] = 0; |
// Initialize times for extraneous events |
future[FSNOVA] = d.date + expran(0.5 * intime); |
future[FTBEAM] = d.date + expran(1.5 * (intime / d.remcom)); |
future[FSNAP] = d.date + 1.0 + Rand(); // Force an early snapshot |
future[FBATTAK] = d.date + expran(0.3*intime); |
future[FCDBAS] = 1e30; |
future[FSCMOVE] = d.nscrem ? d.date+0.2777 : 1e30; |
future[FSCDBAS] = 1e30; |
future[FDSPROB] = 1e30; |
// Starchart is functional |
stdamtim = 1e30; |
// Put stars in the galaxy |
instar = 0; |
for (i=1; i<=8; i++) |
for (j=1; j<=8; j++) { |
int k = Rand()*9.0 + 1.0; |
instar += k; |
d.galaxy[i][j] = k; |
} |
// Locate star bases in galaxy |
for (i = 1; i <= inbase; i++) { |
int contflag; |
do { |
do iran8(&ix, &iy); |
while (d.galaxy[ix][iy] >= 10); |
contflag = FALSE; |
for (j = i-1; j > 0; j--) { |
/* Improved placement algorithm to spread out bases */ |
double distq = square(ix-d.baseqx[j]) + square(iy-d.baseqy[j]); |
if (distq < 6.0*(6-inbase) && Rand() < 0.75) { |
contflag = TRUE; |
#ifdef DEBUG |
printf("DEBUG: Abandoning base #%d at %d-%d\n", i, ix, iy); |
#endif |
break; |
} |
#ifdef DEBUG |
else if (distq < 6.0 * (6-inbase)) { |
printf("DEBUG: saving base #%d, close to #%d\n", i, j); |
} |
#endif |
} |
} while (contflag); |
d.baseqx[i] = ix; |
d.baseqy[i] = iy; |
starch[ix][iy] = -1; |
d.galaxy[ix][iy] += 10; |
} |
// Position ordinary Klingon Battle Cruisers |
krem = inkling - incom - d.nscrem; |
klumper = 0.25*skill*(9.0-length)+1.0; |
if (klumper > 9) klumper = 9; // Can't have more than 9 in quadrant |
do { |
double r = Rand(); |
int klump = (1.0 - r*r)*klumper; |
if (klump > krem) klump = krem; |
krem -= klump; |
klump *= 100; |
do iran8(&ix, &iy); |
while (d.galaxy[ix][iy] + klump >= 1000); |
d.galaxy[ix][iy] += klump; |
} while (krem > 0); |
// Position Klingon Commander Ships |
#ifdef DEBUG |
klumper = 1; |
#endif |
for (i = 1; i <= incom; i++) { |
do { |
do { /* IF debugging, put commanders by bases, always! */ |
#ifdef DEBUG |
if (idebug && klumper <= inbase) { |
ix = d.baseqx[klumper]; |
iy = d.baseqy[klumper]; |
klumper++; |
} |
else |
#endif |
iran8(&ix, &iy); |
} |
while ((d.galaxy[ix][iy] < 99 && Rand() < 0.75)|| |
d.galaxy[ix][iy]>899); |
// check for duplicate |
for (j = 1; j < i; j++) |
if (d.cx[j]==ix && d.cy[j]==iy) break; |
} while (j < i); |
d.galaxy[ix][iy] += 100; |
d.cx[i] = ix; |
d.cy[i] = iy; |
} |
// Locate planets in galaxy |
for (i = 1; i <= inplan; i++) { |
do iran8(&ix, &iy); |
while (d.newstuf[ix][iy] > 0); |
d.newstuf[ix][iy] = 1; |
d.plnets[i].x = ix; |
d.plnets[i].y = iy; |
d.plnets[i].pclass = Rand()*3.0 + 1.0; // Planet class M N or O |
d.plnets[i].crystals = 1.5*Rand(); // 1 in 3 chance of crystals |
d.plnets[i].known = 0; |
} |
// Locate Romulans |
for (i = 1; i <= d.nromrem; i++) { |
iran8(&ix, &iy); |
d.newstuf[ix][iy] += 10; |
} |
// Locate the Super Commander |
if (d.nscrem > 0) { |
do iran8(&ix, &iy); |
while (d.galaxy[ix][iy] >= 900); |
d.isx = ix; |
d.isy = iy; |
d.galaxy[ix][iy] += 100; |
} |
// Place thing (in tournament game, thingx == -1, don't want one!) |
if (Rand() < 0.1 && thingx != -1) { |
iran8(&thingx, &thingy); |
} |
else { |
thingx = thingy = 0; |
} |
// idate = date; |
skip(3); |
d.snap = 0; |
if (skill == SNOVICE) { |
printf("It is stardate %d. The Federation is being attacked by\n", |
(int)d.date); |
printf("a deadly Klingon invasion force. As captain of the United\n" |
"Starship U.S.S. Enterprise, it is your mission to seek out\n" |
"and destroy this invasion force of %d battle cruisers.\n", |
inkling); |
printf("You have an initial allotment of %d stardates to complete\n" |
"your mission. As you proceed you may be given more time.\n\n" |
"You will have %d supporting starbases.\n" |
"Starbase locations- ", |
(int)intime, inbase); |
} |
else { |
printf("Stardate %d.\n\n" |
"%d Klingons,\nan unknown number of Romulans\n", |
(int)d.date, inkling); |
if (d.nscrem) printf("and one (GULP) Super-Commander.\n"); |
printf("%d stardates\n%d starbases in ",(int)intime, inbase); |
} |
for (i = 1; i <= inbase; i++) { |
cramlc(0, d.baseqx[i], d.baseqy[i]); |
if (i < inbase) proutn(" "); |
} |
skip(2); |
proutn("The Enterprise is currently in"); |
cramlc(1, quadx, quady); |
proutn(" "); |
cramlc(2, sectx, secty); |
skip(2); |
prout("Good Luck!"); |
if (d.nscrem) proutn(" YOU'LL NEED IT."); |
skip(1); |
newqad(0); |
if (nenhere) shldup=1.0; |
if (neutz) attack(0); // bad luck to start in a Romulan Neutral Zone |
} |
int choose(void) { |
tourn = 0; |
thawed = 0; |
skill = 0; |
length = 0; |
while (TRUE) { |
if (fromcommandline) /* Can start with command line options */ |
fromcommandline = 0; |
else |
proutn("Would you like a regular, tournament, or frozen game?"); |
scan(); |
if (strlen(citem)==0) continue; // Try again |
if (isit("tournament")) { |
while (scan() == IHEOL) { |
proutn("Type in tournament number-"); |
} |
if (aaitem == 0) { |
chew(); |
continue; // We don't want a blank entry |
} |
tourn = (int)aaitem; |
thingx = -1; |
srand((unsigned int)(int)aaitem); |
break; |
} |
if (isit("frozen")) { |
thaw(); |
chew(); |
if (*passwd==0) continue; |
randomize(); |
Rand(); Rand(); Rand(); Rand(); |
if (!alldone) thawed = 1; // No plaque if not finished |
report(1); |
return TRUE; |
} |
if (isit("regular")) { |
skip(2); |
randomize(); |
Rand(); Rand(); Rand(); Rand(); |
break; |
} |
proutn("What is \""); |
proutn(citem); |
prout("\"?"); |
chew(); |
} |
while (length==0 || skill==0) { |
if (scan() == IHALPHA) { |
if (isit("short")) length = 1; |
else if (isit("medium")) length = 2; |
else if (isit("long")) length = 4; |
else if (isit("novice")) skill = SNOVICE; |
else if (isit("fair")) skill = SFAIR; |
else if (isit("good")) skill = SGOOD; |
else if (isit("expert")) skill = SEXPERT; |
else if (isit("emeritus")) skill = SEMERITUS; |
else { |
proutn("What is \""); |
proutn(citem); |
prout("\"?"); |
} |
} |
else { |
chew(); |
if (length==0) proutn("Would you like a Short, Medium, or Long game? "); |
else if (skill == 0) proutn("Are you a Novice, Fair, Good, Expert, or Emeritus player?"); |
} |
} |
while (TRUE) { |
scan(); |
strcpy(passwd, citem); |
chew(); |
if (*passwd != 0) break; |
proutn("Please type in a secret password (9 characters maximum)-"); |
} |
#ifdef DEBUG |
if (strcmp(passwd, "debug")==0) idebug = 1; |
#endif |
// Use parameters to generate initial values of things |
damfac = 0.5 * skill; |
d.rembase = 3.0*Rand()+2.0; |
inbase = d.rembase; |
inplan = (PLNETMAX/2) + (PLNETMAX/2+1)*Rand(); |
d.nromrem = (2.0+Rand())*skill; |
d.nscrem = (skill > SFAIR? 1 : 0); |
d.remtime = 7.0 * length; |
intime = d.remtime; |
d.remkl = 2.0*intime*((skill+1 - 2*Rand())*skill*0.1+.15); // d.remkl and inkling includes commanders and SC |
inkling = d.remkl; |
incom = skill + 0.0625*inkling*Rand(); |
d.remcom= min(10, incom); |
incom = d.remcom; |
d.remres = (inkling+4*incom)*intime; |
inresor = d.remres; |
if (inkling > 50) { |
inbase = (d.rembase += 1); |
} |
#ifdef CAPTURE |
brigcapacity = 400; |
brigfree = brigcapacity; |
kcaptured = 0; // TAA fix 6/2015 |
#endif |
#ifdef CLOAKING |
ncviol = 0; // TAA fix 6/2015 |
iscloaked = FALSE; |
iscloaking = FALSE; |
#endif |
return FALSE; |
} |
void dropin(int iquad, int *ix, int *iy) { |
do iran10(ix, iy); |
while (quad[*ix][*iy] != IHDOT); |
quad[*ix][*iy] = iquad; |
} |
void newcnd(void) { |
condit = IHGREEN; |
if (energy < 1000.0) condit = IHYELLOW; |
if (d.galaxy[quadx][quady] > 99 || d.newstuf[quadx][quady] > 9) |
condit = IHRED; |
} |
void newqad(int shutup) { |
int quadnum = d.galaxy[quadx][quady]; |
int newnum = d.newstuf[quadx][quady]; |
int i, j, ix, iy, nplan; |
iattak = 1; |
justin = 1; |
basex = basey = 0; |
klhere = 0; |
comhere = 0; |
plnetx = plnety = 0; |
ishere = 0; |
irhere = 0; |
iplnet = 0; |
nenhere = 0; |
neutz = 0; |
inorbit = 0; |
landed = -1; |
ientesc = 0; |
ithere = 0; |
iseenit = 0; |
#ifdef CLOAKING |
isviolreported = FALSE; |
#endif |
if (iscate) { |
// Attempt to escape Super-commander, so tbeam back! |
iscate = 0; |
ientesc = 1; |
} |
// Clear quadrant |
for (i=1; i <= 10; i++) |
for (j=1; j <= 10; j++) quad[i][j] = IHDOT; |
// cope with supernova |
if (quadnum > 999) { |
return; |
} |
klhere = quadnum/100; |
irhere = newnum/10; |
nplan = newnum%10; |
nenhere = klhere + irhere; |
// Position Starship |
quad[sectx][secty] = ship; |
// Decide if quadrant needs a Tholian |
if ((skill < SGOOD && Rand() <= 0.02) || /* Lighten up if skill is low */ |
(skill == SGOOD && Rand() <= 0.05) || |
(skill > SGOOD && Rand() <= 0.08) |
#ifdef DEBUG |
|| strcmp(passwd, "tholianx")==0 |
#endif |
) { |
do { |
ithx = Rand() > 0.5 ? 10 : 1; |
ithy = Rand() > 0.5 ? 10 : 1; |
} while (quad[ithx][ithy] != IHDOT); |
quad[ithx][ithy] = IHT; |
ithere = 1; |
/* Reserve unocupied corners */ |
if (quad[1][1]==IHDOT) quad[1][1] = 'X'; |
if (quad[1][10]==IHDOT) quad[1][10] = 'X'; |
if (quad[10][1]==IHDOT) quad[10][1] = 'X'; |
if (quad[10][10]==IHDOT) quad[10][10] = 'X'; |
} |
if (quadnum >= 100) { |
// Position ordinary Klingons |
quadnum -= 100*klhere; |
for (i = 1; i <= klhere; i++) { |
dropin(IHK, &ix, &iy); |
kx[i] = ix; |
ky[i] = iy; |
kdist[i] = kavgd[i] = sqrt(square(sectx-ix) + square(secty-iy)); |
kpower[i] = Rand()*150.0 +300.0 +25.0*skill; |
} |
// If we need a commander, promote a Klingon |
for (i = 1; i <= d.remcom ; i++) |
if (d.cx[i]==quadx && d.cy[i]==quady) break; |
if (i <= d.remcom) { |
quad[ix][iy] = IHC; |
kpower[klhere] = 950.0+400.0*Rand()+50.0*skill; |
comhere = 1; |
} |
// If we need a super-commander, promote a Klingon |
if (quadx == d.isx && quady == d.isy) { |
quad[kx[1]][ky[1]] = IHS; |
kpower[1] = 1175.0 + 400.0*Rand() + 125.0*skill; |
iscate = 1; |
ishere = 1; |
} |
} |
// Put in Romulans if needed |
for (i = klhere+1; i <= nenhere; i++) { |
dropin(IHR, &ix, &iy); |
kx[i] = ix; |
ky[i] = iy; |
kdist[i] = kavgd[i] = sqrt(square(sectx-ix) + square(secty-iy)); |
kpower[i] = Rand()*400.0 + 450.0 + 50.0*skill; |
} |
sortkl(); |
// If quadrant needs a starbase, put it in |
if (quadnum >= 10) { |
quadnum -= 10; |
dropin(IHB, &basex, &basey); |
} |
if (nplan) { |
// If quadrant needs a planet, put it in |
for (i=1; i <= inplan; i++) |
if (d.plnets[i].x == quadx && d.plnets[i].y == quady) break; |
if (i <= inplan) { |
iplnet = i; |
dropin(IHP, &plnetx, &plnety); |
} |
} |
// Check for condition |
newcnd(); |
// And finally the stars |
for (i = 1; i <= quadnum; i++) dropin(IHSTAR, &ix, &iy); |
// Check for RNZ |
if (irhere > 0 && klhere == 0 && basex == 0) { |
neutz = 1; |
if (REPORTS) { |
skip(1); |
prout("LT. UHURA- \"Captain, an urgent message."); |
prout(" I'll put it on audio.\" CLICK"); |
skip(1); |
prout("INTRUDER! YOU HAVE VIOLATED THE ROMULAN NEUTRAL ZONE."); |
prout("LEAVE AT ONCE, OR YOU WILL BE DESTROYED!"); |
} |
} |
if (shutup==0) { |
// Put in THING if needed |
if (thingx == quadx && thingy == quady) { |
dropin(IHQUEST, &ix, &iy); |
thingx = thingy = 0; // Transient |
if (damage[DSRSENS] == 0.0) { |
skip(1); |
prout("MR. SPOCK- \"Captain, this is most unusual."); |
prout(" Please examine your short-range scan.\""); |
} |
} |
} |
// Put in a few black holes |
for (i = 1; i <= 3; i++) |
if (Rand() > 0.5) dropin(IHBLANK, &ix, &iy); |
// Take out X's in corners if Tholian present |
if (ithere) { |
if (quad[1][1]=='X') quad[1][1] = IHDOT; |
if (quad[1][10]=='X') quad[1][10] = IHDOT; |
if (quad[10][1]=='X') quad[10][1] = IHDOT; |
if (quad[10][10]=='X') quad[10][10] = IHDOT; |
} |
} |
void sortkl(void) { |
double t; |
int sw, j, k; |
// The author liked bubble sort. So we will use it. :-( |
if (nenhere < 2) return; |
do { |
sw = FALSE; |
for (j = 1; j < nenhere; j++) |
if (kdist[j] > kdist[j+1]) { |
sw = TRUE; |
t = kdist[j]; |
kdist[j] = kdist[j+1]; |
kdist[j+1] = t; |
t = kavgd[j]; |
kavgd[j] = kavgd[j+1]; |
kavgd[j+1] = t; |
k = kx[j]; |
kx[j] = kx[j+1]; |
kx[j+1] = k; |
k = ky[j]; |
ky[j] = ky[j+1]; |
ky[j+1] = k; |
t = kpower[j]; |
kpower[j] = kpower[j+1]; |
kpower[j+1] = t; |
} |
} while (sw); |
} |
/programs/games/sstartrek/en/sst.c |
---|
0,0 → 1,818 |
#include <ctype.h> |
#ifdef MSDOS |
#include <dos.h> |
#endif |
#ifndef KOS32 |
#include <time.h> |
#else |
#include <conio.h> |
#include <kos32sys1.h> |
#endif |
#define INCLUDED // Define externs here |
#include "sst.h" |
/*int getch(void); |
*/ |
static char line[128], *linep = line; |
static int linecount; /* for paging */ |
static void clearscreen(void); |
/* Compared to original version, I've changed the "help" command to |
"call" and the "terminate" command to "quit" to better match |
user expectations. The DECUS version apparently made those changes |
as well as changing "freeze" to "save". However I like "freeze". |
When I got a later version of Super Star Trek that I was converting |
from, I added the emexit command. |
That later version also mentions srscan and lrscan working when |
docked (using the starbase's scanners), so I made some changes here |
to do this (and indicating that fact to the player), and then realized |
the base would have a subspace radio as well -- doing a Chart when docked |
updates the star chart, and all radio reports will be heard. The Dock |
command will also give a report if a base is under attack. |
Movecom no longer reports movement if sensors are damaged so you wouldn't |
otherwise know it. |
Also added: |
1. Better base positioning at startup |
2. deathray improvement (but keeping original failure alternatives) |
3. Tholian Web |
4. Enemies can ram the Enterprise. Regular Klingons and Romulans can |
move in Expert and Emeritus games. This code could use improvement. |
5. The deep space probe looks interesting! DECUS version |
6. Cloaking (with contributions from Erik Olofsen) and Capturing (BSD version). |
*/ |
// I don't like the way this is done, relying on an index. But I don't |
// want to invest the time to make this nice and table driven. |
static char *commands[] = { |
"srscan", |
"lrscan", |
"phasers", |
"photons", |
"move", |
"shields", |
"dock", |
"damages", |
"chart", |
"impulse", |
"rest", |
"warp", |
"status", |
"sensors", |
"orbit", |
"transport", |
"mine", |
"crystals", |
"shuttle", |
"planets", |
"request", |
"report", |
"computer", |
"commands", |
"emexit", |
"probe", |
"cloak", |
"capture", |
"score", |
"abandon", |
"destruct", |
"freeze", |
"deathray", |
"debug", |
"call", |
"quit", |
"help" |
}; |
#define NUMCOMMANDS (sizeof(commands)/sizeof(char *)) |
static void listCommands(int x) { |
prout(" SRSCAN MOVE PHASERS CALL\n" |
" STATUS IMPULSE PHOTONS ABANDON\n" |
" LRSCAN WARP SHIELDS DESTRUCT\n" |
" CHART REST DOCK QUIT\n" |
" DAMAGES REPORT SENSORS ORBIT\n" |
" TRANSPORT MINE CRYSTALS SHUTTLE\n" |
" PLANETS REQUEST DEATHRAY FREEZE\n" |
" COMPUTER EMEXIT PROBE COMMANDS"); |
proutn(" "); |
#ifdef SCORE |
proutn("SCORE "); |
#endif |
#ifdef CLOAKING |
proutn("CLOAK "); |
#endif |
#ifdef CAPTURE |
proutn("CAPTURE "); |
#endif |
if (x) proutn("HELP "); |
prout(""); |
} |
static void helpme(void) { |
int i, j; |
char cmdbuf[32]; |
char linebuf[132]; |
FILE *fp; |
/* Give help on commands */ |
int key; |
key = scan(); |
while (TRUE) { |
if (key == IHEOL) { |
proutn("Help on what command?"); |
key = scan(); |
} |
if (key == IHEOL) return; |
for (i = 0; i < NUMCOMMANDS; i++) { |
if (strcmp(commands[i], citem)==0) break; |
} |
if (i != NUMCOMMANDS) break; |
skip(1); |
prout("Valid commands:"); |
listCommands(FALSE); |
key = IHEOL; |
chew(); |
skip(1); |
} |
if (i == 23) { |
strcpy(cmdbuf, " ABBREV"); |
} |
else { |
strcpy(cmdbuf, " Mnemonic: "); |
j = 0; |
while ((cmdbuf[j+13] = toupper(commands[i][j])) != 0) j++; |
} |
fp = fopen("sst.doc", "r"); |
if (fp == NULL) { |
prout("Spock- \"Captain, that information is missing from the"); |
prout(" computer. You need to find SST.DOC and put it in the"); |
prout(" current directory.\""); |
return; |
} |
i = strlen(cmdbuf); |
do { |
if (fgets(linebuf, 132, fp) == NULL) { |
prout("Spock- \"Captain, there is no information on that command.\""); |
fclose(fp); |
return; |
} |
} while (strncmp(linebuf, cmdbuf, i) != 0); |
skip(1); |
prout("Spock- \"Captain, I've found the following information:\""); |
skip(1); |
do { |
if (linebuf[0]!=12) { // ignore page break lines |
linebuf[strlen(linebuf)-1] = '\0'; // No \n at end |
prout(linebuf); |
} |
fgets(linebuf,132,fp); |
} while (strstr(linebuf, "******")==NULL); |
fclose(fp); |
} |
static void makemoves(void) { |
int i, hitme; |
char ch; |
while (TRUE) { /* command loop */ |
hitme = FALSE; |
justin = 0; |
Time = 0.0; |
i = -1; |
while (TRUE) { /* get a command */ |
chew(); |
skip(1); |
proutn("COMMAND> "); |
if (scan() == IHEOL) continue; |
for (i=0; i < 29; i++) // Abbreviations allowed for the first 29 commands, only. |
if (isit(commands[i])) |
break; |
if (i < 29) break; |
for (; i < NUMCOMMANDS; i++) |
if (strcmp(commands[i], citem) == 0) break; |
if (i < NUMCOMMANDS |
#ifndef CLOAKING |
&& i != 26 // ignore the CLOAK command |
#endif |
#ifndef CAPTURE |
&& i != 27 // ignore the CAPTURE command |
#endif |
#ifndef SCORE |
&& i != 28 // ignore the SCORE command |
#endif |
#ifndef DEBUG |
&& i != 33 // ignore the DEBUG command |
#endif |
) break; |
if (skill <= SFAIR) { |
prout("UNRECOGNIZED COMMAND. LEGAL COMMANDS ARE:"); |
listCommands(TRUE); |
} |
else prout("UNRECOGNIZED COMMAND."); |
} |
switch (i) { /* command switch */ |
case 0: // srscan |
srscan(1); |
break; |
case 1: // lrscan |
lrscan(); |
break; |
case 2: // phasers |
phasers(); |
if (ididit) { |
#ifdef CLOAKING |
if (irhere && d.date >= ALGERON && !isviolreported && iscloaked) { |
prout("The Romulan ship discovers you are breaking the Treaty of Algeron!"); |
ncviol++; |
isviolreported = TRUE; |
} |
#endif |
hitme = TRUE; |
} |
break; |
case 3: // photons |
photon(); |
if (ididit) { |
#ifdef CLOAKING |
if (irhere && d.date >= ALGERON && !isviolreported && iscloaked) { |
prout("The Romulan ship discovers you are breaking the Treaty of Algeron!"); |
ncviol++; |
isviolreported = TRUE; |
} |
#endif |
hitme = TRUE; |
} |
break; |
case 4: // move |
warp(1); |
break; |
case 5: // shields |
sheild(1); |
if (ididit) { |
attack(2); |
shldchg = 0; |
} |
break; |
case 6: // dock |
dock(); |
break; |
case 7: // damages |
dreprt(); |
break; |
case 8: // chart |
chart(0); |
break; |
case 9: // impulse |
impuls(); |
break; |
case 10: // rest |
waiting(); |
if (ididit) hitme = TRUE; |
break; |
case 11: // warp |
setwrp(); |
break; |
case 12: // status |
srscan(3); |
break; |
case 13: // sensors |
sensor(); |
break; |
case 14: // orbit |
orbit(); |
if (ididit) hitme = TRUE; |
break; |
case 15: // transport "beam" |
beam(); |
break; |
case 16: // mine |
mine(); |
if (ididit) hitme = TRUE; |
break; |
case 17: // crystals |
usecrystals(); |
break; |
case 18: // shuttle |
shuttle(); |
if (ididit) hitme = TRUE; |
break; |
case 19: // Planet list |
preport(); |
break; |
case 20: // Status information |
srscan(2); |
break; |
case 21: // Game Report |
report(0); |
break; |
case 22: // use COMPUTER! |
eta(); |
break; |
case 23: |
listCommands(TRUE); |
break; |
case 24: // Emergency exit |
clearscreen(); // Hide screen |
freeze(TRUE); // forced save |
#ifdef KOS32 |
con_exit(1); |
#endif |
exit(1); // And quick exit |
break; |
case 25: |
probe(); // Launch probe |
break; |
#ifdef CLOAKING |
case 26: |
cloak(); // turn on/off cloaking |
if (iscloaking) { |
attack(2); // We will be seen while we cloak |
iscloaking = FALSE; |
iscloaked = TRUE; |
} |
break; |
#endif |
#ifdef CAPTURE |
case 27: |
capture(); // Attempt to get Klingon ship to surrender |
if (ididit) hitme = TRUE; |
break; |
#endif |
#ifdef SCORE |
case 28: |
score(1); // get the score |
break; |
#endif |
case 29: // Abandon Ship |
abandn(); |
break; |
case 30: // Self Destruct |
dstrct(); |
break; |
case 31: // Save Game |
freeze(FALSE); |
if (skill > SGOOD) |
prout("WARNING--Frozen games produce no plaques!"); |
break; |
case 32: // Try a desparation measure |
deathray(); |
if (ididit) hitme = TRUE; |
break; |
#ifdef DEBUG |
case 33: // What do we want for debug??? |
debugme(); |
break; |
#endif |
case 34: // Call for help |
help(); |
break; |
case 35: |
alldone = 1; // quit the game |
#ifdef DEBUG |
if (idebug) score(0); |
#endif |
break; |
case 36: |
helpme(); // get help |
break; |
} |
for (;;) { |
if (alldone) break; // Game has ended |
#ifdef DEBUG |
if (idebug) prout("2500"); |
#endif |
if (Time != 0.0) { |
events(); |
if (alldone) break; // Events did us in |
} |
if (d.galaxy[quadx][quady] == 1000) { // Galaxy went Nova! |
atover(0); |
continue; |
} |
if (nenhere == 0) movetho(); |
if (hitme && justin==0) { |
attack(2); |
if (alldone) break; |
if (d.galaxy[quadx][quady] == 1000) { // went NOVA! |
atover(0); |
hitme = TRUE; |
continue; |
} |
} |
break; |
} |
if (alldone) break; |
} |
} |
int main(int argc, char **argv) { |
int i; |
int hitme; |
char ch; |
#ifdef KOS32 |
if (con_init_console_dll()) return 1; // init fail |
con_set_title("-SUPER- STAR TREK"); |
con_set_flags(CON_COLOR_GREEN); |
#endif |
prelim(); |
if (argc > 1) { // look for -f option |
if (strcmp(argv[1], "-f")== 0) { |
coordfixed = 1; |
argc--; |
argv++; |
} |
} |
if (argc > 1) { |
fromcommandline = 1; |
line[0] = '\0'; |
while (--argc > 0) { |
strcat(line, *(++argv)); |
strcat(line, " "); |
} |
} |
else fromcommandline = 0; |
while (TRUE) { /* Play a game */ |
setup(); |
if (alldone) { |
score(0); |
alldone = 0; |
} |
else makemoves(); |
skip(2); |
stars(); |
skip(1); |
if (tourn && alldone) { |
printf("Do you want your score recorded?"); |
if (ja()) { |
chew2(); |
freeze(FALSE); |
} |
} |
printf("Do you want to play again?"); |
if (!ja()) break; |
} |
skip(1); |
prout("May the Great Bird of the Galaxy roost upon your home planet."); |
return 0; |
} |
void cramen(int i) { |
/* return an enemy */ |
char *s; |
switch (i) { |
case IHR: s = "Romulan"; break; |
case IHK: s = "Klingon"; break; |
case IHC: s = "Commander"; break; |
case IHS: s = "Super-commander"; break; |
case IHSTAR: s = "Star"; break; |
case IHP: s = "Planet"; break; |
case IHB: s = "Starbase"; break; |
case IHBLANK: s = "Black hole"; break; |
case IHT: s = "Tholean"; break; |
case IHWEB: s = "Tholean web"; break; |
default: s = "Unknown??"; break; |
} |
proutn(s); |
} |
void cramlc(int key, int x, int y) { |
if (key == 1) proutn(" Quadrant"); |
else if (key == 2) proutn(" Sector"); |
proutn(" "); |
crami(x, 1); |
proutn(" - "); |
crami(y, 1); |
} |
void crmena(int i, int enemy, int key, int x, int y) { |
if (i == 1) proutn("***"); |
cramen(enemy); |
proutn(" at"); |
cramlc(key, x, y); |
} |
void crmshp(void) { |
char *s; |
switch (ship) { |
case IHE: s = "Enterprise"; break; |
case IHF: s = "Faerie Queene"; break; |
default: s = "Ship???"; break; |
} |
proutn(s); |
} |
void stars(void) { |
prouts("******************************************************"); |
skip(1); |
} |
double expran(double avrage) { |
return -avrage*log(1e-7 + Rand()); |
} |
double Rand(void) { |
return rand()/(1.0 + (double)RAND_MAX); |
} |
void iran8(int *i, int *j) { |
*i = Rand()*8.0 + 1.0; |
*j = Rand()*8.0 + 1.0; |
} |
void iran10(int *i, int *j) { |
*i = Rand()*10.0 + 1.0; |
*j = Rand()*10.0 + 1.0; |
} |
void chew(void) { |
linecount = 0; |
linep = line; |
*linep = 0; |
} |
void chew2(void) { |
/* return IHEOL next time */ |
linecount = 0; |
linep = line+1; |
*linep = 0; |
} |
int scan(void) { |
int i; |
char *cp; |
linecount = 0; |
// Init result |
aaitem = 0.0; |
*citem = 0; |
// Read a line if nothing here |
if (*linep == 0) { |
if (linep != line) { |
chew(); |
return IHEOL; |
} |
#ifdef KOS32 |
cp = gets(line); |
if (!cp) exit(); |
#else |
// We should really be using fgets |
fgets(line,sizeof(line),stdin); |
#endif |
if (line[strlen(line)-1] == '\n') |
line[strlen(line)-1] = '\0'; |
linep = line; |
} |
// Skip leading white space |
while (*linep == ' ') linep++; |
// Nothing left |
if (*linep == 0) { |
chew(); |
return IHEOL; |
} |
if (isdigit(*linep) || *linep=='+' || *linep=='-' || *linep=='.') { |
// treat as a number |
if (sscanf(linep, "%lf%n", &aaitem, &i) < 1) { |
linep = line; // Invalid numbers are ignored |
*linep = 0; |
return IHEOL; |
} |
else { |
// skip to end |
linep += i; |
return IHREAL; |
} |
} |
// Treat as alpha |
cp = citem; |
while (*linep && *linep!=' ') { |
if ((cp - citem) < 9) *cp++ = tolower(*linep); |
linep++; |
} |
*cp = 0; |
return IHALPHA; |
} |
int ja(void) { |
chew(); |
while (TRUE) { |
scan(); |
chew(); |
if (*citem == 'y') return TRUE; |
if (*citem == 'n') return FALSE; |
proutn("Please answer with \"Y\" or \"N\":"); |
} |
} |
void cramf(double x, int w, int d) { |
char buf[64]; |
sprintf(buf, "%*.*f", w, d, x); |
proutn(buf); |
} |
void crami(int i, int w) { |
char buf[16]; |
sprintf(buf, "%*d", w, i); |
proutn(buf); |
} |
double square(double i) { return i*i; } |
static void clearscreen(void) { |
/* Somehow we need to clear the screen */ |
proutn("\033[2J\033[0;0H"); /* Hope for an ANSI display */ |
} |
/* We will pull these out in case we want to do something special later */ |
void pause(int i) { |
#ifdef CLOAKING |
if (iscloaked) return; |
#endif |
putchar('\n'); |
if (i==1) { |
if (skill > SFAIR) |
prout("[ANNOUNCEMENT ARRIVING...]"); |
else |
prout("[IMPORTANT ANNOUNCEMENT ARRIVING -- HIT ENTER TO CONTINUE]"); |
getchar(); |
} |
else { |
if (skill > SFAIR) |
proutn("[CONTINUE?]"); |
else |
proutn("[HIT ENTER TO CONTINUE]"); |
getchar(); |
proutn("\r \r"); |
} |
if (i != 0) { |
clearscreen(); |
} |
linecount = 0; |
} |
void skip(int i) { |
while (i-- > 0) { |
linecount++; |
if (linecount >= 23) |
pause(0); |
else |
putchar('\n'); |
} |
} |
void proutn(char *s) { |
#ifndef KOS32 |
fputs(s, stdout); |
#else |
con_write_asciiz(s); |
#endif |
} |
void prout(char *s) { |
proutn(s); |
skip(1); |
} |
void prouts(char *s) { |
#ifdef KOS32 |
#define clock_t long int |
#define clock() get_tick_count() |
#define CLOCKS_PER_SEC 100 |
#endif |
clock_t endTime; |
/* print slowly! */ |
while (*s) { |
endTime = clock() + CLOCKS_PER_SEC*0.05; |
while (clock() < endTime) ; |
putchar(*s++); |
#ifndef KOS32 |
fflush(stdout); |
#endif |
} |
} |
void huh(void) { |
chew(); |
skip(1); |
prout("Beg your pardon, Captain?"); |
} |
int isit(char *s) { |
/* New function -- compares s to scaned citem and returns true if it |
matches to the length of s */ |
return strncmp(s, citem, max(1, strlen(citem))) == 0; |
} |
#ifdef DEBUG |
void debugme(void) { |
proutn("Reset levels? "); |
if (ja() != 0) { |
if (energy < inenrg) energy = inenrg; |
shield = inshld; |
torps = intorps; |
lsupres = inlsr; |
} |
proutn("Reset damage? "); |
if (ja() != 0) { |
int i; |
for (i=0; i <= ndevice; i++) if (damage[i] > 0.0) damage[i] = 0.0; |
stdamtim = 1e30; |
} |
proutn("Toggle idebug? "); |
if (ja() != 0) { |
idebug = !idebug; |
if (idebug) prout("Debug output ON"); |
else prout("Debug output OFF"); |
} |
proutn("Cause selective damage? "); |
if (ja() != 0) { |
int i, key; |
for (i=1; i <= ndevice; i++) { |
proutn("Kill "); |
proutn(device[i]); |
proutn("? "); |
chew(); |
key = scan(); |
if (key == IHALPHA && isit("y")) { |
damage[i] = 10.0; |
if (i == DRADIO) stdamtim = d.date; |
} |
} |
} |
proutn("Examine/change events? "); |
if (ja() != 0) { |
int i; |
for (i = 1; i < NEVENTS; i++) { |
int key; |
if (future[i] == 1e30) continue; |
switch (i) { |
case FSNOVA: proutn("Supernova "); break; |
case FTBEAM: proutn("T Beam "); break; |
case FSNAP: proutn("Snapshot "); break; |
case FBATTAK: proutn("Base Attack "); break; |
case FCDBAS: proutn("Base Destroy "); break; |
case FSCMOVE: proutn("SC Move "); break; |
case FSCDBAS: proutn("SC Base Destroy "); break; |
} |
cramf(future[i]-d.date, 8, 2); |
chew(); |
proutn(" ?"); |
key = scan(); |
if (key == IHREAL) { |
future[i] = d.date + aaitem; |
} |
} |
chew(); |
} |
proutn("Make universe visible? "); |
if (ja() != 0) { |
int i, j; |
for (i = 1; i < 9; i++) |
{ |
for (j = 1; j < 9; j++) |
{ |
starch[i][j] = 1; |
} |
} |
} |
} |
#endif |
/programs/games/sstartrek/en/sst.doc |
---|
0,0 → 1,1591 |
SSSSS U U PPPPP EEEEE RRRRR |
S U U P P E R R |
SSSSS U U PPPPP EEEE RRRRR |
S U U P E R R |
SSSSS UUUUU P EEEEE R R |
SSSSSSS TTTTTTTT A RRRRRRR |
SSSSSSSS TTTTTTTT AAA RRRRRRRR |
SS TT AAA RR RR |
SSSSSSS TT AA AA RR RR |
SSSSSSS TT AA AA RRRRRRRR |
SS TT AAAAAAA RRRRRRR |
SS TT AAAAAAA RR RR |
SSSSSSSS TT AA AA RR RR |
SSSSSSS TT AA AA RR RR |
TTTTTTTT RRRRRRR EEEEEEEEE KK KK |
TTTTTTTT RRRRRRRR EEEEEEEEE KK KK |
TT RR RR EE KK KK |
TT RR RR EEEEEE KKKKKK |
TT RRRRRRRR EEEEEE KKKKK |
TT RRRRRRR EE KK KK |
TT RR RR EE KK KK |
TT RR RR EEEEEEEEE KK KK |
TT RR RR EEEEEEEEE KK KK |
Produced For Your Enjoyment |
By |
David Matuszek |
and |
Paul Reynolds |
With Modifications By |
Don Smith |
Resurrected By |
Tom Almy |
Permission is hereby granted for the copying, distribution, |
modification and use of this program and associated documentation |
for recreational purposes, provided that all references to the |
authors are retained. However, permission is not and will not be |
granted for the sale or promotional use of this program or program |
documentation, or for use in any situation in which profit may be |
considered an objective, since it is the desire of the authors to |
respect the copyrights of the originators of Star Trek. |
----------TABLE OF CONTENTS---------- |
SECTION PAGE |
INTRODUCTION TO THE GAME . . . . . . . . . . . . . . 1 |
HOW TO ISSUE COMMANDS. . . . . . . . . . . . . . . . 4 |
DESCRIPTIONS OF COMMANDS . . . . . . . . . . . . . . 5 |
SHORT-RANGE SCAN. . . . . . . . . . . . . . . . 5 |
STATUS REPORT . . . . . . . . . . . . . . . . . 6 |
LONG-RANGE SCAN . . . . . . . . . . . . . . . . 7 |
STAR CHART. . . . . . . . . . . . . . . . . . . 8 |
DAMAGE REPORT . . . . . . . . . . . . . . . . . 8 |
MOVE UNDER WARP DRIVE . . . . . . . . . . . . . 9 |
WARP FACTOR . . . . . . . . . . . . . . . . . . 10 |
IMPULSE ENGINES . . . . . . . . . . . . . . . . 10 |
DEFLECTOR SHIELDS . . . . . . . . . . . . . . . 11 |
PHASERS . . . . . . . . . . . . . . . . . . . . 12 |
REPORT. . . . . . . . . . . . . . . . . . . . . 13 |
COMPUTER. . . . . . . . . . . . . . . . . . . . 13 |
PHOTON TORPEDOES. . . . . . . . . . . . . . . . 14 |
DOCK AT STARBASE. . . . . . . . . . . . . . . . 15 |
REST. . . . . . . . . . . . . . . . . . . . . . 15 |
CALL STARBASE FOR HELP. . . . . . . . . . . . . 15 |
ABANDON SHIP. . . . . . . . . . . . . . . . . . 16 |
SELF-DESTRUCT . . . . . . . . . . . . . . . . . 16 |
TERMINATE THE CURRENT GAME. . . . . . . . . . . 16 |
SENSOR-SCAN . . . . . . . . . . . . . . . . . . 17 |
ENTER STANDARD ORBIT. . . . . . . . . . . . . . 17 |
TRANSPORTER-TRAVEL. . . . . . . . . . . . . . . 17 |
SHUTTLE CRAFT . . . . . . . . . . . . . . . . . 18 |
MINE DILITHIUM CRYSTALS . . . . . . . . . . . . 18 |
LOAD DILITHIUM CRYSTALS . . . . . . . . . . . . 18 |
PLANET REPORT . . . . . . . . . . . . . . . . . 19 |
FREEZE. . . . . . . . . . . . . . . . . . . . . 19 |
REQUEST . . . . . . . . . . . . . . . . . . . . 20 |
EXPERIMENTAL DEATH RAY. . . . . . . . . . . . . 20 |
LAUNCH DEEP SPACE PROBE . . . . . . . . . . . . 21 |
EMERGENCY EXIT. . . . . . . . . . . . . . . . . 21 |
ASK FOR HELP. . . . . . . . . . . . . . . . . . 21 |
CLOAKING DEVICE . . . . . . . . . . . . . . . . 22 |
CAPTURE KLINGONS . . . . . . . . . . . . . . . 22 |
GET THE SCORE . . . . . . . . . . . . . . . . . 22 |
MISCELLANEOUS NOTES. . . . . . . . . . . . . . . . . 23 |
SCORING. . . . . . . . . . . . . . . . . . . . . . . 24 |
HANDY REFERENCE PAGE . . . . . . . . . . . . . . . . 25 |
MODIFICATIONS. . . . . . . . . . . . . . . . . . . . 26 |
ACKNOWLEDGMENTS. . . . . . . . . . . . . . . . . . . 27 |
REFERENCES . . . . . . . . . . . . . . . . . . . . . 27 |
-----INTRODUCTION TO THE GAME----- 1 |
The Organian Peace Treaty has collapsed, and the Federation is at war |
with the Klingon Empire. Joining the Klingons against the Federation |
are the members of the "Romulan Star Empire." As commander of the |
Starship U.S.S. Enterprise, your job is to wipe out the Klingon |
invasion fleet and make the galaxy safe for democracy. |
Your battleground is the entire galaxy, which for convenience is |
divided up into eight rows of eight quadrants each, like a |
checkerboard. Rows are numbered from top to bottom, and columns are |
numbered left to right, so quadrant 1 - 8 would be in the upper right |
hand corner of the galaxy. |
During battle you will be concerned only with those enemies that |
occupy the same quadrant as yourself. Quadrants are divided up into |
sectors: ten rows of ten sectors each. Sectors are numbered in the |
same way as quadrants, so the sector in the upper right corner is |
sector 1 - 10. You have a short-range scanner which allows you to |
look at the entire quadrant in a single display. |
Enemies recharge during your absence. If you leave a quadrant |
containing a weakened enemy, when you return to that quadrant he will |
be strong again. Also, each time you enter a quadrant, the positions |
of everything in the quadrant (except your ship) are randomized, to |
save you the trouble of trying to remember where everything in the |
quadrant is. Notice that this refers only to the positions of things |
in the quadrant--the numbers of each kind of thing are not changed |
(except for black holes and the Super-commander, which move around |
the galaxy). If you kill something, it stays dead. |
The Romulans are not as serious a threat to the Federation as the |
Klingons. For one thing, there are not as many of them. For |
another, the Romulans are not as treacherous. However, Romulans are |
not to be trifled with, especially when you are in violation of the |
"Romulan Neutral Zone." |
There are two kinds of Klingons: Ordinary Klingons, which are bad |
enough, and Klingon Commanders, which are even worse. Commanders are |
about three times stronger than ordinary Klingons. Commanders are |
more resistant to your weapons. Commanders can move about during |
battle while Ordinary Klingons stay put. And finally, Commanders |
have a thing called a "long-range tractor beam" which they can use, |
at random intervals, to yank you away from what you are doing into |
their quadrant, to do battle with them. There is also a special |
commander, called the "Super-commander." This character is so bad he |
is reserved for the Good, Expert, and Emeritus games. Fortunately, |
there is just one Super-commander in a game. In addition to the |
undesirable traits of Commanders, he can move from quadrant to |
quadrant at will, seeking out and destroying your starbases and any |
helpful planets he runs across. He also has a spy planted aboard |
your ship, giving him valuable information about your condition. |
Using this information, he can do dastardly things like tractor beam |
your ship when you are in bad shape. And once you've been tractor |
beamed by the Super-commander --- |
2 |
But the advantages are not all on the side of the enemy. Your ship |
is more powerful, and has better weapons. Besides, in the this |
galaxy there are from two to five starbases, at which you can stop to |
refuel and lick your wounds, safe from phaser attack or tractor |
beams. But you had best not dally there too long, since time is not |
on your side. The Klingons are not just after you; they are |
attacking the entire Federation. There is always a finite "time |
left," which is how much longer the Federation can hold out if you |
just sit on your fat behind and do nothing. As you wipe out |
Klingons, you reduce the rate at which the invasion fleet weakens the |
Federation, and so the time left until the Federation collapses may |
actually increase. Since Klingons are the main threat to the |
Federation, the Romulans do not figure into the "time left." In |
fact, you need not kill all the Romulans to win. If you can get all |
the Klingons, the Federation will abide forever, and you have won the |
game. |
Space is vast, and it takes precious time to move from one place to |
another. In comparison, other things happen so quickly that we |
assume the take no time at all. Two ways that time can pass are when |
you move, or when you issue a command to sit still and rest for a |
period of time. You will sometimes want to do the latter, since the |
various devices aboard your starship may be damaged and require time |
to repair. Of course, repairs can be made more quickly at a starbase |
than can in flight. |
In addition to Klingons, Romulans, and starbases, the galaxy contains |
(surprise) stars. Mostly, stars are a nuisance and just get in your |
way. You can trigger a star into going nova by shooting one of your |
photon torpedoes at it. When a star novas, it does a lot of damage |
to anything immediately adjacent to it. If another star is adjacent |
to a nova, it too will go nova. Stars may also occasionally go |
supernova; a supernova in a quadrant destroys everything in the |
quadrant and makes the quadrant permanently uninhabitable. You may |
"jump over" a quadrant containing a supernova when you move, but you |
should not stop there. |
Supernovas may happen spontaneously, without provocation. If a |
supernova occurs in the same quadrant you are in, your starship has |
an "emergency automatic override" which picks some random direction |
and some random warp factor, and tries to throw you clear of the |
supernova. If the supernova occurs in some other quadrant, you just |
get a warning message from Starfleet about it (provided, of course, |
that your subspace radio is working). |
Also a few planets are scattered through the galaxy. These can |
sometimes be a great help since some of them will have "dilithium |
crystals," which are capable of replenishing the ship's energy |
supply. You can either beam down to the planet surface using the |
transporter, or take the shuttle craft "Galileo." |
Finally, each quadrant will contain from zero to three black holes. |
These can deflect or swallow torpedoes passing near them. They also |
swallow enemy ships knocked into them. If your ship enters one - - - |
3 |
Star Trek is a rich game, full of detail. These instructions are |
written at a moderate level--no attempt has been made fully to |
describe everything about the game, but there is quite a bit more |
here than you need to get started. If you are new to the game, just |
get a rough idea of the kinds of commands available, and start |
playing. After a game or two you will have learned everything |
important, and the detailed command descriptions which follow will be |
a lot more meaningful to you. |
You have weapons: phasers and photon torpedoes. You have a defense: |
deflector shields. You can look at things: long-range scanners, |
short-range scanners, and a star chart. You can move about, under |
warp drive or impulse power. You can also dock at a starbase, rest |
while repairs are being made, abandon ship, self destruct, or give up |
and start a new game. |
The Klingons are waiting. |
-----HOW TO ISSUE COMMANDS----- 4 |
When the game is waiting for you to enter a command it will print out |
COMMAND> |
You may then type in your command. All you have to remember for each |
command is the mnemonic. For example, if you want to move straight up |
one quadrant, you can type in the mnemonic (case insensitive) |
move |
and the computer will prompt you with |
Manual or automatic- |
Say you type in "manual". The computer then responds |
X and Y displacements- |
Now you type in "0 1" which specifies an X movement of zero and a Y |
movement of one. |
When you have learned the commands, you can avoid being prompted |
simply by typing in the information without waiting to be asked for |
it. For example, in the above example, you could simply type in |
move manual 0 1 |
and it will be done. Or you could type in |
move manual |
and when the computer responds with the displacement prompt, you can type in |
0 1 |
and it will understand. |
You can abbreviate most mnemonics. For "move", you can use any of |
move mov mo m |
successfully. For your safety, certain critical commands (such as to |
abandon ship) must be written out in full. Also, in a few cases two |
or more commands begin with the same letter, and in this case that |
letter refers to a particular one of the commands; to get the other, |
your abbreviation must be two or more characters long. This sounds |
complicated, but you will learn the abbreviations quickly enough. |
What this all boils down to is: |
(1) You can abbreviate practically anything |
(2) If you forget, the computer will prompt you |
(3) If you remember, you can type it all on one line |
If you are part way through entering a command and you change your |
mind, you can cancel the command by typing -1 as one of the |
parameters, with the exception of the manual move command. If |
anything is not clear to you, experiment. The worst you can do is |
lose a game or two. |
-----DESCRIPTION OF COMMANDS----- 5 |
******************** |
* SHORT-RANGE SCAN * |
******************** |
Mnemonic: SRSCAN |
Shortest abbreviation: S |
Full commands: SRSCAN |
SRSCAN NO |
SRSCAN CHART |
The short-range scan gives you a considerable amount of information |
about the quadrant your starship is in. A short-range scan is best |
described by an example. |
1 2 3 4 5 6 7 8 9 10 |
1 * . . . . R . . . . Stardate 2516.3 |
2 . . . E . . . . . . Condition RED |
3 . . . . . * . B . . Position 5 - 1, 2 - 4 |
4 . . . S . . . . . . Life Support DAMAGED, Reserves=2.30 |
5 . . . . . . . K . . Warp Factor 5.0 |
6 . K . . . . . * . Energy 2176.24 |
7 . . . . . P . . . . Torpedoes 3 |
8 . . . . * . . . . . Shields UP, 42% 1050.0 units |
9 . * . . * . . . C . Klingons Left 12 |
10 . . . . . . . . . . Time Left 3.72 |
The left part is a picture of the quadrant. The E at sector 2 - 4 |
represents the Enterprise; the B at sector 3 - 8 is a starbase. |
There are ordinary Klingons (K) at sectors 5 - 8 and 6 - 2, and a |
Klingon Commander (C) at 9 - 9. The (GULP) "Super-commander" (S) is |
occupies sector 4 - 4, and a Romulan (R) is at 1 - 6. A planet (P) |
is at sector 7 - 6. There are also a large number of stars (*). The |
periods (.) are just empty space--they are printed to help you get |
your bearings. Sector 6 - 4 contains a black hole ( ). |
The information on the right is assorted status information. You can |
get this alone with the STATUS command. The status information will |
be absent if you type "N" after SRSCAN. Otherwise status information |
will be presented. |
If you type "C" after SRSCAN, you will be given a short-range scan |
and a Star Chart. |
Short-range scans are free. That is, they use up no energy and no |
time. If you are in battle, doing a short-range scan does not give |
the enemies another chance to hit you. You can safely do a |
short-range scan anytime you like. |
If your short-range sensors are damaged, this command will only show |
the contents of adjacent sectors. |
6 |
***************** |
* STATUS REPORT * |
***************** |
Mnemonic: STATUS |
Shortest abbreviation: ST |
This command gives you information about the current state of your |
starship as follows: |
STARDATE - The current date. A stardate is the same as a day. |
CONDITION - There are four possible conditions: |
DOCKED - docked at starbase. |
RED - in battle. |
YELLOW - low on energy (<1000 units) |
GREEN - none of the above |
POSITION - Quadrant is given first, then sector |
LIFE SUPPORT - If "ACTIVE" then life support systems are |
functioning normally. If on "RESERVES" the number is how many |
stardates your reserve food, air, etc. will last--you must |
get repairs made or get to starbase before your reserves run |
out. |
WARP FACTOR - What your warp factor is currently set to. |
ENERGY - The amount of energy you have left. If it drops to zero, |
you die. |
TORPEDOES - How many photon torpedoes you have left. |
SHIELDS - Whether your shields are up or down, how strong they are |
(what percentage of a hit they can deflect), and shield |
energy. |
KLINGONS LEFT - How many of the Klingons are still out there. |
TIME LEFT - How long the Federation can hold out against the |
present number of Klingons; that is, how long until the end |
if you do nothing in the meantime. If you kill Klingons |
quickly, this number will go up--if not, it will go down. If |
it reaches zero, the federation is conquered and you lose. |
Status information is free--it uses no time or energy, and if you are |
in battle, the Klingons are not given another chance to hit you. |
Status information can also be obtained by doing a short-range scan. |
See the SRSCAN command for details. |
Each item of information can be obtained singly by requesting it. |
See REQUEST command for details. |
7 |
******************* |
* LONG-RANGE SCAN * |
******************* |
Mnemonic: LRSCAN |
Shortest abbreviation: L |
A long-range scan gives you general information about where you are |
and what is around you. Here is an example output. |
Long-range scan for Quadrant 5 - 1 |
-1 107 103 |
-1 316 5 |
-1 105 1000 |
This scan says that you are in row 5, column 1 of the 8 by 8 galaxy. |
The numbers in the scan indicate how many of each kind of thing there |
is in your quadrant and all adjacent quadrants. The digits are |
interpreted as follows. |
Thousands digit: 1000 indicates a supernova (only) |
Hundreds digit: number of Klingons present |
Tens digit: number of starbases present |
Ones digit: number of stars present |
For example, in your quadrant (5 - 1) the number is 316, which |
indicates 3 Klingons, 1 starbase, and 6 stars. The long-range |
scanner does not distinguish between ordinary Klingons and Klingon |
command ships. If there is a supernova, as in the quadrant below and |
to your right (quadrant 6 - 2), there is nothing else in the |
quadrant. |
Romulans possess a "cloaking device" which prevents their detection |
by long-range scan. Because of this fact, Starfleet Command is never |
sure how many Romulans are "out there". When you kill the last |
Klingon, the remaining Romulans surrender to the Federation. |
Planets are also undetectable by long-range scan. The only way to |
detect a planet is to find it in your current quadrant with the |
short-range sensors. |
Since you are in column 1, there are no quadrants to your left. The |
minus ones indicate the negative energy barrier at the edge of the |
galaxy, which you are not permitted to cross. |
Long-range scans are free. They use up no energy or time, and can be |
done safely regardless of battle conditions. |
8 |
************** |
* STAR CHART * |
************** |
Mnemonic: CHART |
Shortest abbreviation: C |
As you proceed in the game, you learn more and more about what things |
are where in the galaxy. When ever you first do a scan in a quadrant, |
telemetry sensors are ejected which will report any changes in the |
quadrant(s) back to your ship, providing the sub-space radio is |
working. Spock will enter this information in the chart. If the radio |
is not working, Spock can only enter new information discovered from |
scans, and information in other quadrants may be obsolete. |
The chart looks like an 8 by 8 array of numbers. These numbers are |
interpreted exactly as they are on a long-range scan. A period (.) in |
place of a digit means you do not know that information yet. For |
example, ... means you know nothing about the quadrant, while .1. |
means you know it contains a base, but an unknown number of Klingons |
and stars. |
Looking at the star chart is a free operation. It costs neither time |
nor energy, and can be done safely whether in or out of battle. |
***************** |
* DAMAGE REPORT * |
***************** |
Mnemonic: DAMAGES |
Shortest abbreviation: DA |
At any time you may ask for a damage report to find out what devices |
are damaged and how long it will take to repair them. Naturally, |
repairs proceed faster at a starbase. |
If you suffer damages while moving, it is possible that a subsequent |
damage report will not show any damage. This happens if the time |
spent on the move exceeds the repair time, since in this case the |
damaged devices were fixed en route. |
Damage reports are free. They use no energy or time, and can be done |
safely even in the midst of battle. |
9 |
************************* |
* MOVE UNDER WARP DRIVE * |
************************* |
Mnemonic: MOVE |
Shortest abbreviation: M |
Full command: MOVE MANUAL <displacement> |
MOVE AUTOMATIC <destination> |
This command is the usual way to move from one place to another |
within the galaxy. You move under warp drive, according to the |
current warp factor (see "WARP FACTOR"). |
There are two command modes for movement: MANUAL and AUTOMATIC. The |
manual mode requires the following format: |
MOVE MANUAL <deltax> <deltay> |
<deltax> and <deltay> are the horizontal and vertical displacements |
for your starship, in quadrants; a displacement of one sector is 0.1 |
quadrants. Specifying <deltax> and <deltay> causes your ship to move |
in a straight line to the specified destination. If <deltay> is |
omitted, it is assumed zero. For example, the shortest possible |
command to move one sector to the right would be |
M M .1 |
The following examples of manual movement refer to the short-range |
scan shown earlier. |
Destination Sector Manual Movement command |
3 - 1 M M -.3 -.1 |
2 - 1 M M -.3 |
1 - 2 M M -.2 .1 |
1 - 4 M M 0 .1 |
(leaving quadrant) M M 0 .2 |
The automatic mode is as follows: |
MOVE AUTOMATIC <qrow> <qcol> <srow> <scol> |
where <qrow> and <qcol> are the row and column numbers of the |
destination quadrant, and <srow> and <scol> are the row and column |
numbers of the destination sector in that quadrant. This command also |
moves your ship in a straight line path to the destination. For |
moving within a quadrant, <qrow> and <qcol> may be omitted. For |
example, to move to sector 2 - 9 in the current quadrant, the |
shortest command would be |
M A 2 9 |
To move to quadrant 3 - 7, sector 5 - 8, type |
M A 3 7 5 8 |
and it will be done. In automatic mode, either two or four numbers |
must be supplied. |
10 |
Automatic mode utilizes the ship's "battle computer." If the |
computer is damaged, manual movement must be used. |
If warp engines are damaged less than 10 stardates (undocked) you can |
still go warp 4. |
It uses time and energy to move. How much time and how much energy |
depends on your current warp factor, the distance you move, and |
whether your shields are up. The higher the warp factor, the faster |
you move, but higher warp factors require more energy. You may move |
with your shields up, but this doubles the energy required. |
You can move within a quadrant without being attacked if you just |
entered the quadrant or have bee attacked since your last move |
command. This enables you to move and hit them before they |
retaliate. |
*************** |
* WARP FACTOR * |
*************** |
Mnemonic: WARP |
Shortest abbreviation: W |
Full command: WARP <number> |
Your warp factor controls the speed of your starship. The larger the |
warp factor, the faster you go and the more energy you use. |
Your minimum warp factor is 1.0 and your maximum warp factor is 10.0 |
(which is 100 times as fast and uses 1000 times as much energy). At |
speeds above warp 6 there is some danger of causing damage to your |
warp engines; this damage is larger at higher warp factors and also |
depends on how far you go at that warp factor. |
At exactly warp 10 there is some probability of entering a so-called |
"time warp" and being thrown forward or backward in time. The farther |
you go at warp 10, the greater is the probability of entering the |
time warp. |
******************* |
* IMPULSE ENGINES * |
******************* |
Mnemonic: IMPULSE |
Shortest abbreviation: I |
Full command: IMPULSE MANUAL <displacement> |
IMPULSE AUTOMATIC <destination> |
The impulse engines give you a way to move when your warp engines are |
damaged. They move you at a speed of 0.95 sectors per stardate, |
which is the equivalent of a warp factor of about 0.975, so they are |
much too slow to use except in emergencies. |
Movement commands are indicated just as in the "MOVE" command. |
The impulse engines require 20 units of energy to engage, plus 10 |
units per sector (100 units per quadrant) traveled. It does not cost |
extra to move with the shields up. |
11 |
********************* |
* DEFLECTOR SHIELDS * |
********************* |
Mnemonic: SHIELDS |
Shortest abbreviation: SH |
Full commands: SHIELDS UP |
SHIELDS DOWN |
SHIELDS TRANSFER <amount of energy to transfer> |
Your deflector shields are a defensive device to protect you from |
Klingon attacks (and nearby novas). As the shields protect you, they |
gradually weaken. A shield strength of 75%, for example, means that |
the next time a Klingon hits you, your shields will deflect 75% of |
the hit, and let 25% get through to hurt you. |
It costs 50 units of energy to raise shields, nothing to lower them. |
You may move with your shields up; this costs nothing under impulse |
power, but doubles the energy required for warp drive. |
Each time you raise or lower your shields, the Klingons have another |
chance to attack. Since shields do not raise and lower |
instantaneously, the hits you receive will be intermediate between |
what they would be if the shields were completely up or completely |
down. |
You may not fire phasers through your shields. However you may use |
the "high-speed shield control" to lower shields, fire phasers, and |
raise the shields again before the Klingons can react. Since rapid |
lowering and raising of the shields requires more energy than normal |
speed operation, it costs you 200 units of energy to activate this |
control. It is automatically activated when you fire phasers while |
shields are up. You may fire photon torpedoes, but they may be |
deflected considerably from their intended course as they pass |
through the shields (depending on shield strength). |
You may transfer energy between the ship's energy (given as "Energy" |
in the status) and the shields. Thee word "TRANSFER" may be |
abbreviated "T". The amount of energy to transfer is the number of |
units of energy you wish to take from the ship's energy and put into |
the shields. If you specify an negative number, energy is drained |
from the shields to the ship. Transferring energy constitutes a turn. |
If you transfer energy to the shields while you are under attack, |
they will be at the new energy level when you are next hit. |
Enemy torpedoes hitting your ship explode on your shields (if they |
are up) and have essentially the same effect as phaser hits. |
12 |
*********** |
* PHASERS * |
*********** |
Mnemonic: PHASERS |
Shortest abbreviation: P |
Full commands: PHASERS AUTOMATIC <AMOUNT TO FIRE> <NO> |
PHASERS <AMOUNT TO FIRE> <NO> |
PHASERS MANUAL <NO> <AMOUNT 1> <AMOUNT 2>...<AMOUNT N> |
Phasers are energy weapons. As you fire phasers at Klingons, you |
specify an "amount to fire" which is drawn from your energy reserves. |
The amount of total hit required to kill an enemy is partly random. |
but also depends on skill level. |
The average hit required to kill an ordinary Klingon varies from 200 |
units in the Novice game to 250 units in the Emeritus game. |
Commanders normally require from 600 (Novice) to 700 (Emeritus). The |
Super-commander requires from 875 (Good) to 1000 (Emeritus). Romulans |
require an average of 350 (Novice) to 450 (Emeritus). |
Hits on enemies are cumulative, as long as you don't leave the |
quadrant. |
In general, not all that you fire will reach the Klingons. The |
farther away they are, the less phaser energy will reach them. If a |
Klingon is adjacent to you, he will receive about 90% of the phaser |
energy directed at him; a Klingon 5 sectors away will receive about |
60% and a Klingon 10 sectors away will receive about 35%. There is |
some randomness involved, so these figures are not exact. Phasers |
have no effect beyond the boundaries of the quadrant you are in. |
Phasers may overheat (and be damaged) if you fire too large a burst |
at once. Firing up to 1500 units is safe. From 1500 on up the |
probability of overheat increases with the amount fired. |
If phaser firing is automatic, the computer decides how to divide up |
your <amount to fire> among the Klingons present. If phaser firing |
is manual, you specify how much energy to fire at each Klingon |
present (nearest first), rather than just specifying a total amount. |
You can abbreviate "MANUAL" and "AUTOMATIC" to one or more letters; if |
you mention neither, automatic fire is usually assumed. |
Battle computer information is available by firing phasers manually, |
and allowing the computer to prompt you. If you enter zero for the |
amount to fire at each enemy, you will get a complete report, without |
cost. The battle computer will tell you how much phaser energy to |
fire at each enemy for a sure kill. This information appears in |
parentheses prior to the prompt for each enemy. SInce the amount is |
computed from sensor data, if either the computer or the S.R. sensors |
are damaged, this information will be unavailable, and phasers must |
be fired manually. |
13 |
A safety interlock prevents phasers from being fired through the |
shields. If this were not so, the shields would contain your fire |
and you would fry yourself. However, you may utilize the |
"high-speed shield control" to drop shields, fire phasers, and raise |
shields before the enemy can react. Since it takes more energy to |
work the shields rapidly with a shot, it costs you 200 units of |
energy each time you activate this control. It is automatically |
activated when you fire phasers while the shields are up. By |
specifying the <no> option, shields are not raised after firing. |
Phasers have no effect on starbases (which are shielded) or on stars. |
********** |
* REPORT * |
********** |
Mnemonic: REPORT |
Shortest abbreviation: REP |
This command supplies you with information about the state of the |
current game. Its purpose is to remind you of things that you have |
learned during play, but may have forgotten, and cannot otherwise |
retrieve if you are not playing at a hard-copy terminal. |
You are told the following things: |
. The length and skill level of the game you are playing |
. The original number of Klingons |
. How many Klingons you have destroyed |
. Whether the Super-Commander has been destroyed |
. How many bases have been destroyed |
. How many bases are left |
. What bases (if any) are under attack; your subspace radio |
must have been working since the attack to get this |
information. |
. How many casualties you have suffered |
. How many times you have called for help. |
This same information is automatically given to you when you start to |
play a frozen game. |
************ |
* COMPUTER * |
************ |
Mnemonic: COMPUTER |
Shortest abbreviation: CO |
This command allows using the ship's computer (if functional) to |
calculate travel times and energy usage. |
14 |
******************** |
* PHOTON TORPEDOES * |
******************** |
Mnemonic: PHOTONS |
Shortest abbreviation: PHO |
Full commands: PHOTONS <NUMBER> <TARG1> <TARG2> <TARG3> |
Photon torpedoes are projectile weapons--you either hit what you aim |
at, or you don't. There are no "partial hits". |
One photon torpedo will usually kill one ordinary Klingon, but it |
usually takes about two for a Klingon Commander. Photon torpedoes |
can also blow up stars and starbases, if you aren't careful. |
You may fire photon torpedoes singly, or in bursts of two or three. |
Each torpedo is individually targetable. The computer will prompt |
you, asking for the target sector for each torpedo. Alternately, you |
may specify each target in the command line. |
Photon torpedoes cannot be aimed precisely--there is always some |
randomness involved in the direction they go. Photon torpedoes may |
be fired with your shields up, but as they pass through the shields |
they are randomly deflected from their intended course even more. |
Photon torpedoes are proximity-fused. The closer they explode to the |
enemy, the more damage they do. There is a hit "window" about one |
sector wide. If the torpedo misses the hit window, it does not |
explode and the enemy is unaffected. Photon torpedoes are only |
effective within the quadrant. They have no effect on things in |
adjacent quadrants. |
If more than one torpedo is fired and only one target sector is |
specified, all torpedoes are fired at that sector. For example, to |
fire two torpedoes at sector 3 - 4, you type |
PHO 2 3 4 (or) PHO 2 3 4 3 4 |
To fire torpedoes at, consecutively, sectors 2 - 6, 1 - 10, and 4 - |
7, type |
PHO 3 2 6 1 10 4 7 |
There is no restriction to fire directly at a sector. For example, |
you can enter |
PHO 1 3 2.5 |
to aim between two sectors. However, sector numbers must be 1 to 10 |
inclusive. |
15 |
******************** |
* DOCK AT STARBASE * |
******************** |
Mnemonic: DOCK |
Shortest abbreviation: D |
You may dock your starship whenever you are in one of the eight |
sector positions immediately adjacent to a starbase. When you dock, |
your starship is resupplied with energy, shield energy photon |
torpedoes, and life support reserves. Repairs also proceed faster at |
starbase, so if some of your devices are damaged, you may wish to |
stay at base (by using the "REST" command) until they are fixed. If |
your ship has more than its normal maximum energy (which can happen |
if you've loaded crystals) the ship's energy is not changed. |
You may not dock while in standard orbit around a planet. |
Starbases have their own deflector shields, so you are completely |
safe from phaser attack while docked. You are also safe from |
long-range tractor beams. |
Starbases also have both short and long range sensors, which you can |
use if yours are broken. There's also a subspace radio to get |
information about happenings in the galaxy. Mr. Spock will update the |
star chart if your ask for it while docked and your own radio is dead. |
******** |
* REST * |
******** |
Mnemonic: REST |
Shortest abbreviation: R |
Full command: REST <NUMBER OF STARDATES> |
This command simply allows the specified number of stardates to go |
by. This is useful if you have suffered damages and wish to wait |
until repairs are made before you go back into battle. |
It is not generally advisable to rest while you are under attack by |
Klingons. |
************************** |
* CALL STARBASE FOR HELP * |
************************** |
Mnemonic: CALL |
(No abbreviation) |
[Originally, this command was called "HELP", but these days it might |
be misinterpreted as built-in documentation!] |
When you get into serious trouble, you may call starbase for help. |
Starbases have a device called a "long-range transporter beam" which |
they can use to teleport you to base. This works by dematerializing |
your starship at its current position and re-materializing it |
adjacent to the nearest starbase. Teleportation is instantaneous, |
and starbase supplies the required energy--all you have to do is let |
them know (via subspace radio) that you need to be rescued. |
16 |
This command should be employed only when absolutely necessary. In |
the first place, calling for help is an admission on your part that |
you got yourself into something you cannot get yourself out of, and |
you are heavily penalized for this in the final scoring. Secondly, |
the long-range transporter beam is not reliable--starbase can always |
manage to dematerialize your starship, but (depending on distance) |
may or may not be able to re-materialize you again. The long-range |
transporter beam has no absolute maximum range; if you are in the |
same quadrant as a starbase, you have a good chance (about 90%) of |
re-materializing successfully. Your chances drop to roughly 50-50 at |
just over 3 quadrants. |
**************** |
* ABANDON SHIP * |
**************** |
Mnemonic: ABANDON |
(no abbreviation) |
You may abandon the Enterprise if necessary. If there is still a |
starbase in the galaxy, you will be sent there and put in charge of a |
weaker ship, the Faerie Queene. |
The Faerie Queene cannot be abandoned. |
***************** |
* SELF-DESTRUCT * |
***************** |
Mnemonic: DESTRUCT |
(no abbreviation) |
You may self-destruct, thus killing yourself and ending the game. If |
there are nearby Klingons, you may take a few of them with you (the |
more energy you have left, the bigger the bang). |
In order to self-destruct you must remember the password you typed in |
at the beginning of the game. |
****************************** |
* TERMINATE THE CURRENT GAME * |
****************************** |
Mnemonic: QUIT |
(no abbreviation) |
Immediately cancel the current game; no conclusion is reached. You |
will be given an opportunity to start a new game or to leave the Star |
Trek program. |
17 |
*************** |
* SENSOR-SCAN * |
*************** |
Mnemonic: SENSORS |
Shortest abbreviation: SE |
Utilizing the short-range sensors, science officer Spock gives you a |
readout on any planet in your quadrant. Planets come in three |
classes: M, N, and O. Only class M planets have earth-like |
conditions. Spock informs you if the planet has any dilithium |
crystals. Sensor scans are free. |
************************ |
* ENTER STANDARD ORBIT * |
************************ |
Mnemonic: ORBIT |
Shortest abbreviation: O |
To land on a planet you must first be in standard orbit. You achieve |
this in a manner similar to docking at starbase. Moving to one of |
the eight sector positions immediately adjacent to the planet, you |
give the orbit command which puts your ship into standard orbit about |
the planet. Since this is a maneuver, a small amount of time is |
used; negligible energy is required. If enemies are present, they |
will attack. |
********************** |
* TRANSPORTER-TRAVEL * |
********************** |
Mnemonic: TRANSPORT |
Shortest abbreviation: T |
The transporter is a device which can convert any physical object |
into energy, beam the energy through space, and reconstruct the |
physical object at some destination. Transporting is one way to land |
on a planet. Since the transporter has a limited range, you must be |
in standard orbit to beam down to a planet. Shields must be down |
while transporting. |
The transport command is used to beam a landing party onto a planet |
to mine "dilithium crystals". Each time the command is given the |
landing party (which you lead) moves from the ship to the planet, or |
vice-versa. |
You are advised against needless transporting, since like all |
devices, the transporter will sometimes malfunction. |
The transporter consumes negligible time and energy. Its use does |
not constitute a "turn". |
18 |
***************** |
* SHUTTLE CRAFT * |
***************** |
Mnemonic: SHUTTLE |
Shortest abbreviation: SHU |
An alternate way to travel to and from planets. Because of limited |
range, you must be in standard orbit to use the shuttle craft, named |
"Galileo". Shields must be down. |
Unlike transporting, use of the shuttle craft does constitute a |
"turn" since time is consumed. The time naturally depends on orbit |
altitude, and is equal to 3.0e-5 times altitude. Shuttling uses no |
ship energy. |
You should use the same travel device going from the planet to the |
ship as you use to go from the ship to the planet. However it is |
possible to transport to the planet and have the Galileo crew come |
and pick your landing party up, or to take the Galileo to the planet |
and then transport back, leaving the shuttle craft on the planet. |
*************************** |
* MINE DILITHIUM CRYSTALS * |
*************************** |
Mnemonic: MINE |
Shortest abbreviation: MI |
Once you and your mining party are on the surface of a planet which |
has dilithium crystals, this command will dig them for you. |
Mining requires time and constitutes a "turn". No energy is used. |
Class M planets require 0.1 to 0.3 stardates to mine. Class N |
planets take twice as long, and class O planets take three times as |
long. |
Dilithium crystals contain enormous energy in a form that is readily |
released in the ship's power system. It is an excellent idea to mine |
them whenever possible, for use in emergencies. You keep the |
crystals until the game is over or you abandon ship when not at a |
starbase. |
*************************** |
* LOAD DILITHIUM CRYSTALS * |
*************************** |
Mnemonic: CRYSTALS |
Shortest abbreviation: CR |
This is a very powerful command which should be used with caution. |
Once you have dilithium crystals aboard ship, this command will |
instruct engineering officer Scott and Mr. Spock to place a raw |
dilithium crystal into the power channel of the ship's |
matter-antimatter converter. When it works, this command will |
greatly boost the ship's energy. |
19 |
Because the crystals are raw and impure, instabilities can occur in |
the power channel. Usually Scotty can control these. When he |
cannot, the results are disastrous. Scotty will use those crystals |
that appear to be most stable first. |
Since using raw dilithium crystals for this purpose entails |
considerable risk, Starfleet Regulations allow its use only during |
"condition yellow". No time or energy is used. |
***************** |
* PLANET REPORT * |
***************** |
Mnemonic: PLANETS |
Shortest abbreviation: PL |
Mr. Spock presents you a list of the available information on planets |
in the galaxy. Since planets do not show up on long-range scans, the |
only way to obtain this information is with the "SENSORS" command. |
********** |
* FREEZE * |
********** |
Mnemonic: FREEZE |
(no abbreviation) |
Full command: FREEZE <FILE NAME> |
The purpose of the FREEZE command is to allow a player to save the |
current state of the game, so that it can be finished later. A |
plaque may not be generated from a frozen game. A file with the |
specified <file name> and type '.TRK' is created (if necessary) in |
the current directory, and all pertinent information about the game |
is written to that file. The game may be continued as usual or be |
terminated at the user's option. |
To restart a game created by the "FREEZE" command, the user need only |
type "FROZEN" in response to the initial question about the type of |
game desired, followed by the <file name>. |
NOTE: A "tournament" game is like a frozen game, with the following |
differences. (1) Tournament games always start from the beginning, |
while a frozen game can start at any point. (2) Tournament games |
require only that the player remember the name or number of the |
tournament, while the information about a frozen game must be kept on |
a file. Tournament games can be frozen, but then they behave like |
regular frozen games. |
A point worth noting is that 'FREEZE' does not save the seed for the |
random number generator, so that identical actions after restarting |
the same frozen game can lead to different results. However, |
identical actions after starting a given tournament game always lead |
to the same results. |
20 |
*********** |
* REQUEST * |
*********** |
Mnemonic: REQUEST |
Shortest abbreviation: REQ |
Full command: REQUEST <ITEM> |
This command allows you to get any single piece of information from |
the <STATUS> command. <ITEM> specifies which information as follows: |
INFORMATION MNEMONIC FOR <ITEM> SHORTEST ABBREVIATION |
STARDATE DATE D |
CONDITION CONDITION C |
POSITION POSITION P |
LIFE SUPPORT LSUPPORT L |
WARP FACTOR WARPFACTOR W |
ENERGY ENERGY E |
TORPEDOES TORPEDOES T |
SHIELDS SHIELDS S |
KLINGONS LEFT KLINGONS K |
TIME LEFT TIME TI |
************************** |
* EXPERIMENTAL DEATH RAY * |
************************** |
Mnemonic: DEATHRAY |
(No abbreviation) |
This command should be used only in those desperate cases where you |
have absolutely no alternative. The death ray uses energy to |
rearrange matter. Unfortunately, its working principles are not yet |
thoroughly understood, and the results are highly unpredictable. |
The only good thing that can result is the destruction of all enemies |
in your current quadrant. This will happen about 70% of the time. |
Only enemies are destroyed; starbases, stars, and planets are |
unaffected. |
Constituting the remaining 30% are results varying from bad to fatal. |
The death ray requires no energy or time, but if you survive, enemies |
will hit you. |
The Faerie Queene has no death ray. |
If the death ray is damaged in its use, it must be totally replaced. |
This can only be done at starbase. Because it is a very complex |
device, it takes 9.99 stardates at base to replace the death ray. |
The death ray cannot be repaired in flight. |
21 |
*************************** |
* LAUNCH DEEP SPACE PROBE * |
*************************** |
Mnemonic: PROBE |
Shortest abbreviation: PR |
Full command: PROBE <ARMED> MANUAL <displacement> |
PROBE <ARMED> AUTOMATIC <destination> |
The Enterprise carries a limited number of Long Range Probes. These |
fly to the end of the galaxy and report back a count of the number of |
important things found in each quadrant through which it went. The |
probe flies at warp 10, and therefore uses time during its flight. |
Results are reported immediately via subspace radio and are recorded |
in the star chart. |
The probe can also be armed with a NOVAMAX warhead. When launched |
with the warhead armed, the probe flies the same except as soon as it |
reaches the target location, it detonates the warhead in the heart of |
a star, causing a supernova and destroying everything in the |
quadrant. It then flies no further. There must be a star in the |
target quadrant for the NOVAMAX to function. |
The probe can fly around objects in a galaxy, but is destroyed if it |
enters a quadrant containing a supernova, or if it leaves the galaxy. |
The target location is specified in the same manner as the MOVE |
command, however for automatic movement, if only one pair of |
coordinates are specified they are assumed to be the quadrant and not |
the sector in the current quadrant! |
The Faerie Queene has no probes. |
****************** |
* EMERGENCY EXIT * |
****************** |
Mnemonic: EMEXIT |
Shortest abbreviation: E |
This command provides a quick way to exit from the game when you |
observe a Klingon battle cruiser approaching your terminal. Its |
effect is to freeze the game on the file 'EMSAVE.TRK' in your current |
directory, erase the screen, and exit. |
Of course, you do loose the chance to get a plaque when you use this |
maneuver. |
**************** |
* ASK FOR HELP * |
**************** |
Mnemonic: HELP |
Full command: HELP <command> |
This command reads the appropriate section from the SST.DOC file, |
providing the file is in the current directory. |
22 |
******************* |
* CLOAKING DEVICE * |
******************* |
Mnemonic: CLOAK |
Shortest abbreviation: CLOAK |
Full commands: CLOAK ON |
CLOAK OFF |
The cloaking device prevents your ship from being seen by any enemy |
vessels. When the cloaking device is in use, your subspace radio will |
not receive transmissions, torpedoes will be less accurate, you cannot |
dock, and you cannot use your warp engines. Enemy ships will get a |
chance to attack you when you turn clocking on. |
The Treaty of Algeron with the Romulans in Stardate 2311 prohibits the |
use of cloaking devices. If a Romulan ship observes you cloaking or |
uncloaking after this point in time you will be in violation, which |
will hurt your final score. |
The Faerie Queene does not have a cloaking device. |
******************** |
* CAPTURE KLINGONS * |
******************** |
Mnemonic: CAPTURE |
Shortest abbreviation: CA |
The capture command provides a more humane way to end a battle than |
just destroying the Klingon battleship with the crew aboard. Assuming |
the subspace radio and transporter are working, and there is room in |
the brig, this command will ask the captain of the weakest Klingon |
ship in the quadrant to surrender. If the captain agrees, some of the |
crew will transport to your ship and the Klingon ship will be |
destroyed. This command does take time and you will be attacked by any |
other enemy ships if the surrender occurs. |
When you dock, any captured Klingons will be transferred to the base |
and you will be credited with the lives you save. |
***************** |
* GET THE SCORE * |
***************** |
Mnemonic: SCORE |
Shortest abbreviation: SC |
Shows what the score would be if the game were to end naturally at |
this point. Since the game hasn't really ended and you lose points if |
you quit, this is perhaps a meaningless command, but it gives you a |
general idea of how well you are performing. |
**********MISCELLANEOUS NOTES********** 23 |
Starbases can be attacked by either commanders or by the |
"Super-Commander". When this happens, you will be notified by |
subspace radio, provided it is working. The message will inform you |
how long the base under attack can last. Since the "Super-Commander" |
is more powerful than an ordinary commander, he can destroy a base |
more quickly. |
The "Super-Commander" travels around the galaxy at a speed of about |
warp 6 or 7. His movement is strictly time based; the more time |
passes, the further he can go. |
Scattered through the galaxy are certain zones of control, |
collectively designated the "Romulan Neutral Zone". Any quadrant |
which contains Romulans without Klingons is part of the Neutral Zone, |
except if a base is present. Since Romulans do not show on either |
the long-range scan or the star chart, it is easy for you to stumble |
into this zone. When you do, if your subspace radio is working, you |
will receive a warning message from the Romulan, politely asking you |
to leave. |
In general, Romulans are a galactic nuisance. |
The high-speed shield control is fairly reliable, but it has been |
known to malfunction. |
You can observe the galactic movements of the "Super-Commander" on |
the star chart, provided he is in territory you have scanned and your |
subspace radio is working. |
Periodically, you will receive intelligence reports from starfleet |
command, indicating the current quadrant of the "Super-Commander". |
Your subspace radio must be working, of course. |
Each quadrant will contain from 0 to 3 black holes. Torpedoes |
entering a black hole disappear. In fact, anything entering a black |
hole disappears, permanently. If you can displace an enemy into one, |
he is a goner. Black holes do not necessarily remain in a quadrant. |
they are transient phenomena. |
Commanders will ram your ship, killing themselves and inflicting |
heavy damage to you, if they should happen to decide to advance into |
your sector. |
You can get a list of commands by typing "COMMANDS". |
----------SCORING---------- 24 |
Scoring is fairly simple. You get points for good things, and you |
lose points for bad things. |
You gain-- |
(1) 10 points for each ordinary Klingon ship you destroy, |
(2) 50 points for each commander ship you destroy, |
(3) 200 points for destroying the "Super-Commander" ship, |
(4) 3 points for each Klingon captured. |
(5) 20 points for each Romulan ship destroyed, |
(6) 1 point for each Romulan captured. |
(7) 500 times your average Klingon ship/stardate kill rate. If you |
lose the game, your kill rate is based on a minimum of |
5 stardates. |
(8) You get a bonus if you win the game, based on your rating: |
Novice=100, Fair=200, Good=300, Expert=400, Emeritus=500. |
You lose-- |
(8) 200 points if you get yourself killed, |
(9) 100 points for each starbase you destroy, |
(10) 100 points for each starship you lose, |
(11) 100 points for each violation of the Treaty of Algeron observed, |
(12) 45 points for each time you had to call for help, |
(13) 10 points for each planet you destroyed, |
(14) 5 points for each star you destroyed, and |
(15) 1 point for each casualty you incurred. |
In addition to your score, you may also be promoted one grade in rank |
if you play well enough. Promotion is based primarily on your |
Klingon/stardate kill rate, since this is the best indicator of |
whether you are ready to go on to the next higher rating. However, |
if you have lost 100 or more points in penalties, the required kill |
rate goes up. Normally, the required kill rate is 0.1 * skill * |
(skill + 1.0) + 0.1, where skill ranges from 1 for Novice to 5 for |
Emeritus. |
You can be promoted from any level. There is a special promotion |
available if you go beyond the "Expert" range. You can also have a |
certificate of merit printed with your name, date, and Klingon kill |
rate, provided you are promoted from either the "Expert" or |
"Emeritus" levels. This "plaque" requires a 132 column printer. You |
may need print the certificate to a file, import it into your word |
processor, selecting Courier 8pt font, and then print in "landscape |
orientation". |
You should probably start out at the novice level, even if you are |
already familiar with one of the other versions of the Star Trek |
game--but, of course, the level of game you play is up to you. If |
you want to start at the Expert level, go ahead. It's your funeral. |
The emeritus game is strictly for masochists. |
----------HANDY REFERENCE PAGE---------- 25 |
ABBREV FULL COMMAND DEVICE USED |
------ ------------ ----------- |
ABANDON ABANDON shuttle craft |
C CHART (none) |
CA CAPTURE subspace radio, transporter |
CALL CALL (for help) subspace radio |
CL CLOAK cloaking |
CO COMPUTER computer |
CR CRYSTALS (none) |
DA DAMAGES (none) |
DEATHRAY DEATHRAY (none) |
DESTRUCT DESTRUCT computer |
D DOCK (none) |
E EMEXIT (none) |
FREEZE FREEZE <FILE NAME> (none) |
I IMPULSE <MANUAL> <DISPLACEMENT> impulse engines |
IMPULSE AUTOMATIC <DESTINATION> impulse engines and computer |
L LRSCAN long-range sensors |
MI MINE (none) |
M MOVE <MANUAL> <DISPLACEMENT> warp engines |
MOVE AUTOMATIC <DESTINATION> warp engines and computer |
O ORBIT warp or impulse engines |
P PHASERS <TOTAL AMOUNT> phasers and computer |
PHASERS AUTOMATIC <TOTAL AMOUNT> phasers, computer, sr sensors |
PHASERS MANUAL <AMT1> <AMT2> ... phasers |
PHO PHOTONS <NUMBER> <TARGETS> torpedo tubes |
PL PLANETS (none) |
PR PROBE <ARMED> <MANUAL> <DISPLACEMENT> probe launcher, radio |
PROBE <ARMED> AUTOMATIC <DESTINATION> launcher, radio, computer |
REP REPORT (none) |
REQ REQUEST (none) |
R REST <NUMBER OF STARDATES> (none) |
QUIT QUIT (none) |
S SRSCAN <NO or CHART> short-range sensors |
SC SCORE (none) |
SE SENSORS short-range sensors |
SH SHIELDS <UP, DOWN, or TRANSFER> deflector shields |
SHU SHUTTLE shuttle craft |
ST STATUS (none) |
T TRANSPORT transporter |
W WARP <FACTOR> (none) |
L. R. Scan: thousands digit: supernova |
hundreds digit: Klingons |
tens digit: starbases |
ones digit: stars |
period (.): digit not known (star chart only) |
Courses are given in manual mode in X - Y displacements; in automatic |
mode as destination quadrant and/or sector. Manual mode is default. |
Distances are given in quadrants. A distance of one sector is 0.1 quadrant. |
Ordinary Klingons have about 400 units of energy, Commanders about |
1200. Romulans normally have about 800 units of energy, and the |
(GULP) "Super-Commander" has about 1800. |
Phaser fire diminishes to about 60 percent at 5 sectors. Up to 1500 |
units may be fired in a single burst without danger of overheat. |
Warp 6 is the fastest safe speed. At higher speeds, engine damage |
may occur. At warp 10 you may enter a time warp. |
Shields cost 50 units of energy to raise, and double the power |
requirements of moving under warp drive. Engaging the high-speed |
shield control requires 200 units of energy. |
Warp drive requires (distance)*(warp factor cubed) units of energy |
to travel at a speed of (warp factor squared)/10 quadrants per stardate. |
Impulse engines require 20 units to warm up, plus 100 units per |
quadrant. Speed is just under one sector per stardate. |
********MODIFICATIONS******** 26 |
Back in (about) 1977 I got a copy of this Super Star Trek game for |
the CDC 6600 mainframe computer. Someone had converted it to PDP-11 |
Fortran but couldn't get it to run because of its size. I modified |
the program to use overlays and managed to shoehorn it in on the 58k |
byte machine. |
I liked the game so much I put some time into fixing bugs, mainly |
what could be called continuity errors and loopholes in the game's |
logic. We even played a couple tournaments. |
In 1979, I lost access to that PDP-11. I did save the source code |
listing. In 1995, missing that old friend, I started converting the |
program into portable ANSI C. It's been slow, tedious work that took |
over a year to accomplish. |
In early 1997, I got the bright idea to look for references to "Super |
Star Trek" on the World Wide Web. There weren't many hits, but there |
was one that came up with 1979 Fortran sources! This version had a |
few additional features that mine didn't have, however mine had some |
feature it didn't have. So I merged its features that I liked. I also |
took a peek at the DECUS version (a port, less sources, to the |
PDP-10), and some other variations. |
Modifications I made: |
Compared to original version, I've changed the "help" command to |
"call" and the "terminate" command to "quit" to better match user |
expectations. The DECUS version apparently made those changes as well |
as changing "freeze" to "save". However I like "freeze". |
I added EMEXIT from the 1979 version. |
That later version also mentions srscan and lrscan working when |
docked (using the starbase's scanners), so I made some changes here |
to do this (and indicating that fact to the player), and then |
realized the base would have a subspace radio as well -- doing a |
Chart when docked updates the star chart, and all radio reports will |
be heard. The Dock command will also give a report if a base is under |
attack. |
It also had some added logic to spread the initial positioning of |
bases. That made sense to add because most people abort games with |
bad base placement. |
The experimental deathray originally had only a 5% chance of success, |
but could be used repeatedly. I guess after a couple years of use, it |
was less "experimental" because the 1979 version had a 70% success |
rate. However it was prone to breaking after use. I upgraded the |
deathray, but kept the original set of failure modes (great humor!). |
I put in the Tholian Web code from the 1979 version. |
I added code so that Romulans and regular Klingons could move in |
advanced games. I re-enabled the code which allows enemy ships to |
ram the Enterprise; it had never worked right. The 1979 version |
seems to have it all fixed up, but I'm still not overly happy with |
the algorithm. |
The DECUS version had a Deep Space Probe. Looked like a good idea |
so I implemented it based on its description. |
In 2013 I added the CLOAK and CAPTURE commands and also fixed lots |
of bugs. The CAPTURE command is based on the one in BSDTrek. When |
making this change I also changed text so that killing Klingons |
became destroying Klingon ships reflecting that a Klingon ship does |
have more than one Klingon aboard! The CLOAK command and some other |
bug fixes and correction of typos are thanks to Erik Olofsen. |
----------ACKNOWLEDGMENTS---------- 27 |
The authors would like to thank Professor Michael Duggan for his |
encouragement and administrative assistance with the development of |
the Star Trek game, without which it might never have been completed. |
Much credit is due to Patrick McGehearty and Rich Cohen, who assisted |
with the original design of the game and contributed greatly to its |
conceptual development. |
Thanks are also due to Carl Strange, Hardy Tichenor and Steven Bruell |
for their assistance with certain coding problems. |
This game was inspired by and rather loosely based on an earlier |
game, programmed in the BASIC language, by Jim Korp and Grady Hicks. |
It is the authors' understanding that the BASIC game was in turn |
derived from a still earlier version in use at Penn State University. |
----------REFERENCES---------- |
1. "Star Trek" (the original television series), produced and |
directed by Gene Rodenberry. |
2. "Star Trek" (the animated television series), produced by Gene |
Rodenberry and directed by Hal Sutherland. Also excellent, |
and not just kiddie fare. If you enjoyed the original series |
you should enjoy this one (unless you have some sort of a |
hangup about watching cartoons). |
3. "The Making of Star Trek", by Steven E. Whitfield and Gene |
Rodenberry. The best and most complete readily available |
book about Star Trek. (Ballantine Books) |
4. "The World of Star Trek", by David Gerrold. Similiar in scope |
to the above book. (Bantam) |
5. "The Star Trek Guide", third revision 4/17/67, by Gene |
Rodenberry. The original writer's guide for the television |
series, but less comprehensive than (3) above. |
(Norway Productions) |
6. "The Trouble With Tribbles", by David Gerrold. Includes the |
complete script of this popular show. (Ballantine Books) |
7. "Star Trek", "Star Trek 2", ..., "Star Trek 9", by James Blish. |
The original shows in short story form. (Bantam) |
8. "Spock Must Die", by James Blish. An original novel, but |
rather similar to the show "The Enemy Within". (Bantam) |
9. Model kits of the Enterprise and a "Klingon Battle-Cruiser" |
by AMT Corporation are available at most hobby shops. |
/programs/games/sstartrek/en/sst.h |
---|
0,0 → 1,496 |
#include <stdio.h> |
#include <math.h> |
#include <stdlib.h> |
#include <string.h> |
#ifndef INCLUDED |
#define EXTERN extern |
#else |
#define EXTERN |
#endif |
#ifdef WINDOWS |
#define DEBUG |
#define SCORE |
#define CLOAKING |
#define CAPTURE |
#endif |
#ifdef CLOAKING |
#define ndevice (16) |
#else |
#define ndevice (15) // Number of devices |
#endif |
#define phasefac (2.0) |
#define PLNETMAX (10) |
#define NEVENTS (8) |
typedef struct { |
int x; /* Quadrant location of planet */ |
int y; |
int pclass; /* class M, N, or O (1, 2, or 3) */ |
int crystals; /* has crystals */ |
int known; /* =1 contents known, =2 shuttle on this planet */ |
} PLANETS; |
EXTERN struct foo { |
int snap, // snapshot taken |
remkl, // remaining klingons |
remcom, // remaining commanders |
rembase, // remaining bases |
starkl, // destroyed stars |
basekl, // destroyed bases |
killk, // Klingons killed |
killc, // commanders killed |
galaxy[9][9], // The Galaxy (subscript 0 not used) |
cx[11],cy[11], // Commander quadrant coordinates |
baseqx[6], // Base quadrant X |
baseqy[6], // Base quadrant Y |
newstuf[9][9], // Extended galaxy goodies |
isx, isy, // Coordinate of Super Commander |
nscrem, // remaining super commanders |
nromkl, // Romulans killed |
nromrem, // Romulans remaining |
nsckill, // super commanders killed |
nplankl; // destroyed planets |
PLANETS plnets[PLNETMAX+1]; // Planet information |
#ifdef CAPTURE |
int kcaptured, brigfree; |
#endif |
double date, // stardate |
remres, // remaining resources |
remtime; // remaining time |
} d, snapsht; // Data that is snapshot |
EXTERN char |
quad[11][11]; // contents of our quadrant |
// Scalar variables that are needed for freezing the game |
// are placed in a structure. #defines are used to access by their |
// original names. Gee, I could have done this with the d structure, |
// but I just didn't think of it back when I started. |
EXTERN struct foo2 { |
int inkling, |
inbase, |
incom, |
instar, |
intorps, |
condit, |
torps, |
ship, |
quadx, |
quady, |
sectx, |
secty, |
length, |
skill, |
basex, |
basey, |
klhere, |
comhere, |
casual, |
nhelp, |
nkinks, |
ididit, |
gamewon, |
alive, |
justin, |
alldone, |
shldchg, |
thingx, |
thingy, |
plnetx, |
plnety, |
inorbit, |
landed, |
iplnet, |
imine, |
inplan, |
nenhere, |
ishere, |
neutz, |
irhere, |
icraft, |
ientesc, |
iscraft, |
isatb, |
iscate, |
#ifdef DEBUG |
idebug, |
#endif |
#ifdef CLOAKING |
iscloaked, |
iscloaking, |
ncviol, |
isviolreported, |
#endif |
#ifdef CAPTURE |
brigcapacity, |
#endif |
iattak, |
icrystl, |
tourn, |
thawed, |
batx, |
baty, |
ithere, |
ithx, |
ithy, |
iseenit, |
probecx, |
probecy, |
proben, |
isarmed, |
nprobes; |
double inresor, |
intime, |
inenrg, |
inshld, |
inlsr, |
indate, |
energy, |
shield, |
shldup, |
warpfac, |
wfacsq, |
lsupres, |
dist, |
direc, |
Time, |
docfac, |
resting, |
damfac, |
stdamtim, |
cryprob, |
probex, |
probey, |
probeinx, |
probeiny; |
} a; |
#define inkling a.inkling // Initial number of klingons |
#define inbase a.inbase // Initial number of bases |
#define incom a.incom // Initian number of commanders |
#define instar a.instar // Initial stars |
#define intorps a.intorps // Initial/Max torpedoes |
#define condit a.condit // Condition (red, yellow, green docked) |
#define torps a.torps // number of torpedoes |
#define ship a.ship // Ship type -- 'E' is Enterprise |
#define quadx a.quadx // where we are |
#define quady a.quady // |
#define sectx a.sectx // where we are |
#define secty a.secty // |
#define length a.length // length of game |
#define skill a.skill // skill level |
#define basex a.basex // position of base in current quad |
#define basey a.basey // |
#define klhere a.klhere // klingons here |
#define comhere a.comhere // commanders here |
#define casual a.casual // causalties |
#define nhelp a.nhelp // calls for help |
#define nkinks a.nkinks // |
#define ididit a.ididit // Action taken -- allows enemy to attack |
#define gamewon a.gamewon // Finished! |
#define alive a.alive // We are alive (not killed) |
#define justin a.justin // just entered quadrant |
#define alldone a.alldone // game is now finished |
#define shldchg a.shldchg // shield is changing (affects efficiency) |
#define thingx a.thingx // location of strange object in galaxy |
#define thingy a.thingy // |
#define plnetx a.plnetx // location of planet in quadrant |
#define plnety a.plnety // |
#define inorbit a.inorbit // orbiting |
#define landed a.landed // party on planet (1), on ship (-1) |
#define iplnet a.iplnet // planet # in quadrant |
#define imine a.imine // mining |
#define inplan a.inplan // initial planets |
#define nenhere a.nenhere // Number of enemies in quadrant |
#define ishere a.ishere // Super-commander in quandrant |
#define neutz a.neutz // Romulan Neutral Zone |
#define irhere a.irhere // Romulans in quadrant |
#define icraft a.icraft // Kirk in Galileo |
#define ientesc a.ientesc // Attempted escape from supercommander |
#define iscraft a.iscraft // =1 if craft on ship, -1 if removed from game |
#define isatb a.isatb // =1 if SuperCommander is attacking base |
#define iscate a.iscate // Super Commander is here |
#ifdef DEBUG |
#define idebug a.idebug // Debug mode |
#endif |
#ifdef CLOAKING |
#define iscloaked a.iscloaked // Cloaking is enabled |
#define iscloaking a.iscloaking // However if iscloaking is TRUE then in process of cloaking and can be attacked |
#define ncviol a.ncviol // Treaty violations |
#define isviolreported a.isviolreported // Violation reported by Romulan in quadrant |
#endif |
#ifdef CAPTURE |
#define kcaptured d.kcaptured // number of captured Klingons |
#define brigfree d.brigfree // room in the brig |
#define brigcapacity a.brigcapacity // How many Klingons the brig will hold |
#endif |
#define iattak a.iattak // attack recursion elimination (was cracks[4]) |
#define icrystl a.icrystl // dilithium crystals aboard |
#define tourn a.tourn // Tournament number |
#define thawed a.thawed // Thawed game |
#define batx a.batx // Base coordinates being attacked |
#define baty a.baty // |
#define ithere a.ithere // Tholean is here |
#define ithx a.ithx // coordinates of tholean |
#define ithy a.ithy |
#define iseenit a.iseenit // Seen base attack report |
#define inresor a.inresor // initial resources |
#define intime a.intime // initial time |
#define inenrg a.inenrg // Initial/Max Energy |
#define inshld a.inshld // Initial/Max Shield |
#define inlsr a.inlsr // initial life support resources |
#define indate a.indate // Initial date |
#define energy a.energy // Energy level |
#define shield a.shield // Shield level |
#define shldup a.shldup // Shields are up |
#define warpfac a.warpfac // Warp speed |
#define wfacsq a.wfacsq // squared warp factor |
#define lsupres a.lsupres // life support reserves |
#define dist a.dist // movement distance |
#define direc a.direc // movement direction |
#define Time a.Time // time taken by current operation |
#define docfac a.docfac // repair factor when docking (constant?) |
#define resting a.resting // rest time |
#define damfac a.damfac // damage factor |
#define stdamtim a.stdamtim // time that star chart was damaged |
#define cryprob a.cryprob // probability that crystal will work |
#define probex a.probex // location of probe |
#define probey a.probey |
#define probecx a.probecx // current probe quadrant |
#define probecy a.probecy |
#define probeinx a.probeinx // Probe x,y increment |
#define probeiny a.probeiny |
#define proben a.proben // number of moves for probe |
#define isarmed a.isarmed // Probe is armed |
#define nprobes a.nprobes // number of probes available |
EXTERN int |
kx[21], // enemy sector locations |
ky[21], |
starch[9][9]; // star chart |
EXTERN int fromcommandline; // Game start from command line options |
EXTERN int coordfixed; // Fix those dumb coordinates. |
EXTERN char passwd[10], // Self Destruct password |
*device[ndevice+1]; |
EXTERN PLANETS nulplanet; // zeroed planet structure |
EXTERN double |
kpower[21], // enemy energy levels |
kdist[21], // enemy distances |
kavgd[21], // average distances |
damage[ndevice+1], // damage encountered |
future[NEVENTS+1]; // future events |
EXTERN int iscore, iskill; // Common PLAQ |
EXTERN double perdate; |
typedef enum {FWON, FDEPLETE, FLIFESUP, FNRG, FBATTLE, |
FNEG3, FNOVA, FSNOVAED, FABANDN, FDILITHIUM, |
FMATERIALIZE, FPHASER, FLOST, FMINING, FDPLANET, |
FPNOVA, FSSC, FSTRACTOR, FDRAY, FTRIBBLE, |
FHOLE |
#ifdef CLOAKING |
, FCLOAK |
#endif |
} FINTYPE ; |
/* Skill levels */ |
typedef enum {SNOVICE=1, SFAIR, SGOOD, SEXPERT, SEMERITUS} SKILLTYPE; |
EXTERN double aaitem; |
EXTERN char citem[24]; |
/* Define devices */ |
#define DSRSENS 1 |
#define DLRSENS 2 |
#define DPHASER 3 |
#define DPHOTON 4 |
#define DLIFSUP 5 |
#define DWARPEN 6 |
#define DIMPULS 7 |
#define DSHIELD 8 |
#define DRADIO 9 |
#define DSHUTTL 10 |
#define DCOMPTR 11 |
#define DTRANSP 12 |
#define DSHCTRL 13 |
#define DDRAY 14 // Added deathray |
#define DDSP 15 // Added deep space probe |
#define DCLOAK 16 // Added cloaking device |
/* Define future events */ |
#define FSPY 0 // Spy event happens always (no future[] entry) |
// can cause SC to tractor beam Enterprise |
#define FSNOVA 1 // Supernova |
#define FTBEAM 2 // Commander tractor beams Enterprise |
#define FSNAP 3 // Snapshot for time warp |
#define FBATTAK 4 // Commander attacks base |
#define FCDBAS 5 // Commander destroys base |
#define FSCMOVE 6 // Supercommander moves (might attack base) |
#define FSCDBAS 7 // Supercommander destroys base |
#define FDSPROB 8 // Move deep space probe |
#ifdef INCLUDED |
PLANETS nulplanet = {0}; |
char *device[ndevice+1] = { |
"", |
"S. R. Sensors", |
"L. R. Sensors", |
"Phasers", |
"Photon Tubes", |
"Life Support", |
"Warp Engines", |
"Impulse Engines", |
"Shields", |
"Subspace Radio", |
"Shuttle Craft", |
"Computer", |
"Transporter", |
"Shield Control", |
"Death Ray", |
"D. S. Probe" |
#ifdef CLOAKING |
,"Cloaking Device" |
#endif |
}; |
#endif |
#define ALGERON (2311) /* Date of the Treaty of Algeron */ |
#ifndef TRUE |
#define TRUE (1) |
#endif |
#ifndef FALSE |
#define FALSE (0) |
#endif |
#define IHR 'R' |
#define IHK 'K' |
#define IHC 'C' |
#define IHS 'S' |
#define IHSTAR '*' |
#define IHP 'P' |
#define IHB 'B' |
#define IHBLANK ' ' |
#define IHDOT '.' |
#define IHQUEST '?' |
#define IHE 'E' |
#define IHF 'F' |
#define IHT 'T' |
#define IHWEB '#' |
#define IHGREEN 'G' |
#define IHYELLOW 'Y' |
#define IHRED 'R' |
#define IHDOCKED 'D' |
/* Function prototypes */ |
void prelim(void); |
void attack(int); |
int choose(void); |
void setup(void); |
void score(int); |
void atover(int); |
void srscan(int); |
void lrscan(void); |
void phasers(void); |
void photon(void); |
void warp(int); |
void sheild(int); |
void dock(void); |
void dreprt(void); |
void chart(int); |
void impuls(void); |
void waiting(void); |
void setwrp(void); |
void events(void); |
void report(int); |
void eta(void); |
void help(void); |
void abandn(void); |
void finish(FINTYPE); |
void dstrct(void); |
void kaboom(void); |
void freeze(int); |
void thaw(void); |
void plaque(void); |
int scan(void); |
#define IHEOL (0) |
#define IHALPHA (1) |
#define IHREAL (2) |
void chew(void); |
void chew2(void); |
void skip(int); |
void prout(char *s); |
void proutn(char *s); |
void stars(void); |
void newqad(int); |
int ja(void); |
void cramen(int); |
void crmshp(void); |
void cramlc(int, int, int); |
double expran(double); |
double Rand(void); |
void iran8(int *, int *); |
void iran10(int *, int *); |
double square(double); |
void dropin(int, int*, int*); |
void newcnd(void); |
void sortkl(void); |
void lmove(void); |
void ram(int, int, int, int); |
void crmena(int, int, int, int, int); |
void deadkl(int, int, int, int, int); |
void timwrp(void); |
void movcom(void); |
void torpedo(double, double, int, int, double *); |
void cramf(double, int, int); |
void crami(int, int); |
void huh(void); |
void pause(int); |
void nova(int, int); |
void snova(int, int); |
void scom(int *); |
void hittem(double *); |
void prouts(char *); |
int isit(char *); |
void preport(void); |
void orbit(void); |
void sensor(void); |
void beam(void); |
void mine(void); |
void usecrystals(void); |
void shuttle(void); |
void deathray(void); |
void debugme(void); |
void attakreport(void); |
void movetho(void); |
void probe(void); |
///#ifndef WINDOWS |
int min(int, int); |
int max(int, int); |
///#endif |
void randomize(void); |
///int getch(void); |
#ifdef CLOAKING |
void cloak(void); |
#endif |
#ifdef CAPTURE |
void capture(void); |
#endif |
#ifdef CLOAKING |
#define REPORTS ((condit==IHDOCKED || damage[DRADIO]<=0.0) && !iscloaked) |
#else |
#define REPORTS (condit==IHDOCKED || damage[DRADIO]<=0.0) |
#endif |