The beginnings of the website.
[super-star-trek.git] / events.c
1 #include "sst.h"\r
2 #include <math.h>\r
3 \r
4 void events(void) {\r
5 \r
6         int ictbeam=0, ipage=0, istract=0, line, i, j, k, l, ixhold, iyhold;\r
7         double fintim = game.state.date + Time, datemin, xtime, repair, yank;\r
8         \r
9 \r
10 #ifdef DEBUG\r
11         if (idebug) prout("EVENTS");\r
12 #endif\r
13 \r
14         if (stdamtim == 1e30 && game.damage[DRADIO] != 0.0) {\r
15                 /* chart will no longer be updated because radio is dead */\r
16                 stdamtim = game.state.date;\r
17                 for (i=1; i <= 8 ; i++)\r
18                         for (j=1; j <= 8; j++)\r
19                                 if (game.starch[i][j] == 1) game.starch[i][j] = game.state.galaxy[i][j]+1000;\r
20         }\r
21 \r
22         for (;;) {\r
23                 /* Select earliest extraneous event, line==0 if no events */\r
24                 line = FSPY;\r
25                 if (alldone) return;\r
26                 datemin = fintim;\r
27                 for (l=1; l<=NEVENTS; l++)\r
28                         if (game.future[l] <= datemin) {\r
29                                 line = l;\r
30                                 datemin = game.future[l];\r
31                         }\r
32                 xtime = datemin-game.state.date;\r
33                 game.state.date = datemin;\r
34                 /* Decrement Federation resources and recompute remaining time */\r
35                 game.state.remres -= (game.state.remkl+4*game.state.remcom)*xtime;\r
36                 game.state.remtime = game.state.remres/(game.state.remkl+4*game.state.remcom);\r
37                 if (game.state.remtime <=0) {\r
38                         finish(FDEPLETE);\r
39                         return;\r
40                 }\r
41                 /* Is life support adequate? */\r
42                 if (game.damage[DLIFSUP] && condit != IHDOCKED) {\r
43                         if (lsupres < xtime && game.damage[DLIFSUP] > lsupres) {\r
44                                 finish(FLIFESUP);\r
45                                 return;\r
46                         }\r
47                         lsupres -= xtime;\r
48                         if (game.damage[DLIFSUP] <= xtime) lsupres = inlsr;\r
49                 }\r
50                 /* Fix devices */\r
51                 repair = xtime;\r
52                 if (condit == IHDOCKED) repair /= docfac;\r
53                 /* Don't fix Deathray here */\r
54                 for (l=1; l<=NDEVICES; l++)\r
55                         if (game.damage[l] > 0.0 && l != DDRAY)\r
56                                 game.damage[l] -= (game.damage[l]-repair > 0.0 ? repair : game.damage[l]);\r
57                 /* If radio repaired, update star chart and attack reports */\r
58                 if (stdamtim != 1e30 && game.damage[DRADIO] == 0.0) {\r
59                         stdamtim = 1e30;\r
60                         prout("Lt. Uhura- \"Captain, the sub-space radio is working and");\r
61                         prout("   surveillance reports are coming in.");\r
62                         skip(1);\r
63                         for (i=1; i <= 8 ; i++)\r
64                                 for (j=1; j <= 8; j++)\r
65                                         if (game.starch[i][j] > 999) game.starch[i][j] = 1;\r
66                         if (iseenit==0) {\r
67                                 attakreport();\r
68                                 iseenit = 1;\r
69                         }\r
70                         skip(1);\r
71                         prout("   The star chart is now up to date.\"");\r
72                         skip(1);\r
73                 }\r
74                 /* Cause extraneous event LINE to occur */\r
75                 Time -= xtime;\r
76                 switch (line) {\r
77                         case FSNOVA: /* Supernova */\r
78                                 if (ipage==0) pause(1);\r
79                                 ipage=1;\r
80                                 snova(0,0);\r
81                                 game.future[FSNOVA] = game.state.date + expran(0.5*intime);\r
82                                 if (game.state.galaxy[quadx][quady] == 1000) return;\r
83                                 break;\r
84                         case FSPY: /* Check with spy to see if S.C. should tractor beam */\r
85                                 if (game.state.nscrem == 0 ||\r
86                                         ictbeam+istract > 0 ||\r
87                                         condit==IHDOCKED || isatb==1 || iscate==1) return;\r
88                                 if (ientesc ||\r
89                                         (energy < 2000 && torps < 4 && shield < 1250) ||\r
90                                         (game.damage[DPHASER]>0 && (game.damage[DPHOTON]>0 || torps < 4)) ||\r
91                                         (game.damage[DSHIELD] > 0 &&\r
92                                          (energy < 2500 || game.damage[DPHASER] > 0) &&\r
93                                          (torps < 5 || game.damage[DPHOTON] > 0))) {\r
94                                         /* Tractor-beam her! */\r
95                                         istract=1;\r
96                                         yank = square(game.state.isx-quadx) + square(game.state.isy-quady);\r
97                                         /*********TBEAM CODE***********/\r
98                                 }\r
99                                 else return;\r
100                         case FTBEAM: /* Tractor beam */\r
101                                 if (line==FTBEAM) {\r
102                                         if (game.state.remcom == 0) {\r
103                                                 game.future[FTBEAM] = 1e30;\r
104                                                 break;\r
105                                         }\r
106                                         i = Rand()*game.state.remcom+1.0;\r
107                                         yank = square(game.state.cx[i]-quadx) + square(game.state.cy[i]-quady);\r
108                                         if (istract || condit == IHDOCKED || yank == 0) {\r
109                                                 /* Drats! Have to reschedule */\r
110                                                 game.future[FTBEAM] = game.state.date + Time +\r
111                                                                                  expran(1.5*intime/game.state.remcom);\r
112                                                 break;\r
113                                         }\r
114                                 }\r
115                                 /* tractor beaming cases merge here */\r
116                                 yank = sqrt(yank);\r
117                                 if (ipage==0) pause(1);\r
118                                 ipage=1;\r
119                                 Time = (10.0/(7.5*7.5))*yank; /* 7.5 is yank rate (warp 7.5) */\r
120                                 ictbeam = 1;\r
121                                 skip(1);\r
122                                 proutn("***");\r
123                                 crmshp();\r
124                                 prout(" caught in long range tractor beam--");\r
125                                 /* If Kirk & Co. screwing around on planet, handle */\r
126                                 atover(1); /* atover(1) is Grab */\r
127                                 if (alldone) return;\r
128                                 if (icraft == 1) { /* Caught in Galileo? */\r
129                                         finish(FSTRACTOR);\r
130                                         return;\r
131                                 }\r
132                                 /* Check to see if shuttle is aboard */\r
133                                 if (iscraft==0) {\r
134                                         skip(1);\r
135                                         if (Rand() >0.5) {\r
136                                                 prout("Galileo, left on the planet surface, is captured");\r
137                                                 prout("by aliens and made into a flying McDonald's.");\r
138                                                 game.damage[DSHUTTL] = -10;\r
139                                                 iscraft = -1;\r
140                                         }\r
141                                         else {\r
142                                                 prout("Galileo, left on the planet surface, is well hidden.");\r
143                                         }\r
144                                 }\r
145                                 if (line==0) {\r
146                                         quadx = game.state.isx;\r
147                                         quady = game.state.isy;\r
148                                 }\r
149                                 else {\r
150                                         quadx = game.state.cx[i];\r
151                                         quady = game.state.cy[i];\r
152                                 }\r
153                                 iran10(&sectx, &secty);\r
154                                 crmshp();\r
155                                 proutn(" is pulled to ");\r
156                                 proutn(cramlc(quadrant, quadx, quady));\r
157                                 proutn(", ");\r
158                                 prout(cramlc(sector, sectx, secty));\r
159                                 if (resting) {\r
160                                         prout("(Remainder of rest/repair period cancellegame.state.)");\r
161                                         resting = 0;\r
162                                 }\r
163                                 if (shldup==0) {\r
164                                         if (game.damage[DSHIELD]==0 && shield > 0) {\r
165                                                 doshield(2); /* Shldsup */\r
166                                                 shldchg=0;\r
167                                         }\r
168                                         else prout("(Shields not currently useable.)");\r
169                                 }\r
170                                 newqad(0);\r
171                                 /* Adjust finish time to time of tractor beaming */\r
172                                 fintim = game.state.date+Time;\r
173                                 if (game.state.remcom <= 0) game.future[FTBEAM] = 1e30;\r
174                                 else game.future[FTBEAM] = game.state.date+Time+expran(1.5*intime/game.state.remcom);\r
175                                 break;\r
176                         case FSNAP: /* Snapshot of the universe (for time warp) */\r
177                                 game.snapsht = game.state;\r
178                                 game.state.snap = 1;\r
179                                 game.future[FSNAP] = game.state.date + expran(0.5 * intime);\r
180                                 break;\r
181                         case FBATTAK: /* Commander attacks starbase */\r
182                                 if (game.state.remcom==0 || game.state.rembase==0) {\r
183                                         /* no can do */\r
184                                         game.future[FBATTAK] = game.future[FCDBAS] = 1e30;\r
185                                         break;\r
186                                 }\r
187                                 i = 0;\r
188                                 for (j=1; j<=game.state.rembase; j++) {\r
189                                         for (k=1; k<=game.state.remcom; k++)\r
190                                                 if (game.state.baseqx[j]==game.state.cx[k] && game.state.baseqy[j]==game.state.cy[k] &&\r
191                                                         (game.state.baseqx[j]!=quadx || game.state.baseqy[j]!=quady) &&\r
192                                                         (game.state.baseqx[j]!=game.state.isx || game.state.baseqy[j]!=game.state.isy)) {\r
193                                                         i = 1;\r
194                                                         break;\r
195                                                 }\r
196                                         if (i == 1) break;\r
197                                 }\r
198                                 if (j>game.state.rembase) {\r
199                                         /* no match found -- try later */\r
200                                         game.future[FBATTAK] = game.state.date + expran(0.3*intime);\r
201                                         game.future[FCDBAS] = 1e30;\r
202                                         break;\r
203                                 }\r
204                                 /* commander + starbase combination found -- launch attack */\r
205                                 batx = game.state.baseqx[j];\r
206                                 baty = game.state.baseqy[j];\r
207                                 game.future[FCDBAS] = game.state.date+1.0+3.0*Rand();\r
208                                 if (isatb) /* extra time if SC already attacking */\r
209                                         game.future[FCDBAS] += game.future[FSCDBAS]-game.state.date;\r
210                                 game.future[FBATTAK] = game.future[FCDBAS] +expran(0.3*intime);\r
211                                 iseenit = 0;\r
212                                 if (game.damage[DRADIO] != 0.0 &&\r
213                                         condit != IHDOCKED) break; /* No warning :-( */\r
214                                 iseenit = 1;\r
215                                 if (ipage==0) pause(1);\r
216                                 ipage = 1;\r
217                                 skip(1);\r
218                                 proutn("Lt. Uhura-  \"Captain, the starbase in ");\r
219                                 prout(cramlc(quadrant, batx, baty));\r
220                                 prout("   reports that it is under atttack and that it can");\r
221                                 proutn("   hold out only until stardate %d",\r
222                                         (int)game.future[FCDBAS]);\r
223                                 prout(".\"");\r
224                                 if (resting) {\r
225                                         skip(1);\r
226                                         proutn("Mr. Spock-  \"Captain, shall we cancel the rest period?\"");\r
227                                         if (ja()) {\r
228                                                 resting = 0;\r
229                                                 Time = 0.0;\r
230                                                 return;\r
231                                         }\r
232                                 }\r
233                                 break;\r
234                         case FSCDBAS: /* Supercommander destroys base */\r
235                                 game.future[FSCDBAS] = 1e30;\r
236                                 isatb = 2;\r
237                                 if (game.state.galaxy[game.state.isx][game.state.isy]%100 < 10) break; /* WAS RETURN! */\r
238                                 ixhold = batx;\r
239                                 iyhold = baty;\r
240                                 batx = game.state.isx;\r
241                                 baty = game.state.isy;\r
242                         case FCDBAS: /* Commander succeeds in destroying base */\r
243                                 if (line==FCDBAS) {\r
244                                         game.future[FCDBAS] = 1e30;\r
245                                         /* find the lucky pair */\r
246                                         for (i = 1; i <= game.state.remcom; i++)\r
247                                                 if (game.state.cx[i]==batx && game.state.cy[i]==baty) break;\r
248                                         if (i > game.state.remcom || game.state.rembase == 0 ||\r
249                                                 game.state.galaxy[batx][baty] % 100 < 10) {\r
250                                                 /* No action to take after all */\r
251                                                 batx = baty = 0;\r
252                                                 break;\r
253                                         }\r
254                                 }\r
255                                 /* Code merges here for any commander destroying base */\r
256                                 /* Not perfect, but will have to do */\r
257                                 if (game.starch[batx][baty] == -1) game.starch[batx][baty] = 0;\r
258                                 /* Handle case where base is in same quadrant as starship */\r
259                                 if (batx==quadx && baty==quady) {\r
260                                         if (game.starch[batx][baty] > 999) game.starch[batx][baty] -= 10;\r
261                                         game.quad[basex][basey]= IHDOT;\r
262                                         basex=basey=0;\r
263                                         newcnd();\r
264                                         skip(1);\r
265                                         prout("Spock-  \"Captain, I believe the starbase has been destroyegame.state.\"");\r
266                                 }\r
267                                 else if (game.state.rembase != 1 &&\r
268                                                  (game.damage[DRADIO] <= 0.0 || condit == IHDOCKED)) {\r
269                                         /* Get word via subspace radio */\r
270                                         if (ipage==0) pause(1);\r
271                                         ipage = 1;\r
272                                         skip(1);\r
273                                         prout("Lt. Uhura-  \"Captain, Starfleet Command reports that");\r
274                                         proutn("   the starbase in ");\r
275                                         proutn(cramlc(quadrant, batx, baty));\r
276                                         prout(" has been destroyed by");\r
277                                         if (isatb==2) prout("the Klingon Super-Commander");\r
278                                         else prout("a Klingon Commander");\r
279                                 }\r
280                                 /* Remove Starbase from galaxy */\r
281                                 game.state.galaxy[batx][baty] -= 10;\r
282                                 for (i=1; i <= game.state.rembase; i++)\r
283                                         if (game.state.baseqx[i]==batx && game.state.baseqy[i]==baty) {\r
284                                                 game.state.baseqx[i]=game.state.baseqx[game.state.rembase];\r
285                                                 game.state.baseqy[i]=game.state.baseqy[game.state.rembase];\r
286                                         }\r
287                                 game.state.rembase--;\r
288                                 if (isatb == 2) {\r
289                                         /* reinstate a commander's base attack */\r
290                                         batx = ixhold;\r
291                                         baty = iyhold;\r
292                                         isatb = 0;\r
293                                 }\r
294                                 else {\r
295                                         batx = baty = 0;\r
296                                 }\r
297                                 break;\r
298                         case FSCMOVE: /* Supercommander moves */\r
299                                 game.future[FSCMOVE] = game.state.date+0.2777;\r
300                                 if (ientesc+istract==0 &&\r
301                                         isatb!=1 &&\r
302                                         (iscate!=1 || justin==1)) scom(&ipage);\r
303                                 break;\r
304                         case FDSPROB: /* Move deep space probe */\r
305                                 game.future[FDSPROB] = game.state.date + 0.01;\r
306                                 probex += probeinx;\r
307                                 probey += probeiny;\r
308                                 i = (int)(probex/10 +0.05);\r
309                                 j = (int)(probey/10 + 0.05);\r
310                                 if (probecx != i || probecy != j) {\r
311                                         probecx = i;\r
312                                         probecy = j;\r
313                                         if (i < 1 || i > 8 || j < 1 || j > 8 ||\r
314                                                 game.state.galaxy[probecx][probecy] == 1000) {\r
315                                                 // Left galaxy or ran into supernova\r
316                                                 if (game.damage[DRADIO]==0.0 || condit == IHDOCKED) {\r
317                                                         if (ipage==0) pause(1);\r
318                                                         ipage = 1;\r
319                                                         skip(1);\r
320                                                         proutn("Lt. Uhura-  \"The deep space probe ");\r
321                                                         if (i < 1 ||i > 8 || j < 1 || j > 8)\r
322                                                                 proutn("has left the galaxy");\r
323                                                         else\r
324                                                                 proutn("is no longer transmitting");\r
325                                                         prout(".\"");\r
326                                                 }\r
327                                                 game.future[FDSPROB] = 1e30;\r
328                                                 break;\r
329                                         }\r
330                                         if (game.damage[DRADIO]==0.0   || condit == IHDOCKED) {\r
331                                                 if (ipage==0) pause(1);\r
332                                                 ipage = 1;\r
333                                                 skip(1);\r
334                                                 proutn("Lt. Uhura-  \"The deep space probe is now in ");\r
335                                                 proutn(cramlc(quadrant, probecx, probecy));\r
336                                                 prout(".\"");\r
337                                         }\r
338                                 }\r
339                                 /* Update star chart if Radio is working or have access to\r
340                                    radio. */\r
341                                 if (game.damage[DRADIO] == 0.0 || condit == IHDOCKED)\r
342                                         game.starch[probecx][probecy] = game.damage[DRADIO] > 0.0 ?\r
343                                                                                    game.state.galaxy[probecx][probecy]+1000 : 1;\r
344                                 proben--; // One less to travel\r
345                                 if (proben == 0 && isarmed &&\r
346                                         game.state.galaxy[probecx][probecy] % 10 > 0) {\r
347                                         /* lets blow the sucker! */\r
348                                         snova(1,0);\r
349                                         game.future[FDSPROB] = 1e30;\r
350                                         if (game.state.galaxy[quadx][quady] == 1000) return;\r
351                                 }\r
352                                 break;\r
353                 }\r
354         }\r
355 }\r
356 \r
357                                 \r
358 void wait(void) {\r
359         int key;\r
360         double temp, delay, origTime;\r
361 \r
362         ididit = 0;\r
363         for (;;) {\r
364                 key = scan();\r
365                 if (key  != IHEOL) break;\r
366                 proutn("How long? ");\r
367         }\r
368         chew();\r
369         if (key != IHREAL) {\r
370                 huh();\r
371                 return;\r
372         }\r
373         origTime = delay = aaitem;\r
374         if (delay <= 0.0) return;\r
375         if (delay >= game.state.remtime || nenhere != 0) {\r
376                 prout("Are you sure? ");\r
377                 if (ja() == 0) return;\r
378         }\r
379 \r
380         /* Alternate resting periods (events) with attacks */\r
381 \r
382         resting = 1;\r
383         do {\r
384                 if (delay <= 0) resting = 0;\r
385                 if (resting == 0) {\r
386                         prout("%d stardates left.", (int)game.state.remtime);\r
387                         return;\r
388                 }\r
389                 temp = Time = delay;\r
390 \r
391                 if (nenhere) {\r
392                         double rtime = 1.0 + Rand();\r
393                         if (rtime < temp) temp = rtime;\r
394                         Time = temp;\r
395                 }\r
396                 if (Time < delay) attack(0);\r
397                 if (nenhere==0) movetho();\r
398                 if (alldone) return;\r
399                 events();\r
400                 ididit = 1;\r
401                 if (alldone) return;\r
402                 delay -= temp;\r
403                 /* Repair Deathray if long rest at starbase */\r
404                 if (origTime-delay >= 9.99 && condit == IHDOCKED)\r
405                         game.damage[DDRAY] = 0.0;\r
406         } while (game.state.galaxy[quadx][quady] != 1000); // leave if quadrant supernovas\r
407 \r
408         resting = 0;\r
409         Time = 0;\r
410 }\r
411 \r
412 void nova(int ix, int iy) {\r
413         static double course[] =\r
414                 {0.0, 10.5, 12.0, 1.5, 9.0, 0.0, 3.0, 7.5, 6.0, 4.5};\r
415         int bot, top, top2, burst, hits[11][3], kount, icx, icy, mm, nn, j;\r
416         int iquad, iquad1, i, ll, newcx, newcy, ii, jj;\r
417         if (Rand() < 0.05) {\r
418                 /* Wow! We've supernova'ed */\r
419                 snova(ix, iy);\r
420                 return;\r
421         }\r
422 \r
423         /* handle initial nova */\r
424         game.quad[ix][iy] = IHDOT;\r
425         crmena(1, IHSTAR, 2, ix, iy);\r
426         prout(" novas.");\r
427         game.state.galaxy[quadx][quady] -= 1;\r
428         game.state.starkl++;\r
429         \r
430         /* Set up stack to recursively trigger adjacent stars */\r
431         bot = top = top2 = 1;\r
432         kount = 0;\r
433         icx = icy = 0;\r
434         hits[1][1] = ix;\r
435         hits[1][2] = iy;\r
436         while (1) {\r
437                 for (mm = bot; mm <= top; mm++) \r
438                 for (nn = 1; nn <= 3; nn++)  /* nn,j represents coordinates around current */\r
439                         for (j = 1; j <= 3; j++) {\r
440                                 if (j==2 && nn== 2) continue;\r
441                                 ii = hits[mm][1]+nn-2;\r
442                                 jj = hits[mm][2]+j-2;\r
443                                 if (ii < 1 || ii > 10 || jj < 1 || jj > 10) continue;\r
444                                 iquad = game.quad[ii][jj];\r
445                                 switch (iquad) {\r
446 //                                      case IHDOT:     /* Empty space ends reaction\r
447 //                                      case IHQUEST:\r
448 //                                      case IHBLANK:\r
449 //                                      case IHT:\r
450 //                                      case IHWEB:\r
451                                         default:\r
452                                                 break;\r
453                                         case IHSTAR: /* Affect another star */\r
454                                                 if (Rand() < 0.05) {\r
455                                                         /* This star supernovas */\r
456                                                         snova(ii,jj);\r
457                                                         return;\r
458                                                 }\r
459                                                 top2++;\r
460                                                 hits[top2][1]=ii;\r
461                                                 hits[top2][2]=jj;\r
462                                                 game.state.galaxy[quadx][quady] -= 1;\r
463                                                 game.state.starkl++;\r
464                                                 crmena(1, IHSTAR, 2, ii, jj);\r
465                                                 prout(" novas.");\r
466                                                 game.quad[ii][jj] = IHDOT;\r
467                                                 break;\r
468                                         case IHP: /* Destroy planet */\r
469                                                 game.state.newstuf[quadx][quady] -= 1;\r
470                                                 game.state.nplankl++;\r
471                                                 crmena(1, IHP, 2, ii, jj);\r
472                                                 prout(" destroyed.");\r
473                                                 DESTROY(&game.state.plnets[iplnet]);\r
474                                                 iplnet = plnetx = plnety = 0;\r
475                                                 if (landed == 1) {\r
476                                                         finish(FPNOVA);\r
477                                                         return;\r
478                                                 }\r
479                                                 game.quad[ii][jj] = IHDOT;\r
480                                                 break;\r
481                                         case IHB: /* Destroy base */\r
482                                                 game.state.galaxy[quadx][quady] -= 10;\r
483                                                 for (i = 1; i <= game.state.rembase; i++)\r
484                                                         if (game.state.baseqx[i]==quadx && game.state.baseqy[i]==quady) break;\r
485                                                 game.state.baseqx[i] = game.state.baseqx[game.state.rembase];\r
486                                                 game.state.baseqy[i] = game.state.baseqy[game.state.rembase];\r
487                                                 game.state.rembase--;\r
488                                                 basex = basey = 0;\r
489                                                 game.state.basekl++;\r
490                                                 newcnd();\r
491                                                 crmena(1, IHB, 2, ii, jj);\r
492                                                 prout(" destroyed.");\r
493                                                 game.quad[ii][jj] = IHDOT;\r
494                                                 break;\r
495                                         case IHE: /* Buffet ship */\r
496                                         case IHF:\r
497                                                 prout("***Starship buffeted by nova.");\r
498                                                 if (shldup) {\r
499                                                         if (shield >= 2000.0) shield -= 2000.0;\r
500                                                         else {\r
501                                                                 double diff = 2000.0 - shield;\r
502                                                                 energy -= diff;\r
503                                                                 shield = 0.0;\r
504                                                                 shldup = 0;\r
505                                                                 prout("***Shields knocked out.");\r
506                                                                 game.damage[DSHIELD] += 0.005*damfac*Rand()*diff;\r
507                                                         }\r
508                                                 }\r
509                                                 else energy -= 2000.0;\r
510                                                 if (energy <= 0) {\r
511                                                         finish(FNOVA);\r
512                                                         return;\r
513                                                 }\r
514                                                 /* add in course nova contributes to kicking starship*/\r
515                                                 icx += sectx-hits[mm][1];\r
516                                                 icy += secty-hits[mm][2];\r
517                                                 kount++;\r
518                                                 break;\r
519                                         case IHK: /* kill klingon */\r
520                                                 deadkl(ii,jj,iquad, ii, jj);\r
521                                                 break;\r
522                                         case IHC: /* Damage/destroy big enemies */\r
523                                         case IHS:\r
524                                         case IHR:\r
525                                                 for (ll = 1; ll <= nenhere; ll++)\r
526                                                         if (game.kx[ll]==ii && game.ky[ll]==jj) break;\r
527                                                 game.kpower[ll] -= 800.0; /* If firepower is lost, die */\r
528                                                 if (game.kpower[ll] <= 0.0) {\r
529                                                         deadkl(ii, jj, iquad, ii, jj);\r
530                                                         break;\r
531                                                 }\r
532                                                 newcx = ii + ii - hits[mm][1];\r
533                                                 newcy = jj + jj - hits[mm][2];\r
534                                                 crmena(1, iquad, 2, ii, jj);\r
535                                                 proutn(" damaged");\r
536                                                 if (newcx<1 || newcx>10 || newcy<1 || newcy>10) {\r
537                                                         /* can't leave quadrant */\r
538                                                         skip(1);\r
539                                                         break;\r
540                                                 }\r
541                                                 iquad1 = game.quad[newcx][newcy];\r
542                                                 if (iquad1 == IHBLANK) {\r
543                                                         proutn(", blasted into ");\r
544                                                         crmena(0, IHBLANK, 2, newcx, newcy);\r
545                                                         skip(1);\r
546                                                         deadkl(ii, jj, iquad, newcx, newcy);\r
547                                                         break;\r
548                                                 }\r
549                                                 if (iquad1 != IHDOT) {\r
550                                                         /* can't move into something else */\r
551                                                         skip(1);\r
552                                                         break;\r
553                                                 }\r
554                                                 proutn(", buffeted to ");\r
555                                                 proutn(cramlc(sector, newcx, newcy));\r
556                                                 game.quad[ii][jj] = IHDOT;\r
557                                                 game.quad[newcx][newcy] = iquad;\r
558                                                 game.kx[ll] = newcx;\r
559                                                 game.ky[ll] = newcy;\r
560                                                 game.kavgd[ll] = sqrt(square(sectx-newcx)+square(secty-newcy));\r
561                                                 game.kdist[ll] = game.kavgd[ll];\r
562                                                 skip(1);\r
563                                                 break;\r
564                                 }\r
565                         }\r
566                 if (top == top2) break;\r
567                 bot = top + 1;\r
568                 top = top2;\r
569         }\r
570         if (kount==0) return;\r
571 \r
572         /* Starship affected by nova -- kick it away. */\r
573         dist = kount*0.1;\r
574         if (icx) icx = (icx < 0 ? -1 : 1);\r
575         if (icy) icy = (icy < 0 ? -1 : 1);\r
576         direc = course[3*(icx+1)+icy+2];\r
577         if (direc == 0.0) dist = 0.0;\r
578         if (dist == 0.0) return;\r
579         Time = 10.0*dist/16.0;\r
580         skip(1);\r
581         prout("Force of nova displaces starship.");\r
582         iattak=2;       /* Eliminates recursion problem */\r
583         move();\r
584         Time = 10.0*dist/16.0;\r
585         return;\r
586 }\r
587         \r
588         \r
589 void snova(int insx, int insy) {\r
590         int comdead, nqx, nqy, nsx, nsy, num, kldead, iscdead;\r
591         int nrmdead, npdead;\r
592         int insipient=0;\r
593 \r
594         nsx = insy;\r
595         nsy = insy;\r
596 \r
597         if (insy== 0) {\r
598                 if (insx == 1) {\r
599                         /* NOVAMAX being used */\r
600                         nqx = probecx;\r
601                         nqy = probecy;\r
602                 }\r
603                 else {\r
604                         int stars = 0;\r
605                         /* Scheduled supernova -- select star */\r
606                         /* logic changed here so that we won't favor quadrants in top\r
607                         left of universe */\r
608                         for (nqx = 1; nqx<=8; nqx++) {\r
609                                 for (nqy = 1; nqy<=8; nqy++) {\r
610                                         stars += game.state.galaxy[nqx][nqy] % 10;\r
611                                 }\r
612                         }\r
613                         if (stars == 0) return; /* nothing to supernova exists */\r
614                         num = Rand()*stars + 1;\r
615                         for (nqx = 1; nqx<=8; nqx++) {\r
616                                 for (nqy = 1; nqy<=8; nqy++) {\r
617                                         num -= game.state.galaxy[nqx][nqy] % 10;\r
618                                         if (num <= 0) break;\r
619                                 }\r
620                                 if (num <=0) break;\r
621                         }\r
622 #ifdef DEBUG\r
623                         if (idebug) {\r
624                                 proutn("Super nova here?");\r
625                                 if (ja()==1) {\r
626                                         nqx = quadx;\r
627                                         nqy = quady;\r
628                                 }\r
629                         }\r
630 #endif\r
631                 }\r
632 \r
633                 if (nqx != quady || nqy != quady || justin != 0) {\r
634                         /* it isn't here, or we just entered (treat as inroute) */\r
635                         if (game.damage[DRADIO] == 0.0 || condit == IHDOCKED) {\r
636                                 skip(1);\r
637                                 prout("Message from Starfleet Command       Stardate %.2f", game.state.date);\r
638                                 proutn("     Supernova in %s; caution advised.",\r
639                                        cramlc(quadrant, nqx, nqy));\r
640                         }\r
641                 }\r
642                 else {\r
643                         /* we are in the quadrant! */\r
644                         insipient = 1;\r
645                         num = Rand()* (game.state.galaxy[nqx][nqy]%10) + 1;\r
646                         for (nsx=1; nsx < 10; nsx++) {\r
647                                 for (nsy=1; nsy < 10; nsy++) {\r
648                                         if (game.quad[nsx][nsy]==IHSTAR) {\r
649                                                 num--;\r
650                                                 if (num==0) break;\r
651                                         }\r
652                                 }\r
653                                 if (num==0) break;\r
654                         }\r
655                 }\r
656         }\r
657         else {\r
658                 insipient = 1;\r
659         }\r
660 \r
661         if (insipient) {\r
662                 skip(1);\r
663                 prouts("***RED ALERT!  RED ALERT!");\r
664                 skip(1);\r
665                 prout("***Incipient supernova detected at ", cramlc(sector, nsx, nsy));\r
666                 nqx = quadx;\r
667                 nqy = quady;\r
668                 if (square(nsx-sectx) + square(nsy-secty) <= 2.1) {\r
669                         proutn("Emergency override attempts t");\r
670                         prouts("***************");\r
671                         skip(1);\r
672                         stars();\r
673                         alldone=1;\r
674                 }\r
675         }\r
676         /* destroy any Klingons in supernovaed quadrant */\r
677         num=game.state.galaxy[nqx][nqy];\r
678         kldead = num/100;\r
679         comdead = iscdead = 0;\r
680         if (nqx==game.state.isx && nqy == game.state.isy) {\r
681                 /* did in the Supercommander! */\r
682                 game.state.nscrem = game.state.isx = game.state.isy = isatb = iscate = 0;\r
683                 iscdead = 1;\r
684                 game.future[FSCMOVE] = game.future[FSCDBAS] = 1e30;\r
685         }\r
686         game.state.remkl -= kldead;\r
687         if (game.state.remcom) {\r
688                 int maxloop = game.state.remcom, l;\r
689                 for (l = 1; l <= maxloop; l++) {\r
690                         if (game.state.cx[l] == nqx && game.state.cy[l] == nqy) {\r
691                                 game.state.cx[l] = game.state.cx[game.state.remcom];\r
692                                 game.state.cy[l] = game.state.cy[game.state.remcom];\r
693                                 game.state.cx[game.state.remcom] = game.state.cy[game.state.remcom] = 0;\r
694                                 game.state.remcom--;\r
695                                 kldead--;\r
696                                 comdead++;\r
697                                 if (game.state.remcom==0) game.future[FTBEAM] = 1e30;\r
698                                 break;\r
699                         }\r
700                 }\r
701         }\r
702         /* destroy Romulans and planets in supernovaed quadrant */\r
703         num = game.state.newstuf[nqx][nqy];\r
704         game.state.newstuf[nqx][nqy] = 0;\r
705         nrmdead = num/10;\r
706         game.state.nromrem -= nrmdead;\r
707         npdead = num - nrmdead*10;\r
708         if (npdead) {\r
709                 int l;\r
710                 for (l = 0; l < inplan; l++)\r
711                         if (game.state.plnets[l].x == nqx && game.state.plnets[l].y == nqy) {\r
712                             DESTROY(&game.state.plnets[l]);\r
713                         }\r
714         }\r
715         /* Destroy any base in supernovaed quadrant */\r
716         if (game.state.rembase) {\r
717                 int maxloop = game.state.rembase, l;\r
718                 for (l = 1; l <= maxloop; l++)\r
719                         if (game.state.baseqx[l]==nqx && game.state.baseqy[l]==nqy) {\r
720                                 game.state.baseqx[l] = game.state.baseqx[game.state.rembase];\r
721                                 game.state.baseqy[l] = game.state.baseqy[game.state.rembase];\r
722                                 game.state.baseqx[game.state.rembase] = game.state.baseqy[game.state.rembase] = 0;\r
723                                 game.state.rembase--;\r
724                                 break;\r
725                         }\r
726         }\r
727         /* If starship caused supernova, tally up destruction */\r
728         if (insx) {\r
729                 num = game.state.galaxy[nqx][nqy] % 100;\r
730                 game.state.starkl += num % 10;\r
731                 game.state.basekl += num/10;\r
732                 game.state.killk += kldead;\r
733                 game.state.killc += comdead;\r
734                 game.state.nromkl += nrmdead;\r
735                 game.state.nplankl += npdead;\r
736                 game.state.nsckill += iscdead;\r
737         }\r
738         /* mark supernova in galaxy and in star chart */\r
739         if ((quadx == nqx && quady == nqy) ||\r
740                 game.damage[DRADIO] == 0 ||\r
741                 condit == IHDOCKED)\r
742                 game.starch[nqx][nqy] = 1;\r
743         game.state.galaxy[nqx][nqy] = 1000;\r
744         /* If supernova destroys last klingons give special message */\r
745         if (game.state.remkl==0 && (nqx != quadx || nqy != quady)) {\r
746                 skip(2);\r
747                 if (insx == 0) prout("Lucky you!");\r
748                 proutn("A supernova in %s has just destroyed the last Klingons.",\r
749                        cramlc(quadrant, nqx, nqy));\r
750                 finish(FWON);\r
751                 return;\r
752         }\r
753         /* if some Klingons remain, continue or die in supernova */\r
754         if (alldone) finish(FSNOVAED);\r
755         return;\r
756 }\r
757                 \r
758                                 \r