b165e4f6b6
git-svn-id: svn://kolibrios.org@7142 a494cfbc-eb01-0410-851d-a64ba20cac60
1483 lines
36 KiB
C
1483 lines
36 KiB
C
#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 |