Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1.         #include "sst.h"
  2.  
  3. #ifdef CLOAKING
  4. void cloak(void) {
  5.         int key;
  6.         enum {NONE, CLON, CLOFF} action = NONE;
  7.  
  8.         if (ship == IHF) {
  9.                 prout("Ye Faerie Queene has no cloaking device.");
  10.                 return;
  11.         }
  12.  
  13.         key = scan();
  14.  
  15.         if (key == IHREAL) return;
  16.  
  17.         if (key == IHALPHA) {
  18.                 if (isit("on")) {
  19.                         if (iscloaked) {
  20.                                 prout("The cloaking device has already been switched on.");
  21.                                 return;
  22.                         }
  23.                         action = CLON;
  24.                 }
  25.                 else if (isit("off")) {
  26.                         if (!iscloaked) {
  27.                                 prout("The cloaking device has already been switched off.");
  28.                                 return;
  29.                         }
  30.                         action = CLOFF;
  31.                 }
  32.                 else {
  33.                         huh();
  34.                         return;
  35.                 }
  36.         } else {
  37.                 if (!iscloaked) {
  38.                         proutn("Switch cloaking device on?");
  39.                         if (ja()==0) return;
  40.                         action = CLON;
  41.                 }
  42.                 if (iscloaked) {
  43.                         proutn("Switch cloaking device off?");
  44.                         if (ja()==0) return;
  45.                         action = CLOFF;
  46.                 }
  47.                 if (action == NONE) return;
  48.         }
  49.  
  50.     if (action==CLOFF) {
  51.         if (irhere && d.date >= ALGERON && !isviolreported) {
  52.             prout("Spock- \"Captain, the Treaty of Algeron is in effect.\n   Are you sure this is wise?\"");
  53.             if (ja() == 0) return;
  54.         }
  55.                 prout("Engineer Scott- \"Aye, Sir.\"");
  56.         iscloaked = FALSE;
  57.         if (irhere && d.date >= ALGERON && !isviolreported) {
  58.             prout("The Romulan ship discovers you are breaking the Treaty of Algeron!");
  59.             ncviol++;
  60.             isviolreported = TRUE;
  61.         }
  62.            
  63. //        if (neutz && d.date >= ALGERON) finish(FCLOAK);
  64.                 return;
  65.         }
  66.  
  67.         if (damage[DCLOAK]!=0) {
  68.                 prout("Engineer Scott- \"The cloaking device is damaged, Sir.\"");
  69.                 return;
  70.         }
  71.  
  72.         if (condit==IHDOCKED) {
  73.                 prout("You cannot cloak while docked.");
  74.                 return;
  75.         }
  76.  
  77.         if (d.date >= ALGERON && !isviolreported)
  78.         {
  79.                 prout("Spock- \"Captain, using the cloaking device is be a violation");
  80.                 prout("  of the Treaty of Algeron. Considering the alternatives,");
  81.                 proutn("  are you sure this is wise?");
  82.                 if (ja()==0) return;
  83.         }
  84.  
  85.         prout("Engineer Scott- \"The cloaking device has been engaged, Sir.\"");
  86.         iscloaking = TRUE;
  87.     if (irhere && d.date >= ALGERON && !isviolreported) {
  88.         prout("The Romulan ship discovers you are breaking the Treaty of Algeron!");
  89.         ncviol++;
  90.         isviolreported = TRUE;
  91.     }
  92. }
  93. #endif
  94.  
  95. void sheild(int i) {
  96.         int key;
  97.         enum {NONE, SHUP, SHDN, NRG} action = NONE;
  98.  
  99.         ididit = 0;
  100.  
  101.         if (i == 2) action = SHUP;
  102.         else {
  103.                 key = scan();
  104.                 if (key == IHALPHA) {
  105.                         if (isit("transfer"))
  106.                                 action = NRG;
  107.                         else {
  108.                                 chew();
  109.                                 if (damage[DSHIELD]) {
  110.                                         prout("Shields damaged and down.");
  111.                                         return;
  112.                                 }
  113.                                 if (isit("up"))
  114.                                         action = SHUP;
  115.                                 else if (isit("down"))
  116.                                         action = SHDN;
  117.                         }
  118.                 }
  119.                 if (action==NONE) {
  120.                         proutn("Do you wish to change shield energy? ");
  121.                         if (ja()) {
  122.                                 proutn("Energy to transfer to shields- ");
  123.                                 action = NRG;
  124.                         }
  125.                         else if (damage[DSHIELD]) {
  126.                                 prout("Shields damaged and down.");
  127.                                 return;
  128.                         }
  129.                         else if (shldup) {
  130.                                 proutn("Shields are up. Do you want them down? ");
  131.                                 if (ja()) action = SHDN;
  132.                                 else {
  133.                                         chew();
  134.                                         return;
  135.                                 }
  136.                         }
  137.                         else {
  138.                                 proutn("Shields are down. Do you want them up? ");
  139.                                 if (ja()) action = SHUP;
  140.                                 else {
  141.                                         chew();
  142.                                         return;
  143.                                 }
  144.                         }
  145.                 }
  146.         }
  147.         switch (action) {
  148.                 case SHUP: /* raise shields */
  149.                         if (shldup) {
  150.                                 prout("Shields already up.");
  151.                                 return;
  152.                         }
  153.                         shldup = 1;
  154.                         shldchg = 1;
  155.                         if (condit != IHDOCKED) energy -= 50.0;
  156.                         prout("Shields raised.");
  157.                         if (energy <= 0) {
  158.                                 skip(1);
  159.                                 prout("Shields raising uses up last of energy.");
  160.                                 finish(FNRG);
  161.                                 return;
  162.                         }
  163.                         ididit=1;
  164.                         return;
  165.                 case SHDN:
  166.                         if (shldup==0) {
  167.                                 prout("Shields already down.");
  168.                                 return;
  169.                         }
  170.                         shldup=0;
  171.                         shldchg=1;
  172.                         prout("Shields lowered.");
  173.                         ididit=1;
  174.                         return;
  175.                 case NRG:
  176.                         while (scan() != IHREAL) {
  177.                                 chew();
  178.                                 proutn("Energy to transfer to shields- ");
  179.                         }
  180.                         chew();
  181.                         if (aaitem==0) return;
  182.                         if (aaitem > energy) {
  183.                                 prout("Insufficient ship energy.");
  184.                                 return;
  185.                         }
  186.                         ididit = 1;
  187.                         if (shield+aaitem >= inshld) {
  188.                                 prout("Shield energy maximized.");
  189.                                 if (shield+aaitem > inshld) {
  190.                                         prout("Excess energy requested returned to ship energy");
  191.                                 }
  192.                                 energy -= inshld-shield;
  193.                                 shield = inshld;
  194.                                 return;
  195.                         }
  196.                         if (aaitem < 0.0 && energy-aaitem > inenrg) {
  197.                                 /* Prevent shield drain loophole */
  198.                                 skip(1);
  199.                                 prout("Engineering to bridge--");
  200.                                 prout("  Scott here. Power circuit problem, Captain.");
  201.                                 prout("  I can't drain the shields.");
  202.                                 ididit = 0;
  203.                                 return;
  204.                         }
  205.                         if (shield+aaitem < 0) {
  206.                                 prout("All shield energy transferred to ship.");
  207.                                 energy += shield;
  208.                                 shield = 0.0;
  209.                                 return;
  210.                         }
  211.                         proutn("Scotty- \"");
  212.                         if (aaitem > 0)
  213.                                 prout("Transferring energy to shields.\"");
  214.                         else
  215.                                 prout("Draining energy from shields.\"");
  216.                         shield += aaitem;
  217.                         energy -= aaitem;
  218.                         return;
  219.                 case NONE: break;
  220.         }
  221. }
  222.  
  223. void ram(int ibumpd, int ienm, int ix, int iy) {
  224.         double type = 1.0, extradm;
  225.         int icas, l;
  226.        
  227.         prouts("***RED ALERT!  RED ALERT!");
  228.         skip(1);
  229.         prout("***COLLISION IMMINENT.");
  230.         skip(2);
  231.         proutn("***");
  232.         crmshp();
  233.         switch (ienm) {
  234.                 case IHR: type = 1.5; break;
  235.                 case IHC: type = 2.0; break;
  236.                 case IHS: type = 2.5; break;
  237.                 case IHT: type = 0.5; break;
  238.         }
  239.         proutn(ibumpd ? " rammed by " : " rams ");
  240.         crmena(0, ienm, 2, ix, iy);
  241.         if (ibumpd) proutn(" (original position)");
  242.         skip(1);
  243.         deadkl(ix, iy, ienm, sectx, secty);
  244.         proutn("***");
  245.         crmshp();
  246.         prout(" heavily damaged.");
  247.         icas = 10.0+20.0*Rand();
  248.         proutn("***Sickbay reports ");
  249.         crami(icas, 1);
  250.         prout(" casualties.");
  251.         casual += icas;
  252.         for (l=1; l <= ndevice; l++) {
  253.                 if (l == DDRAY) continue; // Don't damage deathray
  254.                 if (damage[l] < 0) continue;
  255.                 extradm = (10.0*type*Rand()+1.0)*damfac;
  256.                 damage[l] += Time + extradm; /* Damage for at least time of travel! */
  257.         }
  258.         shldup = 0;
  259.         if (d.remkl) {
  260.                 pause(2);
  261.                 dreprt();
  262.         }
  263.         else finish(FWON);
  264.         return;
  265. }
  266.  
  267. void torpedo(double course, double r, int inx, int iny, double *hit) {
  268.         int l, iquad, ix, iy,  jx, jy, shoved=0, ll;
  269.         double ac=course + 0.25*r;
  270.         double angle = (15.0-ac)*0.5235988;
  271.         double bullseye = (15.0 - course)*0.5235988;
  272.         double deltax=-sin(angle), deltay=cos(angle), x=inx, y=iny, bigger;
  273.         double ang, temp, xx, yy, kp, h1;
  274.  
  275.         bigger = fabs(deltax);
  276.         if (fabs(deltay) > bigger) bigger = fabs(deltay);
  277.         deltax /= bigger;
  278.         deltay /= bigger;
  279.  
  280.         /* Loop to move a single torpedo */
  281.         for (l=1; l <= 15; l++) {
  282.                 x += deltax;
  283.                 ix = x + 0.5;
  284.                 if (ix < 1 || ix > 10) break;
  285.                 y += deltay;
  286.                 iy = y + 0.5;
  287.                 if (iy < 1 || iy > 10) break;
  288.                 if (l==4 || l==9) skip(1);
  289.                 cramf(x, 0, 1);
  290.                 proutn(" - ");
  291.                 cramf(y, 0, 1);
  292.                 proutn("   ");
  293.                 iquad=quad[ix][iy];
  294.                 if (iquad==IHDOT) continue;
  295.                 /* hit something */
  296.                 skip(1);
  297.                 switch(iquad) {
  298.                         case IHE: /* Hit our ship */
  299.                         case IHF:
  300.                                 skip(1);
  301.                                 proutn("Torpedo hits ");
  302.                                 crmshp();
  303.                                 prout(".");
  304.                                 *hit = 700.0 + 100.0*Rand() -
  305.                                            1000.0*sqrt(square(ix-inx)+square(iy-iny))*
  306.                                            fabs(sin(bullseye-angle));
  307.                                 *hit = fabs(*hit);
  308.                                 newcnd(); /* undock */
  309.                                 /* We may be displaced. */
  310.                                 if (landed==1) return; /* Cheat if on a planet */
  311.                                 ang = angle + 2.5*(Rand()-0.5);
  312.                                 temp = fabs(sin(ang));
  313.                                 if (fabs(cos(ang)) > temp) temp = fabs(cos(ang));
  314.                                 xx = -sin(ang)/temp;
  315.                                 yy = cos(ang)/temp;
  316.                                 jx=ix+xx+0.5;
  317.                                 jy=iy+yy+0.5;
  318.                                 if (jx<1 || jx>10 || jy<1 ||jy > 10) return;
  319.                                 if (quad[jx][jy]==IHBLANK) {
  320.                                         finish(FHOLE);
  321.                                         return;
  322.                                 }
  323.                                 if (quad[jx][jy]!=IHDOT) {
  324.                                         /* can't move into object */
  325.                                         return;
  326.                                 }
  327.                                 sectx = jx;
  328.                                 secty = jy;
  329.                                 crmshp();
  330.                                 shoved = 1;
  331.                                 break;
  332.                                          
  333.                         case IHC: /* Hit a commander */
  334.                         case IHS:
  335.                                 if (Rand() <= 0.05) {
  336.                                         crmena(1, iquad, 2, ix, iy);
  337.                                         prout(" uses anti-photon device;");
  338.                                         prout("   torpedo neutralized.");
  339.                                         return;
  340.                                 }
  341.                         case IHR: /* Hit a regular enemy */
  342.                         case IHK:
  343.                                 /* find the enemy */
  344.                                 for (ll=1; ll <= nenhere; ll++)
  345.                                         if (ix==kx[ll] && iy==ky[ll]) break;
  346.                                 kp = fabs(kpower[ll]);
  347.                                 h1 = 700.0 + 100.0*Rand() -
  348.                                          1000.0*sqrt(square(ix-inx)+square(iy-iny))*
  349.                                          fabs(sin(bullseye-angle));
  350.                                 h1 = fabs(h1);
  351.                                 if (kp < h1) h1 = kp;
  352.                                 kpower[ll] -= (kpower[ll]<0 ? -h1 : h1);
  353.                                 if (kpower[ll] == 0) {
  354.                                         deadkl(ix, iy, iquad, ix, iy);
  355.                                         return;
  356.                                 }
  357.                                 crmena(1, iquad, 2, ix, iy);
  358.                                 /* If enemy damaged but not destroyed, try to displace */
  359.                                 ang = angle + 2.5*(Rand()-0.5);
  360.                                 temp = fabs(sin(ang));
  361.                                 if (fabs(cos(ang)) > temp) temp = fabs(cos(ang));
  362.                                 xx = -sin(ang)/temp;
  363.                                 yy = cos(ang)/temp;
  364.                                 jx=ix+xx+0.5;
  365.                                 jy=iy+yy+0.5;
  366.                                 if (jx<1 || jx>10 || jy<1 ||jy > 10) {
  367.                                         prout(" damaged but not destroyed.");
  368.                                         return;
  369.                                 }
  370.                                 if (quad[jx][jy]==IHBLANK) {
  371.                                         prout(" buffeted into black hole.");
  372.                                         deadkl(ix, iy, iquad, jx, jy);
  373.                                         return;
  374.                                 }
  375.                                 if (quad[jx][jy]!=IHDOT) {
  376.                                         /* can't move into object */
  377.                                         prout(" damaged but not destroyed.");
  378.                                         return;
  379.                                 }
  380.                                 prout(" damaged--");
  381.                                 kx[ll] = jx;
  382.                                 ky[ll] = jy;
  383.                                 shoved = 1;
  384.                                 break;
  385.                         case IHB: /* Hit a base */
  386.                                 prout("***STARBASE DESTROYED..");
  387.                                 if (starch[quadx][quady] < 0) starch[quadx][quady] = 0;
  388.                                 for (ll=1; ll<=d.rembase; ll++) {
  389.                                         if (d.baseqx[ll]==quadx && d.baseqy[ll]==quady) {
  390.                                                 d.baseqx[ll]=d.baseqx[d.rembase];
  391.                                                 d.baseqy[ll]=d.baseqy[d.rembase];
  392.                                                 break;
  393.                                         }
  394.                                 }
  395.                                 quad[ix][iy]=IHDOT;
  396.                                 d.rembase--;
  397.                                 basex=basey=0;
  398.                                 d.galaxy[quadx][quady] -= 10;
  399.                                 d.basekl++;
  400.                                 newcnd();
  401.                                 return;
  402.                         case IHP: /* Hit a planet */
  403.                                 crmena(1, iquad, 2, ix, iy);
  404.                                 prout(" destroyed.");
  405.                                 d.nplankl++;
  406.                                 d.newstuf[quadx][quady] -= 1;
  407.                                 d.plnets[iplnet] = nulplanet;
  408.                                 iplnet = 0;
  409.                                 plnetx = plnety = 0;
  410.                                 quad[ix][iy] = IHDOT;
  411.                                 if (landed==1) {
  412.                                         /* captain parishes on planet */
  413.                                         finish(FDPLANET);
  414.                                 }
  415.                                 return;
  416.                         case IHSTAR: /* Hit a star */
  417.                                 if (Rand() > 0.10) {
  418.                                         nova(ix, iy);
  419.                                         return;
  420.                                 }
  421.                                 crmena(1, IHSTAR, 2, ix, iy);
  422.                                 prout(" unaffected by photon blast.");
  423.                                 return;
  424.                         case IHQUEST: /* Hit a thingy */
  425.                                 skip(1);
  426.                                 prouts("AAAAIIIIEEEEEEEEAAAAAAAAUUUUUGGGGGHHHHHHHHHHHH!!!");
  427.                                 skip(1);
  428.                                 prouts("    HACK!     HACK!    HACK!        *CHOKE!*  ");
  429.                                 skip(1);
  430.                                 proutn("Mr. Spock-");
  431.                                 prouts("  \"Facinating!\"");
  432.                                 skip(1);
  433.                                 quad[ix][iy] = IHDOT;
  434.                                 return;
  435.                         case IHBLANK: /* Black hole */
  436.                                 skip(1);
  437.                                 crmena(1, IHBLANK, 2, ix, iy);
  438.                                 prout(" swallows torpedo.");
  439.                                 return;
  440.                         case IHWEB: /* hit the web */
  441.                                 skip(1);
  442.                                 prout("***Torpedo absorbed by Tholian web.");
  443.                                 return;
  444.                         case IHT:  /* Hit a Tholian */
  445.                                 skip(1);
  446.                                 crmena(1, IHT, 2, ix, iy);
  447.                                 h1 = 700.0 + 100.0*Rand() -
  448.                                          1000.0*sqrt(square(ix-inx)+square(iy-iny))*
  449.                                          fabs(sin(bullseye-angle));
  450.                                 h1 = fabs(h1);
  451.                                 if (h1 >= 600) {
  452.                                         prout(" destroyed.");
  453.                                         quad[ix][iy] = IHDOT;
  454.                                         ithere = 0;
  455.                                         ithx = ithy = 0;
  456.                                         return;
  457.                                 }
  458.                                 if (Rand() > 0.05) {
  459.                                         prout(" survives photon blast.");
  460.                                         return;
  461.                                 }
  462.                                 prout(" disappears.");
  463.                                 quad[ix][iy] = IHWEB;
  464.                                 ithere = ithx = ithy = 0;
  465.                                 {
  466.                                         int dum, my;
  467.                                         dropin(IHBLANK, &dum, &my);
  468.                                 }
  469.                                 return;
  470.                                        
  471.                         default: /* Problem! */
  472.                                 skip(1);
  473.                                 proutn("Don't know how to handle collision with ");
  474.                                 crmena(1, iquad, 2, ix, iy);
  475.                                 skip(1);
  476.                                 return;
  477.                 }
  478.                 break;
  479.         }
  480.         if (shoved) {
  481.                 quad[jx][jy]=iquad;
  482.                 quad[ix][iy]=IHDOT;
  483.                 proutn(" displaced by blast to");
  484.                 cramlc(2, jx, jy);
  485.                 skip(1);
  486.                 for (ll=1; ll<=nenhere; ll++)
  487.                         kdist[ll] = kavgd[ll] = sqrt(square(sectx-kx[ll])+square(secty-ky[ll]));
  488.                 sortkl();
  489.                 return;
  490.         }
  491.         skip(1);
  492.         prout("Torpedo missed.");
  493.         return;
  494. }
  495.  
  496. static void fry(double hit) {
  497.         double ncrit, extradm;
  498.         int ktr=1, l, ll, j, cdam[6], crptr;
  499.  
  500.         /* a critical hit occured */
  501.         if (hit < (275.0-25.0*skill)*(1.0+0.5*Rand())) return;
  502.  
  503.         ncrit = 1.0 + hit/(500.0+100.0*Rand());
  504.         proutn("***CRITICAL HIT--");
  505.         /* Select devices and cause damage */
  506.         for (l = 1; l <= ncrit; l++) {
  507.                 do {
  508.                         j = ndevice*Rand()+1.0;
  509.                         /* Cheat to prevent shuttle damage unless on ship */
  510.                 } while (damage[j] < 0.0 || (j == DSHUTTL && iscraft != 1) ||
  511. #ifdef CLOAKING
  512.                                  (j == DCLOAK && ship != IHE) ||
  513. #endif
  514.                                  j == DDRAY);
  515.                 cdam[l] = j;
  516.                 extradm = (hit*damfac)/(ncrit*(75.0+25.0*Rand()));
  517.                 damage[j] += extradm;
  518.                 if (l > 1) {
  519.                         for (ll=2; ll<=l && j != cdam[ll-1]; ll++) ;
  520.                         if (ll<=l) continue;
  521.                         ktr += 1;
  522.                         if (ktr==3) skip(1);
  523.                         proutn(" and ");
  524.                 }
  525.                 proutn(device[j]);
  526.         }
  527.         prout(" damaged.");
  528.         if (damage[DSHIELD] && shldup) {
  529.                 prout("***Shields knocked down.");
  530.                 shldup=0;
  531.         }
  532. #ifdef CLOAKING
  533.         if (damage[DCLOAK] && iscloaked)
  534.         {
  535.                 prout("***Cloaking device rendered inoperative.");
  536.                 iscloaked = FALSE;
  537.         }
  538. #endif
  539. }
  540.  
  541. void attack(int k) {
  542.         /* k == 0 forces use of phasers in an attack */
  543.         int percent, ihurt=0, l, i=0, jx, jy, iquad, itflag;
  544.         int atackd = 0, attempt = 0;
  545.         double hit;
  546.         double pfac, dustfac, hitmax=0.0, hittot=0.0, chgfac=1.0, r;
  547.  
  548. #ifdef CLOAKING
  549.     if (iscloaked && !iscloaking) return; // Nothing happens if we are cloaked
  550. #endif
  551.    
  552.         iattak = 1;
  553.         if (alldone) return;
  554. #ifdef DEBUG
  555.         if (idebug) prout("ATTACK!");
  556. #endif
  557.  
  558.         if (ithere) movetho();
  559.  
  560.         if (neutz) { /* The one chance not to be attacked */
  561.                 neutz = 0;
  562.                 return;
  563.         }
  564.         if (((comhere || ishere) && (justin == 0)) || skill == SEMERITUS) movcom();
  565.         if (nenhere==0) return;
  566.         pfac = 1.0/inshld;
  567.         if (shldchg == 1) chgfac = 0.25+0.5*Rand();
  568.         skip(1);
  569.         if (skill <= SFAIR) i = 2;
  570.         for (l=1; l <= nenhere; l++) {
  571.                 if (kpower[l] < 0) continue;    /* too weak to attack */
  572.                 /* compute hit strength and diminsh shield power */
  573.                 r = Rand();
  574.                 /* Increase chance of photon torpedos if docked or enemy energy low */
  575.                 if (condit == IHDOCKED) r *= 0.25;
  576.                 if (kpower[l] < 500) r *= 0.25;
  577.                 jx = kx[l];
  578.                 jy = ky[l];
  579.                 iquad = quad[jx][jy];
  580.                 itflag = (iquad == IHK && r > 0.0005) || k == 0 ||
  581.                         (iquad==IHC && r > 0.015) ||
  582.                         (iquad==IHR && r > 0.3) ||
  583.                         (iquad==IHS && r > 0.07);
  584.                 if (itflag) {
  585.                         /* Enemy uses phasers */
  586.                         if (condit == IHDOCKED) continue; /* Don't waste the effort! */
  587.                         attempt = 1; /* Attempt to attack */
  588.                         dustfac = 0.8+0.05*Rand();
  589.                         hit = kpower[l]*pow(dustfac,kavgd[l]);
  590.                         kpower[l] *= 0.75;
  591.                 }
  592.                 else { /* Enemy used photon torpedo */
  593.                         double course = 1.90985*atan2((double)secty-jy, (double)jx-sectx);
  594.                         hit = 0;
  595.                         proutn("***TORPEDO INCOMING");
  596.                         if (damage[DSRSENS] <= 0.0) {
  597.                                 proutn(" From ");
  598.                                 crmena(0, iquad, i, jx, jy);
  599.                         }
  600.                         attempt = 1;
  601.                         prout("--");
  602.                         r = (Rand()+Rand())*0.5 -0.5;
  603.                         r += 0.002*kpower[l]*r;
  604.                         torpedo(course, r, jx, jy, &hit);
  605.                         if (d.remkl==0) finish(FWON); /* Klingons did themselves in! */
  606.                         if (d.galaxy[quadx][quady] == 1000 ||
  607.                                 alldone) return; /* Supernova or finished */
  608.                         if (hit == 0) continue;
  609.                 }
  610.                 if (shldup != 0 || shldchg != 0) {
  611.                         /* shields will take hits */
  612.                         double absorb, hitsh, propor = pfac*shield;
  613.                         if(propor < 0.1) propor = 0.1;
  614.                         hitsh = propor*chgfac*hit+1.0;
  615.                         atackd=1;
  616.                         absorb = 0.8*hitsh;
  617.                         if (absorb > shield) absorb = shield;
  618.                         shield -= absorb;
  619.                         hit -= hitsh;
  620.                         if (propor > 0.1 && hit < 0.005*energy) continue;
  621.                 }
  622.                 /* It's a hit -- print out hit size */
  623.                 atackd = 1; /* We weren't going to check casualties, etc. if
  624.                                shields were down for some strange reason. This
  625.                                            doesn't make any sense, so I've fixed it */
  626.                 ihurt = 1;
  627.                 cramf(hit, 0, 2);
  628.                 proutn(" unit hit");
  629.                 if ((damage[DSRSENS] > 0 && itflag) || skill <= SFAIR) {
  630.                         proutn(" on the ");
  631.                         crmshp();
  632.                 }
  633.                 if (damage[DSRSENS] <= 0.0 && itflag) {
  634.                         proutn(" from ");
  635.                         crmena(0, iquad, i, jx, jy);
  636.                 }
  637.                 skip(1);
  638.                 /* Decide if hit is critical */
  639.                 if (hit > hitmax) hitmax = hit;
  640.                 hittot += hit;
  641.                 fry(hit);
  642.                 printf("Hit %g energy %g\n", hit, energy);
  643.                 energy -= hit;
  644.         }
  645.         if (energy <= 0) {
  646.                 /* Returning home upon your shield, not with it... */
  647.                 finish(FBATTLE);
  648.                 return;
  649.         }
  650.         if (attempt == 0 && condit == IHDOCKED)
  651.                 prout("***Enemies decide against attacking your ship.");
  652.         if (atackd == 0) return;
  653.         percent = 100.0*pfac*shield+0.5;
  654.         if (ihurt==0) {
  655.                 /* Shields fully protect ship */
  656.                 proutn("Enemy attack reduces shield strength to ");
  657.         }
  658.         else {
  659.                 /* Print message if starship suffered hit(s) */
  660.                 skip(1);
  661.                 proutn("Energy left ");
  662.                 cramf(energy, 0, 2);
  663.                 proutn("    shields ");
  664.                 if (shldup) proutn("up, ");
  665.                 else if (damage[DSHIELD] == 0) proutn("down, ");
  666.                 else proutn("damaged, ");
  667.         }
  668.         crami(percent, 1);
  669.         proutn("%   torpedoes left ");
  670.         crami(torps, 1);
  671.         skip(1);
  672.         /* Check if anyone was hurt */
  673.         if (hitmax >= 200 || hittot >= 500) {
  674.                 int icas= hittot*Rand()*0.015;
  675.                 if (icas >= 2) {
  676.                         skip(1);
  677.                         proutn("Mc Coy-  \"Sickbay to bridge.  We suffered ");
  678.                         crami(icas, 1);
  679.                         prout(" casualties");
  680.                         prout("   in that last attack.\"");
  681.                         casual += icas;
  682.                 }
  683.         }
  684.         /* After attack, reset average distance to enemies */
  685.         for (l = 1; l <= nenhere; l++)
  686.                 kavgd[l] = kdist[l];
  687.         sortkl();
  688.         return;
  689. }
  690.                
  691. void deadkl(int ix, int iy, int type, int ixx, int iyy) {
  692.         /* Added ixx and iyy allow enemy to "move" before dying */
  693.  
  694.         int i,j;
  695.        
  696.         crmena(1, type, 2, ixx, iyy);
  697.         /* Decide what kind of enemy it is and update approriately */
  698.         if (type == IHR) {
  699.                 /* chalk up a Romulan */
  700.                 d.newstuf[quadx][quady] -= 10;
  701.                 irhere--;
  702.                 d.nromkl++;
  703.                 d.nromrem--;
  704.         }
  705.         else if (type == IHT) {
  706.                 /* Killed a Tholean */
  707.                 ithere = 0;
  708.         }
  709.         else {
  710.                 /* Some type of a Klingon */
  711.                 d.galaxy[quadx][quady] -= 100;
  712.                 klhere--;
  713.                 d.remkl--;
  714.                 switch (type) {
  715.                         case IHC:
  716.                                 comhere = 0;
  717.                                 for (i=1; i<=d.remcom; i++)
  718.                                         if (d.cx[i]==quadx && d.cy[i]==quady) break;
  719.                                 d.cx[i] = d.cx[d.remcom];
  720.                                 d.cy[i] = d.cy[d.remcom];
  721.                                 d.cx[d.remcom] = 0;
  722.                                 d.cy[d.remcom] = 0;
  723.                                 d.remcom--;
  724.                                 future[FTBEAM] = 1e30;
  725.                                 if (d.remcom != 0)
  726.                                         future[FTBEAM] = d.date + expran(1.0*incom/d.remcom);
  727.                                 d.killc++;
  728.                                 break;
  729.                         case IHK:
  730.                                 d.killk++;
  731.                                 break;
  732.                         case IHS:
  733.                                 d.nscrem = ishere = d.isx = d.isy = isatb = iscate = 0;
  734.                                 d.nsckill = 1;
  735.                                 future[FSCMOVE] = future[FSCDBAS] = 1e30;
  736.                                 break;
  737.                 }
  738.         }
  739.  
  740.         /* For each kind of enemy, finish message to player */
  741.         prout(" destroyed.");
  742.         quad[ix][iy] = IHDOT;
  743.         if (d.remkl==0) return;
  744.  
  745.         d.remtime = d.remres/(d.remkl + 4*d.remcom);
  746.  
  747.         if (type == IHT) return;
  748.  
  749.         /* Remove enemy ship from arrays describing local conditions */
  750.  
  751.         for (i=1; i<=nenhere; i++)
  752.                 if (kx[i]==ix && ky[i]==iy) break;
  753.         nenhere--;
  754.         if (i <= nenhere)  {
  755.                 for (j=i; j<=nenhere; j++) {
  756.                         kx[j] = kx[j+1];
  757.                         ky[j] = ky[j+1];
  758.                         kpower[j] = kpower[j+1];
  759.                         kavgd[j] = kdist[j] = kdist[j+1];
  760.                 }
  761.         }
  762.         kx[nenhere+1] = 0;
  763.         ky[nenhere+1] = 0;
  764.         kdist[nenhere+1] = 0;
  765.         kavgd[nenhere+1] = 0;
  766.         kpower[nenhere+1] = 0;
  767.         return;
  768. }
  769.  
  770. static int targetcheck(double x, double y, double *course) {
  771.         double deltx, delty;
  772.         /* Return TRUE if target is invalid */
  773.         if (x < 1.0 || x > 10.0 || y < 1.0 || y > 10.0) {
  774.                 huh();
  775.                 return 1;
  776.         }
  777.         deltx = 0.1*(y - secty);
  778.         delty = 0.1*(sectx - x);
  779.         if (deltx==0 && delty== 0) {
  780.                 skip(1);
  781.                 prout("Spock-  \"Bridge to sickbay.  Dr. McCoy,");
  782.                 prout("  I recommend an immediate review of");
  783.                 prout("  the Captain's psychological profile.");
  784.                 chew();
  785.                 return 1;
  786.         }
  787.         *course = 1.90985932*atan2(deltx, delty);
  788.         return 0;
  789. }
  790.  
  791. void photon(void) {
  792.         double targ[4][3], course[4];
  793.         double r, dummy;
  794.         int key, n, i, osuabor;
  795.  
  796.         ididit = 0;
  797.  
  798.         if (damage[DPHOTON]) {
  799.                 prout("Photon tubes damaged.");
  800.                 chew();
  801.                 return;
  802.         }
  803.         if (torps == 0) {
  804.                 prout("No torpedoes left.");
  805.                 chew();
  806.                 return;
  807.         }
  808.         key = scan();
  809.         for (;;) {
  810.                 if (key == IHALPHA) {
  811.                         huh();
  812.                         return;
  813.                 }
  814.                 else if (key == IHEOL) {
  815.                         crami(torps,1);
  816.                         prout(" torpedoes left.");
  817.                         proutn("Number of torpedoes to fire- ");
  818.                         key = scan();
  819.                 }
  820.                 else /* key == IHREAL */ {
  821.                         n = aaitem + 0.5;
  822.                         if (n <= 0) { /* abort command */
  823.                                 chew();
  824.                                 return;
  825.                         }
  826.                         if (n > 3) {
  827.                                 prout("Maximum of 3 torpedoes per burst.");
  828.                         } else if (n <= torps) break;
  829.                         chew();
  830.                         key = IHEOL;
  831.                 }
  832.         }
  833.         for (i = 1; i <= n; i++) {
  834.                 key = scan();
  835.                 if (i==1 && key == IHEOL) {
  836.                         break;  /* we will try prompting */
  837.                 }
  838.                 if (i==2 && key == IHEOL) {
  839.                         /* direct all torpedoes at one target */
  840.                         while (i <= n) {
  841.                                 targ[i][1] = targ[1][1];
  842.                                 targ[i][2] = targ[1][2];
  843.                                 course[i] = course[1];
  844.                                 i++;
  845.                         }
  846.                         break;
  847.                 }
  848.                 if (key != IHREAL) {
  849.                         huh();
  850.                         return;
  851.                 }
  852.                 targ[i][1] = aaitem;
  853.                 key = scan();
  854.                 if (key != IHREAL) {
  855.                         huh();
  856.                         return;
  857.                 }
  858.                 targ[i][2] = aaitem;
  859.                 if (targetcheck(targ[i][1], targ[i][2], &course[i])) return;
  860.         }
  861.         chew();
  862.         if (i == 1 && key == IHEOL) {
  863.                 /* prompt for each one */
  864.                 for (i = 1; i <= n; i++) {
  865.                         proutn("Target sector for torpedo number");
  866.                         crami(i, 2);
  867.                         proutn("- ");
  868.                         key = scan();
  869.                         if (key != IHREAL) {
  870.                                 huh();
  871.                                 return;
  872.                         }
  873.                         targ[i][1] = aaitem;
  874.                         key = scan();
  875.                         if (key != IHREAL) {
  876.                                 huh();
  877.                                 return;
  878.                         }
  879.                         targ[i][2] = aaitem;
  880.                         chew();
  881.                         if (targetcheck(targ[i][1], targ[i][2], &course[i])) return;
  882.                 }
  883.         }
  884.         ididit = 1;
  885.         /* Loop for moving <n> torpedoes */
  886.         osuabor = 0;
  887.         for (i = 1; i <= n && !osuabor; i++) {
  888.                 if (condit != IHDOCKED) torps--;
  889.                 r = (Rand()+Rand())*0.5 -0.5;
  890.                 if (fabs(r) >= 0.47) {
  891.                         /* misfire! */
  892.                         r = (Rand()+1.2) * r;
  893.                         if (n>1) {
  894.                                 prouts("***TORPEDO NUMBER");
  895.                                 crami(i, 2);
  896.                                 prouts(" MISFIRES.");
  897.                         }
  898.                         else prouts("***TORPEDO MISFIRES.");
  899.                         skip(1);
  900.                         if (i < n)
  901.                                 prout("  Remainder of burst aborted.");
  902.                         osuabor=1;
  903.                         if (Rand() <= 0.2) {
  904.                                 prout("***Photon tubes damaged by misfire.");
  905.                                 damage[DPHOTON] = damfac*(1.0+2.0*Rand());
  906.                                 break;
  907.                         }
  908.                 }
  909. #ifdef CLOAKING
  910.                 if (iscloaked) r *= 1.2; /* Torpedoes are less accurate */
  911.                 else
  912. #endif
  913.                 if (shldup != 0 || condit == IHDOCKED) r *= 1.0 + 0.0001*shield; /* Torpedos are less accurate */
  914.  
  915.                 if (n != 1) {
  916.                         skip(1);
  917.                         proutn("Track for torpedo number");
  918.                         crami(i, 2);
  919.                         proutn("-   ");
  920.                 }
  921.                 else {
  922.                         skip(1);
  923.                         proutn("Torpedo track- ");
  924.                 }
  925.                 torpedo(course[i], r, sectx, secty, &dummy);
  926.                 if (alldone || d.galaxy[quadx][quady]==1000) return;
  927.         }
  928.         if (d.remkl==0) finish(FWON);
  929. }
  930.  
  931.        
  932.  
  933. static void overheat(double rpow) {
  934.         if (rpow > 1500) {
  935.                 double chekbrn = (rpow-1500.)*0.00038;
  936.                 if (Rand() <= chekbrn) {
  937.                         prout("Weapons officer Sulu-  \"Phasers overheated, sir.\"");
  938.                         damage[DPHASER] = damfac*(1.0 + Rand()) * (1.0+chekbrn);
  939.                 }
  940.         }
  941. }
  942.  
  943. static int checkshctrl(double rpow) {
  944.         double hit;
  945.         int icas;
  946.        
  947.         skip(1);
  948.         if (Rand() < .998) {
  949.                 prout("Shields lowered.");
  950.                 return 0;
  951.         }
  952.         /* Something bad has happened */
  953.         prouts("***RED ALERT!  RED ALERT!");
  954.         skip(2);
  955.         hit = rpow*shield/inshld;
  956.         energy -= rpow+hit*0.8;
  957.         shield -= hit*0.2;
  958.         if (energy <= 0.0) {
  959.                 prouts("Sulu-  \"Captain! Shield malf***********************\"");
  960.                 skip(1);
  961.                 stars();
  962.                 finish(FPHASER);
  963.                 return 1;
  964.         }
  965.         prouts("Sulu-  \"Captain! Shield malfunction! Phaser fire contained!\"");
  966.         skip(2);
  967.         prout("Lt. Uhura-  \"Sir, all decks reporting damage.\"");
  968.         icas = hit*Rand()*0.012;
  969.         skip(1);
  970.         fry(0.8*hit);
  971.         if (icas) {
  972.                 skip(1);
  973.                 prout("McCoy to bridge- \"Severe radiation burns, Jim.");
  974.                 proutn("  ");
  975.                 crami(icas, 1);
  976.                 prout(" casualties so far.\"");
  977.                 casual += icas; // Changed from -=, October 2013
  978.         }
  979.         skip(1);
  980.         prout("Phaser energy dispersed by shields.");
  981.         prout("Enemy unaffected.");
  982.         overheat(rpow);
  983.         return 1;
  984. }
  985.        
  986.  
  987. void phasers(void) {
  988.         double hits[21], rpow, extra, powrem, over, temp;
  989.         int kz = 0, k=1, i; /* Cheating inhibitor */
  990.         int ifast=0, no=0, ipoop=1, msgflag = 1;
  991.         enum {NOTSET, MANUAL, FORCEMAN, AUTOMATIC} automode = NOTSET;
  992.         int key;
  993.  
  994.         skip(1);
  995.         /* SR sensors and Computer */
  996.         if (damage[DSRSENS]+damage[DCOMPTR] > 0) ipoop = 0;
  997.         if (condit == IHDOCKED) {
  998.                 prout("Phasers can't be fired through base shields.");
  999.                 chew();
  1000.                 return;
  1001.         }
  1002.         if (damage[DPHASER] != 0) {
  1003.                 prout("Phaser control damaged.");
  1004.                 chew();
  1005.                 return;
  1006.         }
  1007.         if (shldup) {
  1008.                 if (damage[DSHCTRL]) {
  1009.                         prout("High speed shield control damaged.");
  1010.                         chew();
  1011.                         return;
  1012.                 }
  1013.                 if (energy <= 200.0) {
  1014.                         prout("Insufficient energy to activate high-speed shield control.");
  1015.                         chew();
  1016.                         return;
  1017.                 }
  1018.                 prout("Weapons Officer Sulu-  \"High-speed shield control enabled, sir.\"");
  1019.                 ifast = 1;
  1020.                
  1021.         }
  1022.         ididit = 1;
  1023.         /* Original code so convoluted, I re-did it all */
  1024.         while (automode==NOTSET) {
  1025.                 key=scan();
  1026.                 if (key == IHALPHA) {
  1027.                         if (isit("manual")) {
  1028.                                 if (nenhere==0) {
  1029.                                         prout("There is no enemy present to select.");
  1030.                                         chew();
  1031.                                         key = IHEOL;
  1032.                                         automode=AUTOMATIC;
  1033.                                 }
  1034.                                 else {
  1035.                                         automode = MANUAL;
  1036.                                         key = scan();
  1037.                                 }
  1038.                         }
  1039.                         else if (isit("automatic")) {
  1040.                                 if ((!ipoop) && nenhere != 0) {
  1041.                                         automode = FORCEMAN;
  1042.                                 }
  1043.                                 else {
  1044.                                         if (nenhere==0)
  1045.                                                 prout("Energy will be expended into space.");
  1046.                                         automode = AUTOMATIC;
  1047.                                         key = scan();
  1048.                                 }
  1049.                         }
  1050.                         else if (isit("no")) {
  1051.                                 no = 1;
  1052.                         }
  1053.                         else {
  1054.                                 huh();
  1055.                                 ididit = 0;
  1056.                                 return;
  1057.                         }
  1058.                 }
  1059.                 else if (key == IHREAL) {
  1060.                         if (nenhere==0) {
  1061.                                 prout("Energy will be expended into space.");
  1062.                                 automode = AUTOMATIC;
  1063.                         }
  1064.                         else if (!ipoop)
  1065.                                 automode = FORCEMAN;
  1066.                         else
  1067.                                 automode = AUTOMATIC;
  1068.                 }
  1069.                 else {
  1070.                         /* IHEOL */
  1071.                         if (nenhere==0) {
  1072.                                 prout("Energy will be expended into space.");
  1073.                                 automode = AUTOMATIC;
  1074.                         }
  1075.                         else if (!ipoop)
  1076.                                 automode = FORCEMAN;
  1077.                         else
  1078.                         proutn("Manual or automatic? ");
  1079.                 }
  1080.         }
  1081.                                
  1082.         switch (automode) {
  1083.                 case AUTOMATIC:
  1084.                         if (key == IHALPHA && isit("no")) {
  1085.                                 no = 1;
  1086.                                 key = scan();
  1087.                         }
  1088.                         if (key != IHREAL && nenhere != 0) {
  1089.                                 proutn("Phasers locked on target. Energy available =");
  1090.                                 cramf(ifast?energy-200.0:energy,1,2);
  1091.                                 skip(1);
  1092.                         }
  1093.                         do {
  1094.                                 while (key != IHREAL) {
  1095.                                         chew();
  1096.                                         proutn("Units to fire=");
  1097.                                         key = scan();
  1098.                                 }
  1099.                                 rpow = aaitem;
  1100.                                 if (rpow >= (ifast?energy-200:energy)) {
  1101.                                         proutn("Energy available= ");
  1102.                                         cramf(ifast?energy-200:energy, 1,2);
  1103.                                         skip(1);
  1104.                                         key = IHEOL;
  1105.                                 }
  1106.                         } while (rpow >= (ifast?energy-200:energy));
  1107.                         if (rpow<=0) {
  1108.                                 /* chicken out */
  1109.                                 ididit = 0;
  1110.                                 chew();
  1111.                                 return;
  1112.                         }
  1113.                         if ((key=scan()) == IHALPHA && isit("no")) {
  1114.                                 no = 1;
  1115.                         }
  1116.                         if (ifast) {
  1117.                                 energy -= 200; /* Go and do it! */
  1118.                                 if (checkshctrl(rpow)) return;
  1119.                         }
  1120.                         chew();
  1121.                         energy -= rpow;
  1122.                         extra = rpow;
  1123.                         if (nenhere) {
  1124.                                 extra = 0.0;
  1125.                                 powrem = rpow;
  1126.                                 for (i = 1; i <= nenhere; i++) {
  1127.                                         hits[i] = 0.0;
  1128.                                         if (powrem <= 0) continue;
  1129.                                         hits[i] = fabs(kpower[i])/(phasefac*pow(0.90,kdist[i]));
  1130.                                         over = (0.01 + 0.05*Rand())*hits[i];
  1131.                                         temp = powrem;
  1132.                                         powrem -= hits[i] + over;
  1133.                                         if (powrem <= 0 && temp < hits[i]) hits[i] = temp;
  1134.                                         if (powrem <= 0) over = 0.0;
  1135.                                         extra += over;
  1136.                                 }
  1137.                                 if (powrem > 0.0) extra += powrem;
  1138.                                 hittem(hits);
  1139.                         }
  1140.                         if (extra > 0 && alldone == 0) {
  1141.                                 if (ithere) {
  1142.                                         proutn("*** Tholian web absorbs ");
  1143.                                         if (nenhere>0) proutn("excess ");
  1144.                                         prout("phaser energy.");
  1145.                                 }
  1146.                                 else {
  1147.                                         cramf(extra, 0, 2);
  1148.                                         prout(" expended on empty space.");
  1149.                                 }
  1150.                         }
  1151.                         break;
  1152.  
  1153.                 case FORCEMAN:
  1154.                         chew();
  1155.                         key = IHEOL;
  1156.                         if (damage[DCOMPTR]!=0)
  1157.                                 prout("Battle computer damaged, manual file only.");
  1158.                         else {
  1159.                                 skip(1);
  1160.                                 prouts("---WORKING---");
  1161.                                 skip(1);
  1162.                                 prout("Short-range-sensors-damaged");
  1163.                                 prout("Insufficient-data-for-automatic-phaser-fire");
  1164.                                 prout("Manual-fire-must-be-used");
  1165.                                 skip(1);
  1166.                         }
  1167.                 case MANUAL:
  1168.                         rpow = 0.0;
  1169.                         for (k = 1; k <= nenhere;) {
  1170.                                 int ii = kx[k], jj = ky[k];
  1171.                                 int ienm = quad[ii][jj];
  1172.                                 if (msgflag) {
  1173.                                         proutn("Energy available= ");
  1174.                                         cramf(energy-.006-(ifast?200:0), 0, 2);
  1175.                                         skip(1);
  1176.                                         msgflag = 0;
  1177.                                         rpow = 0.0;
  1178.                                 }
  1179.                                 if (damage[DSRSENS] && !(abs(sectx-ii) < 2 && abs(secty-jj) < 2) &&
  1180.                                         (ienm == IHC || ienm == IHS)) {
  1181.                                         cramen(ienm);
  1182.                                         prout(" can't be located without short range scan.");
  1183.                                         chew();
  1184.                                         key = IHEOL;
  1185.                                         hits[k] = 0; /* prevent overflow -- thanks to Alexei Voitenko */
  1186.                                         k++;
  1187.                                         continue;
  1188.                                 }
  1189.                                 if (key == IHEOL) {
  1190.                                         chew();
  1191.                                         if (ipoop && k > kz) {
  1192.                                                 int irec=(fabs(kpower[k])/(phasefac*pow(0.9,kdist[k])))*
  1193.                                                                  (1.01+0.05*Rand()) + 1.0;
  1194.                                                 kz = k;
  1195.                                                 proutn("(");
  1196.                                                 crami(irec, 1);
  1197.                                                 proutn(")  ");
  1198.                                         }
  1199.                                         proutn("units to fire at ");
  1200.                                         crmena(0, ienm, 2, ii, jj);
  1201.                                         proutn("-  ");
  1202.                                         key = scan();
  1203.                                 }
  1204.                                 if (key == IHALPHA && isit("no")) {
  1205.                                         no = 1;
  1206.                                         key = scan();
  1207.                                         continue;
  1208.                                         }
  1209.                                 if (key == IHALPHA) {
  1210.                                         huh();
  1211.                                         ididit = 0;
  1212.                                         return;
  1213.                                 }
  1214.                                 if (key == IHEOL) {
  1215.                                         if (k==1) { /* Let me say I'm baffled by this */
  1216.                                                 msgflag = 1;
  1217.                                         }
  1218.                                         continue;
  1219.                                 }
  1220.                                 if (aaitem < 0) {
  1221.                                         /* abort out */
  1222.                                         ididit = 0;
  1223.                                         chew();
  1224.                                         return;
  1225.                                 }
  1226.                                 hits[k] = aaitem;
  1227.                                 rpow += aaitem;
  1228.                                 /* If total requested is too much, inform and start over */
  1229.                                
  1230.                                 if (rpow >= (ifast?energy-200:energy)) {
  1231.                                         prout("Available energy exceeded -- try again.");
  1232.                                         chew();
  1233.                                         key = IHEOL;
  1234.                                         k = 1;
  1235.                                         msgflag = 1;
  1236.                                         continue;
  1237.                                 }
  1238.                                 key = scan(); /* scan for next value */
  1239.                                 k++;
  1240.                         }
  1241.                         if (rpow == 0.0) {
  1242.                                 /* zero energy -- abort */
  1243.                                 ididit = 0;
  1244.                                 chew();
  1245.                                 return;
  1246.                         }
  1247.                         if (key == IHALPHA && isit("no")) {
  1248.                                 no = 1;
  1249.                         }
  1250.                         energy -= rpow;
  1251.                         chew();
  1252.                         if (ifast) {
  1253.                                 energy -= 200.0;
  1254.                                 if (checkshctrl(rpow)) return;
  1255.                         }
  1256.                         hittem(hits);
  1257.                         ididit=1;
  1258.                         break;
  1259.                         case NOTSET: break; // cannot occur
  1260.         }
  1261.         /* Say shield raised or malfunction, if necessary */
  1262.         if (alldone) return;
  1263.         if (ifast) {
  1264.                 skip(1);
  1265.                 if (no == 0) {
  1266.                         if (Rand() >= 0.99) {
  1267.                                 prout("Sulu-  \"Sir, the high-speed shield control has malfunctioned . . .");
  1268.                                 prouts("         CLICK   CLICK   POP  . . .");
  1269.                                 prout(" No  response, sir!");
  1270.                                 shldup = 0;
  1271.                         }
  1272.                         else
  1273.                                 prout("Shields raised.");
  1274.                 }
  1275.                 else
  1276.                         shldup = 0;
  1277.         }
  1278.         overheat(rpow);
  1279. }
  1280.  
  1281. void hittem(double *hits) {
  1282.         double kp, kpow, wham, hit, dustfac, kpini;
  1283.         int nenhr2=nenhere, k=1, kk=1, ii, jj, ienm;
  1284.  
  1285.         skip(1);
  1286.  
  1287.         for (; k <= nenhr2; k++, kk++) {
  1288.                 if ((wham = hits[k])==0) continue;
  1289.                 dustfac = 0.9 + 0.01*Rand();
  1290.                 hit = wham*pow(dustfac,kdist[kk]);
  1291.                 kpini = kpower[kk];
  1292.                 kp = fabs(kpini);
  1293.                 if (phasefac*hit < kp) kp = phasefac*hit;
  1294.                 kpower[kk] -= (kpower[kk] < 0 ? -kp: kp);
  1295.                 kpow = kpower[kk];
  1296.                 ii = kx[kk];
  1297.                 jj = ky[kk];
  1298.                 if (hit > 0.005) {
  1299.                         cramf(hit, 0, 2);
  1300.                         proutn(" unit hit on ");
  1301.                 }
  1302.                 else
  1303.                         proutn("Very small hit on ");
  1304.                 ienm = quad[ii][jj];
  1305.                 crmena(0,ienm,2,ii,jj);
  1306.                 skip(1);
  1307.                 if (kpow == 0) {
  1308.                         deadkl(ii, jj, ienm, ii, jj);
  1309.                         if (d.remkl==0) finish(FWON);
  1310.                         if (alldone) return;
  1311.                         kk--; /* don't do the increment */
  1312.                 }
  1313.                 else /* decide whether or not to emasculate klingon */
  1314.                         if (kpow > 0 && Rand() >= 0.9 &&
  1315.                                 kpow <= ((0.4 + 0.4*Rand())*kpini)) {
  1316.                                 proutn("***Mr. Spock-  \"Captain, the vessel at");
  1317.                                 cramlc(2,ii,jj);
  1318.                                 skip(1);
  1319.                                 prout("   has just lost its firepower.\"");
  1320.                                 kpower[kk] = -kpow;
  1321.                         }
  1322.         }
  1323.         return;
  1324. }
  1325.  
  1326. #ifdef CAPTURE
  1327. /*      $NetBSD: capture.c,v 1.6 2003/08/07 09:37:50 agc Exp $  */
  1328.  
  1329. /*
  1330.  * Copyright (c) 1980, 1993
  1331.  *      The Regents of the University of California.  All rights reserved.
  1332.  *
  1333.  * Redistribution and use in source and binary forms, with or without
  1334.  * modification, are permitted provided that the following conditions
  1335.  * are met:
  1336.  * 1. Redistributions of source code must retain the above copyright
  1337.  *    notice, this list of conditions and the following disclaimer.
  1338.  * 2. Redistributions in binary form must reproduce the above copyright
  1339.  *    notice, this list of conditions and the following disclaimer in the
  1340.  *    documentation and/or other materials provided with the distribution.
  1341.  * 3. Neither the name of the University nor the names of its contributors
  1342.  *    may be used to endorse or promote products derived from this software
  1343.  *    without specific prior written permission.
  1344.  *
  1345.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  1346.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  1347.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  1348.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  1349.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  1350.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  1351.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  1352.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  1353.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  1354.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  1355.  * SUCH DAMAGE.
  1356.  */
  1357.  
  1358. /*
  1359. **  Ask a Klingon To Surrender
  1360. **
  1361. **      (Fat chance)
  1362. **
  1363. **      The Subspace Radio is needed to ask a Klingon if he will kindly
  1364. **      surrender.  A random Klingon from the ones in the quadrant is
  1365. **      chosen.
  1366. **
  1367. **      The Klingon is requested to surrender.  The probability of this
  1368. **      is a function of that Klingon's remaining power, our power,
  1369. **      etc.
  1370. */
  1371.  
  1372. int selectklingon(void);
  1373.  
  1374. void
  1375.    capture(void)
  1376. {
  1377.         int             i;
  1378.         int k;
  1379.         double                  x;
  1380.  
  1381.         ididit = FALSE; // Nothing if we fail
  1382.         Time = 0.0;
  1383.  
  1384.         /* Make sure there is room in the brig */
  1385.         if (brigfree == 0)
  1386.         {
  1387.                 printf("Security reports the brig is already full.\n");
  1388.                 return;
  1389.         }
  1390.  
  1391.         if (!REPORTS) {
  1392.                 printf("Uhura- \"We have no subspace radio communication, sir.\"\n");
  1393.                 return;
  1394.         }
  1395.  
  1396.         if (damage[DTRANSP] != 0) {
  1397.                 printf("Scotty- \"Transporter damaged, sir.\"\n");
  1398.                 return;
  1399.         }
  1400.  
  1401.        
  1402.        
  1403.         /* find out if there are any at all */
  1404.         if (klhere < 1)
  1405.         {
  1406.                 printf("Uhura- \"Getting no response, sir.\"\n");
  1407.                 return;
  1408.         }
  1409.  
  1410.         /* if there is more than one Klingon, find out which one */
  1411.         k = selectklingon();
  1412.         Time = 0.05;   // This action will take some time
  1413.         ididit = TRUE; //  So any others can strike back
  1414.  
  1415.     /* check out that Klingon */
  1416.     /* The algorithm isn't that great and could use some more
  1417.      * intelligent design */
  1418. //      x = 300 + 25*skill;
  1419.         x = energy;
  1420.         x /= kpower[k] * nenhere;
  1421.         x *= 2.5;  /* would originally have been equivalent of 1.4, but we want command to work more often, more humanely */
  1422.         i = x;
  1423. #ifdef DEBUG
  1424.         printf("Prob = %d (%.4f)\n", i, x);
  1425. //      i = 100; // For testing, of course!
  1426. #endif
  1427.         if (i > 100*Rand())
  1428.         {
  1429.                 /* guess what, he surrendered!!! */
  1430.                 printf("Klingon captain at %d,%d surrenders\n", kx[k], ky[k]);
  1431.                 i = 200*Rand();
  1432.                 if ( i > 0 )
  1433.                         printf("%d Klingons commit suicide rather than be taken captive\n", 200 - i);
  1434.                 if (i > brigfree)
  1435.                 {
  1436.                         printf("%d Klingons die because there is no room for them in the brig.\n", i-brigfree);
  1437.                         i = brigfree;
  1438.                 }
  1439.                 brigfree -= i;
  1440.                 printf("%d captives taken\n", i);
  1441.                 deadkl(kx[k], ky[k], quad[kx[k]][ky[k]], kx[k], ky[k]);
  1442.                 if (d.remkl==0) finish(FWON);
  1443.                 return;
  1444.         }
  1445.  
  1446.         /* big surprise, he refuses to surrender */
  1447.         printf("Fat chance, captain\n");
  1448.         return;
  1449. }
  1450.  
  1451.  
  1452. /*
  1453.  **  SELECT A KLINGON
  1454.  **
  1455.  **     Cruddy, just takes one at random.  Should ask the captain.
  1456.  **     Nah, just select the weakest one since it is most likely to
  1457.  **     surrender (Tom Almy mod)
  1458.  */
  1459.  
  1460. int selectklingon()
  1461. {
  1462.         int             i;
  1463.  
  1464.         if (nenhere < 2)
  1465.                 i = 1;
  1466.         else
  1467.         {       // Select the weakest one
  1468.                 double pow  = 1e6;
  1469.                 int j;
  1470.                 for (j=1; j <= nenhere; j++)
  1471.                 {
  1472.                         if (quad[kx[j]][ky[j]] == IHR) continue; // No Romulans surrender
  1473.                         if (kpower[j]< pow)
  1474.                         {
  1475.                                 pow = kpower[j];
  1476.                                 i = j;
  1477.                         }
  1478.                 }
  1479.         }
  1480.         return i;
  1481. }
  1482.  
  1483. #endif