More merging of SERGEEV changes.
[super-star-trek.git] / battle.c
1 #ifdef SERGEEV\r
2 #include <conio.h>\r
3 #include <unistd.h>\r
4 #include "sstlinux.h"\r
5 #endif /* SERGEEV */\r
6 #include "sst.h"\r
7 \r
8 void doshield(int i) {\r
9         int key;\r
10         enum {NONE, SHUP, SHDN, NRG} action = NONE;\r
11 \r
12         ididit = 0;\r
13 \r
14         if (i == 2) action = SHUP;\r
15         else {\r
16                 key = scan();\r
17                 if (key == IHALPHA) {\r
18                         if (isit("transfer"))\r
19                                 action = NRG;\r
20                         else {\r
21                                 chew();\r
22                                 if (game.damage[DSHIELD]) {\r
23                                         prout("Shields damaged and down.");\r
24                                         return;\r
25                                 }\r
26                                 if (isit("up"))\r
27                                         action = SHUP;\r
28                                 else if (isit("down"))\r
29                                         action = SHDN;\r
30                         }\r
31                 }\r
32                 if (action==NONE) {\r
33                         proutn("Do you wish to change shield energy? ");\r
34                         if (ja()) {\r
35                                 proutn("Energy to transfer to shields- ");\r
36                                 action = NRG;\r
37                         }\r
38                         else if (game.damage[DSHIELD]) {\r
39                                 prout("Shields damaged and down.");\r
40                                 return;\r
41                         }\r
42                         else if (shldup) {\r
43                                 proutn("Shields are up. Do you want them down? ");\r
44                                 if (ja()) action = SHDN;\r
45                                 else {\r
46                                         chew();\r
47                                         return;\r
48                                 }\r
49                         }\r
50                         else {\r
51                                 proutn("Shields are down. Do you want them up? ");\r
52                                 if (ja()) action = SHUP;\r
53                                 else {\r
54                                         chew();\r
55                                         return;\r
56                                 }\r
57                         }\r
58                 }\r
59         }\r
60         switch (action) {\r
61                 case SHUP: /* raise shields */\r
62                         if (shldup) {\r
63                                 prout("Shields already up.");\r
64                                 return;\r
65                         }\r
66                         shldup = 1;\r
67                         shldchg = 1;\r
68                         if (condit != IHDOCKED) energy -= 50.0;\r
69                         prout("Shields raised.");\r
70                         if (energy <= 0) {\r
71                                 skip(1);\r
72                                 prout("Shields raising uses up last of energy.");\r
73                                 finish(FNRG);\r
74                                 return;\r
75                         }\r
76                         ididit=1;\r
77                         return;\r
78                 case SHDN:\r
79                         if (shldup==0) {\r
80                                 prout("Shields already down.");\r
81                                 return;\r
82                         }\r
83                         shldup=0;\r
84                         shldchg=1;\r
85                         prout("Shields lowered.");\r
86                         ididit=1;\r
87                         return;\r
88                 case NRG:\r
89                         while (scan() != IHREAL) {\r
90                                 chew();\r
91                                 proutn("Energy to transfer to shields- ");\r
92                         }\r
93                         chew();\r
94                         if (aaitem==0) return;\r
95                         if (aaitem > energy) {\r
96                                 prout("Insufficient ship energy.");\r
97                                 return;\r
98                         }\r
99                         ididit = 1;\r
100                         if (shield+aaitem >= inshld) {\r
101                                 prout("Shield energy maximized.");\r
102                                 if (shield+aaitem > inshld) {\r
103                                         prout("Excess energy requested returned to ship energy");\r
104                                 }\r
105                                 energy -= inshld-shield;\r
106                                 shield = inshld;\r
107                                 return;\r
108                         }\r
109                         if (aaitem < 0.0 && energy-aaitem > inenrg) {\r
110                                 /* Prevent shield drain loophole */\r
111                                 skip(1);\r
112                                 prout("Engineering to bridge--");\r
113                                 prout("  Scott here. Power circuit problem, Captain.");\r
114                                 prout("  I can't drain the shields.");\r
115                                 ididit = 0;\r
116                                 return;\r
117                         }\r
118                         if (shield+aaitem < 0) {\r
119                                 prout("All shield energy transferred to ship.");\r
120                                 energy += shield;\r
121                                 shield = 0.0;\r
122                                 return;\r
123                         }\r
124                         proutn("Scotty- \"");\r
125                         if (aaitem > 0)\r
126                                 prout("Transferring energy to shields.\"");\r
127                         else\r
128                                 prout("Draining energy from shields.\"");\r
129                         shield += aaitem;\r
130                         energy -= aaitem;\r
131                         return;\r
132                 case NONE:;     /* avoid gcc warning */\r
133         }\r
134 }\r
135 \r
136 void ram(int ibumpd, int ienm, int ix, int iy) {\r
137         double type = 1.0, extradm;\r
138         int icas, l;\r
139         \r
140         prouts("***RED ALERT!  RED ALERT!");\r
141         skip(1);\r
142         prout("***COLLISION IMMINENT.");\r
143         skip(2);\r
144         proutn("***");\r
145         crmshp();\r
146         switch (ienm) {\r
147                 case IHR: type = 1.5; break;\r
148                 case IHC: type = 2.0; break;\r
149                 case IHS: type = 2.5; break;\r
150                 case IHT: type = 0.5; break;\r
151                 case IHQUEST: type = 4.0; break;\r
152         }\r
153         proutn(ibumpd ? " rammed by " : " rams ");\r
154         crmena(0, ienm, 2, ix, iy);\r
155         if (ibumpd) proutn(" (original position)");\r
156         skip(1);\r
157         deadkl(ix, iy, ienm, sectx, secty);\r
158         proutn("***");\r
159         crmshp();\r
160         prout(" heavily damaged.");\r
161         icas = 10.0+20.0*Rand();\r
162         prout("***Sickbay reports %d casualties", icas);\r
163         casual += icas;\r
164         for (l=1; l <= NDEVICES; l++) {\r
165                 if (l == DDRAY) continue; // Don't damage deathray \r
166                 if (game.damage[l] < 0) continue;\r
167                 extradm = (10.0*type*Rand()+1.0)*damfac;\r
168                 game.damage[l] += Time + extradm; /* Damage for at least time of travel! */\r
169         }\r
170         shldup = 0;\r
171         if (game.state.remkl) {\r
172                 pause_game(2);\r
173                 dreprt();\r
174         }\r
175         else finish(FWON);\r
176         return;\r
177 }\r
178 \r
179 void torpedo(double course, double r, int inx, int iny, double *hit, int wait) {\r
180         int l, iquad=0, ix=0, iy=0, jx=0, jy=0, shoved=0, ll;\r
181 #ifdef SERGEEV\r
182         int crx,cry;\r
183         \r
184 #endif /* SERGEEV */\r
185         double ac=course + 0.25*r;\r
186         double angle = (15.0-ac)*0.5235988;\r
187         double bullseye = (15.0 - course)*0.5235988;\r
188         double deltax=-sin(angle), deltay=cos(angle), x=inx, y=iny, bigger;\r
189         double ang, temp, xx, yy, kp, h1;\r
190 \r
191         bigger = fabs(deltax);\r
192         if (fabs(deltay) > bigger) bigger = fabs(deltay);\r
193         deltax /= bigger;\r
194         deltay /= bigger;\r
195 #ifdef SERGEEV\r
196         crx=wherex();\r
197         cry=wherey();\r
198         if (game.damage[DSRSENS]==0 || condit==IHDOCKED) setwnd(1);\r
199         else setwnd(4);\r
200 #endif /* SERGEEV */\r
201         /* Loop to move a single torpedo */\r
202         for (l=1; l <= 15; l++) {\r
203                 x += deltax;\r
204                 ix = x + 0.5;\r
205                 if (ix < 1 || ix > 10) break;\r
206                 y += deltay;\r
207                 iy = y + 0.5;\r
208                 if (iy < 1 || iy > 10) break;\r
209 #ifndef SERGEEV\r
210                 if (l==4 || l==9) skip(1);\r
211                 proutn("%d - %d   ", (int)x, (int)y);\r
212                 iquad=game.quad[ix][iy];\r
213 #else\r
214                 iquad=game.quad[ix][iy];\r
215                 if (game.damage[DSRSENS]==0 || condit==IHDOCKED){\r
216                    drawmaps(2);\r
217                    delay((wait!=1)*400);\r
218                    wait=1;\r
219                    gotoxy(iy*2+3,ix+2);\r
220                    if ((game.quad[ix][iy]==IHDOT)||(game.quad[ix][iy]==IHBLANK)){\r
221                       game.quad[ix][iy]='+';\r
222                       drawmaps(2);\r
223                       game.quad[ix][iy]=iquad;\r
224                       sound(l*10);\r
225                       delay(100);\r
226                       nosound();\r
227                    }\r
228                    else {\r
229                         game.quad[ix][iy]|=128;\r
230                         drawmaps(2);\r
231                         game.quad[ix][iy]=iquad;\r
232                         _setcursortype(_NOCURSOR);\r
233                         sound(500);\r
234                         delay(1000);\r
235                         nosound();\r
236                         lowvideo();\r
237                         _setcursortype(_NORMALCURSOR);\r
238                    }\r
239                 }\r
240                 else {\r
241                   proutn("%d - %d   ", (int)x, (int)y);\r
242                 }\r
243 #endif /* SERGEEV */\r
244                 if (iquad==IHDOT) continue;\r
245                 /* hit something */\r
246 #ifndef SERGEEV\r
247                 skip(1);\r
248 #else\r
249                 setwnd(4);\r
250                 gotoxy(crx,cry);\r
251 #endif\r
252                 switch(iquad) {\r
253                         case IHE: /* Hit our ship */\r
254                         case IHF:\r
255                                 skip(1);\r
256                                 proutn("Torpedo hits ");\r
257                                 crmshp();\r
258                                 prout(".");\r
259                                 *hit = 700.0 + 100.0*Rand() -\r
260                                            1000.0*sqrt(square(ix-inx)+square(iy-iny))*\r
261                                            fabs(sin(bullseye-angle));\r
262                                 *hit = fabs(*hit);\r
263 #ifndef SERGEEV\r
264                                 newcnd(); /* undock */\r
265 #endif /* SERGEEV */\r
266                                 /* We may be displaced. */\r
267                                 if (landed==1 || condit==IHDOCKED) return; /* Cheat if on a planet */\r
268                                 ang = angle + 2.5*(Rand()-0.5);\r
269                                 temp = fabs(sin(ang));\r
270                                 if (fabs(cos(ang)) > temp) temp = fabs(cos(ang));\r
271                                 xx = -sin(ang)/temp;\r
272                                 yy = cos(ang)/temp;\r
273                                 jx=ix+xx+0.5;\r
274                                 jy=iy+yy+0.5;\r
275                                 if (jx<1 || jx>10 || jy<1 ||jy > 10) return;\r
276                                 if (game.quad[jx][jy]==IHBLANK) {\r
277                                         finish(FHOLE);\r
278                                         return;\r
279                                 }\r
280                                 if (game.quad[jx][jy]!=IHDOT) {\r
281                                         /* can't move into object */\r
282                                         return;\r
283                                 }\r
284                                 sectx = jx;\r
285                                 secty = jy;\r
286                                 crmshp();\r
287                                 shoved = 1;\r
288                                 break;\r
289                                           \r
290                         case IHC: /* Hit a commander */\r
291                         case IHS:\r
292                                 if (Rand() <= 0.05) {\r
293                                         crmena(1, iquad, 2, ix, iy);\r
294                                         prout(" uses anti-photon device;");\r
295                                         prout("   torpedo neutralized.");\r
296                                         return;\r
297                                 }\r
298                         case IHR: /* Hit a regular enemy */\r
299                         case IHK:\r
300                                 /* find the enemy */\r
301                                 for (ll=1; ll <= nenhere; ll++)\r
302                                         if (ix==game.kx[ll] && iy==game.ky[ll]) break;\r
303                                 kp = fabs(game.kpower[ll]);\r
304                                 h1 = 700.0 + 100.0*Rand() -\r
305                                          1000.0*sqrt(square(ix-inx)+square(iy-iny))*\r
306                                          fabs(sin(bullseye-angle));\r
307                                 h1 = fabs(h1);\r
308                                 if (kp < h1) h1 = kp;\r
309                                 game.kpower[ll] -= (game.kpower[ll]<0 ? -h1 : h1);\r
310                                 if (game.kpower[ll] == 0) {\r
311                                         deadkl(ix, iy, iquad, ix, iy);\r
312                                         return;\r
313                                 }\r
314                                 crmena(1, iquad, 2, ix, iy);\r
315                                 /* If enemy damaged but not destroyed, try to displace */\r
316                                 ang = angle + 2.5*(Rand()-0.5);\r
317                                 temp = fabs(sin(ang));\r
318                                 if (fabs(cos(ang)) > temp) temp = fabs(cos(ang));\r
319                                 xx = -sin(ang)/temp;\r
320                                 yy = cos(ang)/temp;\r
321                                 jx=ix+xx+0.5;\r
322                                 jy=iy+yy+0.5;\r
323                                 if (jx<1 || jx>10 || jy<1 ||jy > 10) {\r
324                                         prout(" damaged but not destroyed.");\r
325                                         return;\r
326                                 }\r
327                                 if (game.quad[jx][jy]==IHBLANK) {\r
328                                         prout(" buffeted into black hole.");\r
329                                         deadkl(ix, iy, iquad, jx, jy);\r
330                                         return;\r
331                                 }\r
332                                 if (game.quad[jx][jy]!=IHDOT) {\r
333                                         /* can't move into object */\r
334                                         prout(" damaged but not destroyed.");\r
335                                         return;\r
336                                 }\r
337                                 proutn(" damaged--");\r
338                                 game.kx[ll] = jx;\r
339                                 game.ky[ll] = jy;\r
340                                 shoved = 1;\r
341                                 break;\r
342                         case IHB: /* Hit a base */\r
343                                 skip(1);\r
344                                 prout("***STARBASE DESTROYED..");\r
345                                 if (game.starch[quadx][quady] < 0) game.starch[quadx][quady] = 0;\r
346                                 for (ll=1; ll<=game.state.rembase; ll++) {\r
347                                         if (game.state.baseqx[ll]==quadx && game.state.baseqy[ll]==quady) {\r
348                                                 game.state.baseqx[ll]=game.state.baseqx[game.state.rembase];\r
349                                                 game.state.baseqy[ll]=game.state.baseqy[game.state.rembase];\r
350                                                 break;\r
351                                         }\r
352                                 }\r
353                                 game.quad[ix][iy]=IHDOT;\r
354                                 game.state.rembase--;\r
355                                 basex=basey=0;\r
356                                 game.state.galaxy[quadx][quady] -= 10;\r
357                                 game.state.basekl++;\r
358                                 newcnd();\r
359                                 return;\r
360                         case IHP: /* Hit a planet */\r
361                                 crmena(1, iquad, 2, ix, iy);\r
362                                 prout(" destroyed.");\r
363                                 game.state.nplankl++;\r
364                                 game.state.newstuf[quadx][quady] -= 1;\r
365                                 DESTROY(&game.state.plnets[iplnet]);\r
366                                 iplnet = 0;\r
367                                 plnetx = plnety = 0;\r
368                                 game.quad[ix][iy] = IHDOT;\r
369                                 if (landed==1) {\r
370                                         /* captain parishes on planet */\r
371                                         finish(FDPLANET);\r
372                                 }\r
373                                 return;\r
374                         case IHSTAR: /* Hit a star */\r
375                                 if (Rand() > 0.10) {\r
376                                         nova(ix, iy);\r
377                                         return;\r
378                                 }\r
379                                 crmena(1, IHSTAR, 2, ix, iy);\r
380                                 prout(" unaffected by photon blast.");\r
381                                 return;\r
382                         case IHQUEST: /* Hit a thingy */\r
383                             if (Rand()>0.7) {   // Used to be certain death \r
384                                 skip(1);\r
385                                 prouts("AAAAIIIIEEEEEEEEAAAAAAAAUUUUUGGGGGHHHHHHHHHHHH!!!");\r
386                                 skip(1);\r
387                                 prouts("    HACK!     HACK!    HACK!        *CHOKE!*  ");\r
388                                 skip(1);\r
389                                 proutn("Mr. Spock-");\r
390                                 prouts("  \"Fascinating!\"");\r
391                                 skip(1);\r
392                                 deadkl(ix, iy, iquad, ix, iy);\r
393                             } else {\r
394                                 /*\r
395                                  * Stas Sergeev added the possibility that\r
396                                  * you can shove the Thingy.\r
397                                  */\r
398                                 iqengry=1;\r
399                                 shoved=1;\r
400                             }\r
401                             return;\r
402                         case IHBLANK: /* Black hole */\r
403                                 skip(1);\r
404                                 crmena(1, IHBLANK, 2, ix, iy);\r
405                                 prout(" swallows torpedo.");\r
406                                 return;\r
407                         case IHWEB: /* hit the web */\r
408                                 skip(1);\r
409                                 prout("***Torpedo absorbed by Tholian web.");\r
410                                 return;\r
411                         case IHT:  /* Hit a Tholian */\r
412                                 h1 = 700.0 + 100.0*Rand() -\r
413                                          1000.0*sqrt(square(ix-inx)+square(iy-iny))*\r
414                                          fabs(sin(bullseye-angle));\r
415                                 h1 = fabs(h1);\r
416                                 if (h1 >= 600) {\r
417 #ifndef SERGEEV\r
418                                         prout(" destroyed.");\r
419 #endif /* SERGEEV */\r
420                                         game.quad[ix][iy] = IHDOT;\r
421                                         ithere = 0;\r
422                                         ithx = ithy = 0;\r
423 #ifdef SERGEEV\r
424                                         deadkl(ix, iy, iquad, ix, iy);\r
425 #endif /* SERGEEV */\r
426                                         return;\r
427                                 }\r
428                                 skip(1);\r
429                                 crmena(1, IHT, 2, ix, iy);\r
430                                 if (Rand() > 0.05) {\r
431                                         prout(" survives photon blast.");\r
432                                         return;\r
433                                 }\r
434                                 prout(" disappears.");\r
435                                 game.quad[ix][iy] = IHWEB;\r
436                                 ithere = ithx = ithy = 0;\r
437                                 nenhere--;\r
438                                 {\r
439                                         int dum, my;\r
440                                         dropin(IHBLANK, &dum, &my);\r
441                                 }\r
442                                 return;\r
443                                         \r
444                         default: /* Problem! */\r
445                                 skip(1);\r
446                                 proutn("Don't know how to handle collision with ");\r
447                                 crmena(1, iquad, 2, ix, iy);\r
448                                 skip(1);\r
449                                 return;\r
450                 }\r
451                 break;\r
452         }\r
453 #ifdef SERGEEV\r
454         if(curwnd!=4) {\r
455             setwnd(4);\r
456             gotoxy(crx,cry);\r
457         }\r
458 #endif /* SERGEEV */\r
459         if (shoved) {\r
460                 game.quad[jx][jy]=iquad;\r
461                 game.quad[ix][iy]=IHDOT;\r
462                 prout(" displaced by blast to %s ", cramlc(sector, jx, jy));\r
463                 for (ll=1; ll<=nenhere; ll++)\r
464                         game.kdist[ll] = game.kavgd[ll] = sqrt(square(sectx-game.kx[ll])+square(secty-game.ky[ll]));\r
465                 sortkl();\r
466                 return;\r
467         }\r
468 #ifndef SERGEEV\r
469         skip(1);\r
470 #endif /* SERGEEV */\r
471         prout("Torpedo missed.");\r
472         return;\r
473 }\r
474 \r
475 static void fry(double hit) {\r
476         double ncrit, extradm;\r
477         int ktr=1, l, ll, j, cdam[NDEVICES+1];\r
478 \r
479         /* a critical hit occured */\r
480         if (hit < (275.0-25.0*skill)*(1.0+0.5*Rand())) return;\r
481 \r
482         ncrit = 1.0 + hit/(500.0+100.0*Rand());\r
483         proutn("***CRITICAL HIT--");\r
484         /* Select devices and cause damage */\r
485         for (l = 1; l <= ncrit && l <= NDEVICES; l++) {\r
486                 do {\r
487                         j = NDEVICES*Rand()+1.0;\r
488                         /* Cheat to prevent shuttle damage unless on ship */\r
489                 } while (game.damage[j] < 0.0 || (j == DSHUTTL && iscraft != 1) ||\r
490                                  j == DDRAY);\r
491                 cdam[l] = j;\r
492                 extradm = (hit*damfac)/(ncrit*(75.0+25.0*Rand()));\r
493                 game.damage[j] += extradm;\r
494                 if (l > 1) {\r
495                         for (ll=2; ll<=l && j != cdam[ll-1]; ll++) ;\r
496                         if (ll<=l) continue;\r
497                         ktr += 1;\r
498                         if (ktr==3) skip(1);\r
499                         proutn(" and ");\r
500                 }\r
501                 proutn(device[j]);\r
502         }\r
503         prout(" damaged.");\r
504         if (game.damage[DSHIELD] && shldup) {\r
505                 prout("***Shields knocked down.");\r
506                 shldup=0;\r
507         }\r
508 }\r
509 \r
510 void attack(int k) {\r
511         /* k == 0 forces use of phasers in an attack */\r
512         int percent, ihurt=0, l, i=0, jx, jy, iquad, itflag;\r
513         int atackd = 0, attempt = 0;\r
514         double hit;\r
515         double pfac, dustfac, hitmax=0.0, hittot=0.0, chgfac=1.0, r;\r
516 \r
517         iattak = 1;\r
518         if (alldone) return;\r
519 #ifdef DEBUG\r
520         if (idebug) prout("ATTACK!");\r
521 #endif\r
522 \r
523         if (ithere) movetho();\r
524 \r
525         if (neutz) { /* The one chance not to be attacked */\r
526                 neutz = 0;\r
527                 return;\r
528         }\r
529         if ((((comhere || ishere) && (justin == 0)) || skill == 5)&&(k!=0)) movcom();\r
530         if (nenhere==0 || (nenhere==1 && iqhere && iqengry==0)) return;\r
531         pfac = 1.0/inshld;\r
532         if (shldchg == 1) chgfac = 0.25+0.5*Rand();\r
533         skip(1);\r
534         if (skill <= 2) i = 2;\r
535         for (l=1; l <= nenhere; l++) {\r
536                 if (game.kpower[l] < 0) continue;       /* too weak to attack */\r
537                 /* compute hit strength and diminsh shield power */\r
538                 r = Rand();\r
539                 /* Increase chance of photon torpedos if docked or enemy energy low */\r
540                 if (condit == IHDOCKED) r *= 0.25;\r
541                 if (game.kpower[l] < 500) r *= 0.25; \r
542                 jx = game.kx[l];\r
543                 jy = game.ky[l];\r
544                 iquad = game.quad[jx][jy];\r
545                 if (iquad==IHT || (iquad==IHQUEST && !iqengry)) continue;\r
546                 itflag = (iquad == IHK && r > 0.0005) || k == 0 ||\r
547                         (iquad==IHC && r > 0.015) ||\r
548                         (iquad==IHR && r > 0.3) ||\r
549                         (iquad==IHS && r > 0.07) ||\r
550                         (iquad==IHQUEST && r > 0.05);\r
551                 if (itflag) {\r
552                         /* Enemy uses phasers */\r
553                         if (condit == IHDOCKED) continue; /* Don't waste the effort! */\r
554                         attempt = 1; /* Attempt to attack */\r
555                         dustfac = 0.8+0.05*Rand();\r
556                         hit = game.kpower[l]*pow(dustfac,game.kavgd[l]);\r
557                         game.kpower[l] *= 0.75;\r
558                 }\r
559                 else { /* Enemy used photon torpedo */\r
560                         double course = 1.90985*atan2((double)secty-jy, (double)jx-sectx);\r
561                         hit = 0;\r
562                         proutn("***TORPEDO INCOMING");\r
563                         if (game.damage[DSRSENS] <= 0.0) {\r
564                                 proutn(" From ");\r
565                                 crmena(0, iquad, i, jx, jy);\r
566                         }\r
567                         attempt = 1;\r
568                         prout("  ");\r
569                         r = (Rand()+Rand())*0.5 -0.5;\r
570                         r += 0.002*game.kpower[l]*r;\r
571                         torpedo(course, r, jx, jy, &hit, 0);\r
572                         if (game.state.remkl==0) finish(FWON); /* Klingons did themselves in! */\r
573                         if (game.state.galaxy[quadx][quady] == 1000 ||\r
574                                 alldone) return; /* Supernova or finished */\r
575                         if (hit == 0) continue;\r
576                 }\r
577                 if (shldup != 0 || shldchg != 0 || condit==IHDOCKED) {\r
578                         /* shields will take hits */\r
579                         double absorb, hitsh, propor = pfac*shield*(condit==IHDOCKED ? 2.1 : 1.0);\r
580                         if(propor < 0.1) propor = 0.1;\r
581                         hitsh = propor*chgfac*hit+1.0;\r
582                         atackd=1;\r
583                         absorb = 0.8*hitsh;\r
584                         if (absorb > shield) absorb = shield;\r
585                         shield -= absorb;\r
586                         hit -= hitsh;\r
587                         if (condit==IHDOCKED) dock(0);\r
588                         if (propor > 0.1 && hit < 0.005*energy) continue;\r
589                 }\r
590                 /* It's a hit -- print out hit size */\r
591                 atackd = 1; /* We weren't going to check casualties, etc. if\r
592                                shields were down for some strange reason. This\r
593                                            doesn't make any sense, so I've fixed it */\r
594                 ihurt = 1;\r
595                 proutn("%d unit hit", (int)hit);\r
596                 if ((game.damage[DSRSENS] > 0 && itflag) || skill <= 2) {\r
597                         proutn(" on the ");\r
598                         crmshp();\r
599                 }\r
600                 if (game.damage[DSRSENS] <= 0.0 && itflag) {\r
601                         proutn(" from ");\r
602                         crmena(0, iquad, i, jx, jy);\r
603                 }\r
604                 skip(1);\r
605                 /* Decide if hit is critical */\r
606                 if (hit > hitmax) hitmax = hit;\r
607                 hittot += hit;\r
608                 fry(hit);\r
609                 prout("Hit %g energy %g", hit, energy);\r
610                 energy -= hit;\r
611                 if (condit==IHDOCKED) dock(0);\r
612         }\r
613         if (energy <= 0) {\r
614                 /* Returning home upon your shield, not with it... */\r
615                 finish(FBATTLE);\r
616                 return;\r
617         }\r
618         if (attempt == 0 && condit == IHDOCKED)\r
619                 prout("***Enemies decide against attacking your ship.");\r
620         if (atackd == 0) return;\r
621         percent = 100.0*pfac*shield+0.5;\r
622         if (ihurt==0) {\r
623                 /* Shields fully protect ship */\r
624                 proutn("Enemy attack reduces shield strength to ");\r
625         }\r
626         else {\r
627                 /* Print message if starship suffered hit(s) */\r
628                 skip(1);\r
629                 proutn("Energy left %2d    shields ", (int)energy);\r
630                 if (shldup) proutn("up ");\r
631                 else if (game.damage[DSHIELD] == 0) proutn("down ");\r
632                 else proutn("damaged, ");\r
633         }\r
634         prout("%d%%,   torpedoes left %d", percent, torps);\r
635         /* Check if anyone was hurt */\r
636         if (hitmax >= 200 || hittot >= 500) {\r
637                 int icas= hittot*Rand()*0.015;\r
638                 if (icas >= 2) {\r
639                         skip(1);\r
640                         prout("Mc Coy-  \"Sickbay to bridge.  We suffered %d casualties", icas);\r
641                         prout("   in that last attack.\"");\r
642                         casual += icas;\r
643                 }\r
644         }\r
645         /* After attack, reset average distance to enemies */\r
646         for (l = 1; l <= nenhere; l++)\r
647                 game.kavgd[l] = game.kdist[l];\r
648         sortkl();\r
649         return;\r
650 }\r
651                 \r
652 void deadkl(int ix, int iy, int type, int ixx, int iyy) {\r
653         /* Added ixx and iyy allow enemy to "move" before dying */\r
654 \r
655         int i,j;\r
656 \r
657 #ifdef SERGEEV  \r
658         skip(1);\r
659 #endif /* SERGEEV */\r
660         crmena(1, type, 2, ixx, iyy);\r
661         /* Decide what kind of enemy it is and update approriately */\r
662         if (type == IHR) {\r
663                 /* chalk up a Romulan */\r
664                 game.state.newstuf[quadx][quady] -= 10;\r
665                 irhere--;\r
666                 game.state.nromkl++;\r
667                 game.state.nromrem--;\r
668         }\r
669         else if (type == IHT) {\r
670                 /* Killed a Tholian */\r
671                 ithere = 0;\r
672         }\r
673         else if (type == IHQUEST) {\r
674                 /* Killed a Thingy */\r
675              iqhere=iqengry=thingx=thingy=0;\r
676         }\r
677         else {\r
678                 /* Some type of a Klingon */\r
679                 game.state.galaxy[quadx][quady] -= 100;\r
680                 klhere--;\r
681                 game.state.remkl--;\r
682                 switch (type) {\r
683                         case IHC:\r
684                                 comhere = 0;\r
685                                 for (i=1; i<=game.state.remcom; i++)\r
686                                         if (game.state.cx[i]==quadx && game.state.cy[i]==quady) break;\r
687                                 game.state.cx[i] = game.state.cx[game.state.remcom];\r
688                                 game.state.cy[i] = game.state.cy[game.state.remcom];\r
689                                 game.state.cx[game.state.remcom] = 0;\r
690                                 game.state.cy[game.state.remcom] = 0;\r
691                                 game.state.remcom--;\r
692                                 game.future[FTBEAM] = 1e30;\r
693                                 if (game.state.remcom != 0)\r
694                                         game.future[FTBEAM] = game.state.date + expran(1.0*incom/game.state.remcom);\r
695                                 game.state.killc++;\r
696                                 break;\r
697                         case IHK:\r
698                                 game.state.killk++;\r
699                                 break;\r
700                         case IHS:\r
701                                 game.state.nscrem = ishere = game.state.isx = game.state.isy = isatb = iscate = 0;\r
702                                 game.state.nsckill = 1;\r
703                                 game.future[FSCMOVE] = game.future[FSCDBAS] = 1e30;\r
704                                 break;\r
705                 }\r
706         }\r
707 \r
708         /* For each kind of enemy, finish message to player */\r
709         prout(" destroyed.");\r
710         game.quad[ix][iy] = IHDOT;\r
711         if (game.state.remkl==0) return;\r
712 \r
713         game.state.remtime = game.state.remres/(game.state.remkl + 4*game.state.remcom);\r
714 \r
715         /* Remove enemy ship from arrays describing local conditions */\r
716         if (game.future[FCDBAS] < 1e30 && batx==quadx && baty==quady && type==IHC)\r
717             game.future[FCDBAS] = 1e30;\r
718         for (i=1; i<=nenhere; i++)\r
719                 if (game.kx[i]==ix && game.ky[i]==iy) break;\r
720         nenhere--;\r
721         if (i <= nenhere)  {\r
722                 for (j=i; j<=nenhere; j++) {\r
723                         game.kx[j] = game.kx[j+1];\r
724                         game.ky[j] = game.ky[j+1];\r
725                         game.kpower[j] = game.kpower[j+1];\r
726                         game.kavgd[j] = game.kdist[j] = game.kdist[j+1];\r
727                 }\r
728         }\r
729         game.kx[nenhere+1] = 0;\r
730         game.ky[nenhere+1] = 0;\r
731         game.kdist[nenhere+1] = 0;\r
732         game.kavgd[nenhere+1] = 0;\r
733         game.kpower[nenhere+1] = 0;\r
734         return;\r
735 }\r
736 \r
737 static int targetcheck(double x, double y, double *course) {\r
738         double deltx, delty;\r
739         /* Return TRUE if target is invalid */\r
740         if (x < 1.0 || x > 10.0 || y < 1.0 || y > 10.0) {\r
741                 huh();\r
742                 return 1;\r
743         }\r
744         deltx = 0.1*(y - secty);\r
745         delty = 0.1*(sectx - x);\r
746         if (deltx==0 && delty== 0) {\r
747                 skip(1);\r
748                 prout("Spock-  \"Bridge to sickbay.  Dr. McCoy,");\r
749                 prout("  I recommend an immediate review of");\r
750                 prout("  the Captain's psychological profile.\"");\r
751                 chew();\r
752                 return 1;\r
753         }\r
754         *course = 1.90985932*atan2(deltx, delty);\r
755         return 0;\r
756 }\r
757 \r
758 void photon(void) {\r
759         double targ[4][3], course[4];\r
760         double r, dummy;\r
761         int key, n, i, osuabor;\r
762 \r
763         ididit = 0;\r
764 \r
765         if (game.damage[DPHOTON]) {\r
766                 prout("Photon tubes damaged.");\r
767                 chew();\r
768                 return;\r
769         }\r
770         if (torps == 0) {\r
771                 prout("No torpedoes left.");\r
772                 chew();\r
773                 return;\r
774         }\r
775         key = scan();\r
776         for (;;) {\r
777                 if (key == IHALPHA) {\r
778                         huh();\r
779                         return;\r
780                 }\r
781                 else if (key == IHEOL) {\r
782                         prout("%d torpedoes left.", torps);\r
783                         proutn("Number of torpedoes to fire- ");\r
784                         key = scan();\r
785                 }\r
786                 else /* key == IHREAL */ {\r
787                         n = aaitem + 0.5;\r
788                         if (n <= 0) { /* abort command */\r
789                                 chew();\r
790                                 return;\r
791                         }\r
792                         if (n > 3) {\r
793                                 chew();\r
794                                 prout("Maximum of 3 torpedoes per burst.");\r
795                                 key = IHEOL;\r
796                                 return;\r
797                         }\r
798                         if (n <= torps) break;\r
799                         chew();\r
800                         key = IHEOL;\r
801                 }\r
802         }\r
803         for (i = 1; i <= n; i++) {\r
804                 key = scan();\r
805                 if (i==1 && key == IHEOL) {\r
806                         break;  /* we will try prompting */\r
807                 }\r
808                 if (i==2 && key == IHEOL) {\r
809                         /* direct all torpedoes at one target */\r
810                         while (i <= n) {\r
811                                 targ[i][1] = targ[1][1];\r
812                                 targ[i][2] = targ[1][2];\r
813                                 course[i] = course[1];\r
814                                 i++;\r
815                         }\r
816                         break;\r
817                 }\r
818                 if (key != IHREAL) {\r
819                         huh();\r
820                         return;\r
821                 }\r
822                 targ[i][1] = aaitem;\r
823                 key = scan();\r
824                 if (key != IHREAL) {\r
825                         huh();\r
826                         return;\r
827                 }\r
828                 targ[i][2] = aaitem;\r
829                 if (targetcheck(targ[i][1], targ[i][2], &course[i])) return;\r
830         }\r
831         chew();\r
832         if (i == 1 && key == IHEOL) {\r
833                 /* prompt for each one */\r
834                 for (i = 1; i <= n; i++) {\r
835                     proutn("Target sector for torpedo number %d- ", i);\r
836                         key = scan();\r
837                         if (key != IHREAL) {\r
838                                 huh();\r
839                                 return;\r
840                         }\r
841                         targ[i][1] = aaitem;\r
842                         key = scan();\r
843                         if (key != IHREAL) {\r
844                                 huh();\r
845                                 return;\r
846                         }\r
847                         targ[i][2] = aaitem;\r
848                         chew();\r
849                         if (targetcheck(targ[i][1], targ[i][2], &course[i])) return;\r
850                 }\r
851         }\r
852         ididit = 1;\r
853         /* Loop for moving <n> torpedoes */\r
854         osuabor = 0;\r
855         for (i = 1; i <= n && !osuabor; i++) {\r
856                 if (condit != IHDOCKED) torps--;\r
857                 r = (Rand()+Rand())*0.5 -0.5;\r
858                 if (fabs(r) >= 0.47) {\r
859                         /* misfire! */\r
860                         r = (Rand()+1.2) * r;\r
861                         if (n>1) {\r
862                             prouts("***TORPEDO NUMBER %d MISFIRES", i);\r
863                         }\r
864                         else prouts("***TORPEDO MISFIRES.");\r
865                         skip(1);\r
866                         if (i < n)\r
867                                 prout("  Remainder of burst aborted.");\r
868                         osuabor=1;\r
869                         if (Rand() <= 0.2) {\r
870                                 prout("***Photon tubes damaged by misfire.");\r
871                                 game.damage[DPHOTON] = damfac*(1.0+2.0*Rand());\r
872                                 break;\r
873                         }\r
874                 }\r
875                 if (shldup || condit == IHDOCKED) r *= 1.0 + 0.0001*shield;\r
876 #ifndef SERGEEV\r
877                 if (n != 1) {\r
878                         skip(1);\r
879                         proutn("Track for torpedo number %d-  ", i);\r
880                 }\r
881                 else {\r
882                         skip(1);\r
883                         proutn("Torpedo track- ");\r
884                 }\r
885 #endif /* SERGEEV */\r
886                 torpedo(course[i], r, sectx, secty, &dummy, i);\r
887                 if (alldone || game.state.galaxy[quadx][quady]==1000) return;\r
888         }\r
889         if (game.state.remkl==0) finish(FWON);\r
890 }\r
891 \r
892         \r
893 \r
894 static void overheat(double rpow) {\r
895         if (rpow > 1500) {\r
896                 double chekbrn = (rpow-1500.)*0.00038;\r
897                 if (Rand() <= chekbrn) {\r
898                         prout("Weapons officer Sulu-  \"Phasers overheated, sir.\"");\r
899                         game.damage[DPHASER] = damfac*(1.0 + Rand()) * (1.0+chekbrn);\r
900                 }\r
901         }\r
902 }\r
903 \r
904 static int checkshctrl(double rpow) {\r
905         double hit;\r
906         int icas;\r
907         \r
908         skip(1);\r
909         if (Rand() < .998) {\r
910                 prout("Shields lowered.");\r
911                 return 0;\r
912         }\r
913         /* Something bad has happened */\r
914         prouts("***RED ALERT!  RED ALERT!");\r
915         skip(2);\r
916         hit = rpow*shield/inshld;\r
917         energy -= rpow+hit*0.8;\r
918         shield -= hit*0.2;\r
919         if (energy <= 0.0) {\r
920                 prouts("Sulu-  \"Captain! Shield malf***********************\"");\r
921                 skip(1);\r
922                 stars();\r
923                 finish(FPHASER);\r
924                 return 1;\r
925         }\r
926         prouts("Sulu-  \"Captain! Shield malfunction! Phaser fire contained!\"");\r
927         skip(2);\r
928         prout("Lt. Uhura-  \"Sir, all decks reporting damage.\"");\r
929         icas = hit*Rand()*0.012;\r
930         skip(1);\r
931         fry(0.8*hit);\r
932         if (icas) {\r
933                 skip(1);\r
934                 prout("McCoy to bridge- \"Severe radiation burns, Jim.");\r
935                 prout("  %d casualties so far.\"", icas);\r
936                 casual -= icas;\r
937         }\r
938         skip(1);\r
939         prout("Phaser energy dispersed by shields.");\r
940         prout("Enemy unaffected.");\r
941         overheat(rpow);\r
942         return 1;\r
943 }\r
944         \r
945 \r
946 void phasers(void) {\r
947         double hits[21], rpow=0, extra, powrem, over, temp;\r
948         int kz = 0, k=1, i, irec=0; /* Cheating inhibitor */\r
949         int ifast=0, no=0, ipoop=1, msgflag = 1;\r
950         enum {NOTSET, MANUAL, FORCEMAN, AUTOMATIC} automode = NOTSET;\r
951         int key=0;\r
952 \r
953         skip(1);\r
954         /* SR sensors and Computer */\r
955         if (game.damage[DSRSENS]+game.damage[DCOMPTR] > 0) ipoop = 0;\r
956         if (condit == IHDOCKED) {\r
957                 prout("Phasers can't be fired through base shields.");\r
958                 chew();\r
959                 return;\r
960         }\r
961         if (game.damage[DPHASER] != 0) {\r
962                 prout("Phaser control damaged.");\r
963                 chew();\r
964                 return;\r
965         }\r
966         if (shldup) {\r
967                 if (game.damage[DSHCTRL]) {\r
968                         prout("High speed shield control damaged.");\r
969                         chew();\r
970                         return;\r
971                 }\r
972                 if (energy <= 200.0) {\r
973                         prout("Insufficient energy to activate high-speed shield control.");\r
974                         chew();\r
975                         return;\r
976                 }\r
977                 prout("Weapons Officer Sulu-  \"High-speed shield control enabled, sir.\"");\r
978                 ifast = 1;\r
979                 \r
980         }\r
981         /* Original code so convoluted, I re-did it all */\r
982         while (automode==NOTSET) {\r
983                 key=scan();\r
984                 if (key == IHALPHA) {\r
985                         if (isit("manual")) {\r
986                                 if (nenhere==0) {\r
987                                         prout("There is no enemy present to select.");\r
988                                         chew();\r
989                                         key = IHEOL;\r
990                                         automode=AUTOMATIC;\r
991                                 }\r
992                                 else {\r
993                                         automode = MANUAL;\r
994                                         key = scan();\r
995                                 }\r
996                         }\r
997                         else if (isit("automatic")) {\r
998                                 if ((!ipoop) && nenhere != 0) {\r
999                                         automode = FORCEMAN;\r
1000                                 }\r
1001                                 else {\r
1002                                         if (nenhere==0)\r
1003                                                 prout("Energy will be expended into space.");\r
1004                                         automode = AUTOMATIC;\r
1005                                         key = scan();\r
1006                                 }\r
1007                         }\r
1008                         else if (isit("no")) {\r
1009                                 no = 1;\r
1010                         }\r
1011                         else {\r
1012                                 huh();\r
1013                                 return;\r
1014                         }\r
1015                 }\r
1016                 else if (key == IHREAL) {\r
1017                         if (nenhere==0) {\r
1018                                 prout("Energy will be expended into space.");\r
1019                                 automode = AUTOMATIC;\r
1020                         }\r
1021                         else if (!ipoop)\r
1022                                 automode = FORCEMAN;\r
1023                         else\r
1024                                 automode = AUTOMATIC;\r
1025                 }\r
1026                 else {\r
1027                         /* IHEOL */\r
1028                         if (nenhere==0) {\r
1029                                 prout("Energy will be expended into space.");\r
1030                                 automode = AUTOMATIC;\r
1031                         }\r
1032                         else if (!ipoop)\r
1033                                 automode = FORCEMAN;\r
1034                         else \r
1035                         proutn("Manual or automatic? ");\r
1036                 }\r
1037         }\r
1038                                 \r
1039         switch (automode) {\r
1040                 case AUTOMATIC:\r
1041                         if (key == IHALPHA && isit("no")) {\r
1042                                 no = 1;\r
1043                                 key = scan();\r
1044                         }\r
1045                         if (key != IHREAL && nenhere != 0) {\r
1046                                 prout("Phasers locked on target. Energy available: %.2f",\r
1047                                     ifast?energy-200.0:energy,1,2);\r
1048                         }\r
1049                         irec=0;\r
1050                         do {\r
1051                                         chew();\r
1052                                         if (!kz) for (i = 1; i <= nenhere; i++)\r
1053                                                      irec+=fabs(game.kpower[i])/(PHASEFAC*pow(0.90,game.kdist[i]))*\r
1054                                                      (1.01+0.05*Rand()) + 1.0;\r
1055                                         kz=1;\r
1056                                         proutn("(%d) units required. ", irec);\r
1057                                         chew();\r
1058                                         proutn("Units to fire= ");\r
1059                                         key = scan();\r
1060                                         if (key!=IHREAL) return;\r
1061                                         rpow = aaitem;\r
1062                                         if (rpow > (ifast?energy-200:energy)) {\r
1063                                             proutn("Energy available= %.2f",\r
1064                                             ifast?energy-200:energy);\r
1065                                         skip(1);\r
1066                                         key = IHEOL;\r
1067                                 }\r
1068                         } while (rpow > (ifast?energy-200:energy));\r
1069                         if (rpow<=0) {\r
1070                                 /* chicken out */\r
1071                                 chew();\r
1072                                 return;\r
1073                         }\r
1074                         if ((key=scan()) == IHALPHA && isit("no")) {\r
1075                                 no = 1;\r
1076                         }\r
1077                         if (ifast) {\r
1078                                 energy -= 200; /* Go and do it! */\r
1079                                 if (checkshctrl(rpow)) return;\r
1080                         }\r
1081                         chew();\r
1082                         energy -= rpow;\r
1083                         extra = rpow;\r
1084                         if (nenhere) {\r
1085                                 extra = 0.0;\r
1086                                 powrem = rpow;\r
1087                                 for (i = 1; i <= nenhere; i++) {\r
1088                                         hits[i] = 0.0;\r
1089                                         if (powrem <= 0) continue;\r
1090                                         hits[i] = fabs(game.kpower[i])/(PHASEFAC*pow(0.90,game.kdist[i]));\r
1091                                         over = (0.01 + 0.05*Rand())*hits[i];\r
1092                                         temp = powrem;\r
1093                                         powrem -= hits[i] + over;\r
1094                                         if (powrem <= 0 && temp < hits[i]) hits[i] = temp;\r
1095                                         if (powrem <= 0) over = 0.0;\r
1096                                         extra += over;\r
1097                                 }\r
1098                                 if (powrem > 0.0) extra += powrem;\r
1099                                 hittem(hits);\r
1100                                 ididit=1;\r
1101                         }\r
1102                         if (extra > 0 && alldone == 0) {\r
1103                                 if (ithere) {\r
1104                                         proutn("*** Tholian web absorbs ");\r
1105                                         if (nenhere>0) proutn("excess ");\r
1106                                         prout("phaser energy.");\r
1107                                 }\r
1108                                 else {\r
1109                                         prout("%d expended on empty space.", (int)extra);\r
1110                                 }\r
1111                         }\r
1112                         break;\r
1113 \r
1114                 case FORCEMAN:\r
1115                         chew();\r
1116                         key = IHEOL;\r
1117                         if (game.damage[DCOMPTR]!=0)\r
1118                                 prout("Battle comuter damaged, manual file only.");\r
1119                         else {\r
1120                                 skip(1);\r
1121                                 prouts("---WORKING---");\r
1122                                 skip(1);\r
1123                                 prout("Short-range-sensors-damaged");\r
1124                                 prout("Insufficient-data-for-automatic-phaser-fire");\r
1125                                 prout("Manual-fire-must-be-used");\r
1126                                 skip(1);\r
1127                         }\r
1128                 case MANUAL:\r
1129                         rpow = 0.0;\r
1130                         for (k = 1; k <= nenhere;) {\r
1131                                 int ii = game.kx[k], jj = game.ky[k];\r
1132                                 int ienm = game.quad[ii][jj];\r
1133                                 if (msgflag) {\r
1134                                         proutn("Energy available= %.2f",\r
1135                                                energy-.006-(ifast?200:0));\r
1136                                         skip(1);\r
1137                                         msgflag = 0;\r
1138                                         rpow = 0.0;\r
1139                                 }\r
1140                                 if (game.damage[DSRSENS] && !(abs(sectx-ii) < 2 && abs(secty-jj) < 2) &&\r
1141                                         (ienm == IHC || ienm == IHS)) {\r
1142                                         cramen(ienm);\r
1143                                         prout(" can't be located without short range scan.");\r
1144                                         chew();\r
1145                                         key = IHEOL;\r
1146                                         hits[k] = 0; /* prevent overflow -- thanks to Alexei Voitenko */\r
1147                                         k++;\r
1148                                         continue;\r
1149                                 }\r
1150                                 if (key == IHEOL) {\r
1151                                         chew();\r
1152                                         if (ipoop && k > kz)\r
1153                                                 irec=(fabs(game.kpower[k])/(PHASEFAC*pow(0.9,game.kdist[k])))*\r
1154                                                                  (1.01+0.05*Rand()) + 1.0;\r
1155                                         kz = k;\r
1156                                         proutn("(");\r
1157                                         if (game.damage[DCOMPTR]==0) proutn("%d", irec);\r
1158                                         else proutn("??");\r
1159                                         proutn(")  ");\r
1160                                         proutn("units to fire at ");\r
1161                                         crmena(0, ienm, 2, ii, jj);\r
1162                                         proutn("-  ");\r
1163                                         key = scan();\r
1164                                 }\r
1165                                 if (key == IHALPHA && isit("no")) {\r
1166                                         no = 1;\r
1167                                         key = scan();\r
1168                                         continue;\r
1169                                         }\r
1170                                 if (key == IHALPHA) {\r
1171                                         huh();\r
1172                                         return;\r
1173                                 }\r
1174                                 if (key == IHEOL) {\r
1175                                         if (k==1) { /* Let me say I'm baffled by this */\r
1176                                                 msgflag = 1;\r
1177                                         }\r
1178                                         continue;\r
1179                                 }\r
1180                                 if (aaitem < 0) {\r
1181                                         /* abort out */\r
1182                                         chew();\r
1183                                         return;\r
1184                                 }\r
1185                                 hits[k] = aaitem;\r
1186                                 rpow += aaitem;\r
1187                                 /* If total requested is too much, inform and start over */\r
1188                                 \r
1189                                 if (rpow > (ifast?energy-200:energy)) {\r
1190                                         prout("Available energy exceeded -- try again.");\r
1191                                         chew();\r
1192                                         return;\r
1193                                 }\r
1194                                 key = scan(); /* scan for next value */\r
1195                                 k++;\r
1196                         }\r
1197                         if (rpow == 0.0) {\r
1198                                 /* zero energy -- abort */\r
1199                                 chew();\r
1200                                 return;\r
1201                         }\r
1202                         if (key == IHALPHA && isit("no")) {\r
1203                                 no = 1;\r
1204                         }\r
1205                         energy -= rpow;\r
1206                         chew();\r
1207                         if (ifast) {\r
1208                                 energy -= 200.0;\r
1209                                 if (checkshctrl(rpow)) return;\r
1210                         }\r
1211                         hittem(hits);\r
1212                         ididit=1;\r
1213                 case NOTSET:;   /* avoid gcc warning */\r
1214         }\r
1215         /* Say shield raised or malfunction, if necessary */\r
1216         if (alldone) return;\r
1217         if (ifast) {\r
1218                 skip(1);\r
1219                 if (no == 0) {\r
1220                         if (Rand() >= 0.99) {\r
1221                                 prout("Sulu-  \"Sir, the high-speed shield control has malfunctioned . . .");\r
1222                                 prouts("         CLICK   CLICK   POP  . . .");\r
1223                                 prout(" No  response, sir!");\r
1224                                 shldup = 0;\r
1225                         }\r
1226                         else\r
1227                                 prout("Shields raised.");\r
1228                 }\r
1229                 else\r
1230                         shldup = 0;\r
1231         }\r
1232         overheat(rpow);\r
1233 }\r
1234 \r
1235 void hittem(double *hits) {\r
1236         double kp, kpow, wham, hit, dustfac, kpini;\r
1237 #ifdef SERGEEV\r
1238         int cx, cy;\r
1239 #endif /* SERGEEV */\r
1240         int nenhr2=nenhere, k=1, kk=1, ii, jj, ienm;\r
1241 \r
1242         skip(1);\r
1243 \r
1244         for (; k <= nenhr2; k++, kk++) {\r
1245                 if ((wham = hits[k])==0) continue;\r
1246                 dustfac = 0.9 + 0.01*Rand();\r
1247                 hit = wham*pow(dustfac,game.kdist[kk]);\r
1248                 kpini = game.kpower[kk];\r
1249                 kp = fabs(kpini);\r
1250                 if (PHASEFAC*hit < kp) kp = PHASEFAC*hit;\r
1251                 game.kpower[kk] -= (game.kpower[kk] < 0 ? -kp: kp);\r
1252                 kpow = game.kpower[kk];\r
1253                 ii = game.kx[kk];\r
1254                 jj = game.ky[kk];\r
1255                 if (hit > 0.005) {\r
1256 #ifdef SERGEEV\r
1257                         if (game.damage[DSRSENS]==0){\r
1258                            crx=wherex();\r
1259                            cry=wherey();\r
1260                            setwnd(1);\r
1261                            drawmaps(2);\r
1262                            gotoxy(jj*2+3,ii+2);\r
1263                            highvideo();\r
1264                            proutn("%c", game.quad[ii][jj]);\r
1265                            gotoxy(wherex()-1,wherey());\r
1266                            sound(500);\r
1267                            delay(1000);\r
1268                            nosound();\r
1269                            lowvideo();\r
1270                            proutn("%c", game.quad[ii][jj]);\r
1271                            setwnd(4);\r
1272                            gotoxy(crx,cry);\r
1273                            _setcursortype(_NORMALCURSOR);\r
1274                            delay(500);\r
1275                         }\r
1276 #endif /* SERGEEV */\r
1277                         proutn("%d unit hit on ", (int)hit);\r
1278                 }\r
1279                 else\r
1280                         proutn("Very small hit on ");\r
1281                 ienm = game.quad[ii][jj];\r
1282                 if (ienm==IHQUEST) iqengry=1;\r
1283                 crmena(0,ienm,2,ii,jj);\r
1284                 skip(1);\r
1285                 if (kpow == 0) {\r
1286                         deadkl(ii, jj, ienm, ii, jj);\r
1287                         if (game.state.remkl==0) finish(FWON);\r
1288                         if (alldone) return;\r
1289                         kk--; /* don't do the increment */\r
1290                 }\r
1291                 else /* decide whether or not to emasculate klingon */\r
1292                         if (kpow > 0 && Rand() >= 0.9 &&\r
1293                                 kpow <= ((0.4 + 0.4*Rand())*kpini)) {\r
1294                                 prout("***Mr. Spock-  \"Captain, the vessel at ",\r
1295                                         cramlc(sector,ii,jj));\r
1296                                 prout("   has just lost its firepower.\"");\r
1297                                 game.kpower[kk] = -kpow;\r
1298                         }\r
1299         }\r
1300         return;\r
1301 }\r
1302 \r