2 * events.c -- event-queue handling
4 * This isn't a real event queue a la BSD Trek yet -- you can only have one
5 * event of each type active at any given time. Mostly these means we can
6 * only have one FDISTR/FENSLV/FREPRO sequence going at any given time;
7 * BSD Trek, from which we swiped the idea, can have up to 5.
12 event *unschedule(int evtype)
13 /* remove an event from the schedule */
15 game.future[evtype].date = FOREVER;
16 return &game.future[evtype];
19 int is_scheduled(int evtype)
20 /* is an event of specified type scheduled */
22 return game.future[evtype].date != FOREVER;
25 extern double scheduled(int evtype)
26 /* when will this event happen? */
28 return game.future[evtype].date;
31 event *schedule(int evtype, double offset)
32 /* schedule an event of specified type */
34 game.future[evtype].date = game.state.date + offset;
35 return &game.future[evtype];
38 void postpone(int evtype, double offset)
39 /* poistpone a scheduled event */
41 game.future[evtype].date += offset;
44 static bool cancelrest(void)
48 proutn(_("Mr. Spock- \"Captain, shall we cancel the rest period?\""));
61 int istract=0, evcode, i=0, j, k, l;
62 double fintim = game.state.date + game.optime, datemin, xtime, repair, yank=0;
63 bool radio_was_broken, ictbeam = false, ipage = false;
64 struct quadrant *pdest, *q;
69 prout("=== EVENTS from %.2f to %.2f:", game.state.date, fintim);
70 for (i = 1; i < NEVENTS; i++) {
72 case FSNOVA: proutn("=== Supernova "); break;
73 case FTBEAM: proutn("=== T Beam "); break;
74 case FSNAP: proutn("=== Snapshot "); break;
75 case FBATTAK: proutn("=== Base Attack "); break;
76 case FCDBAS: proutn("=== Base Destroy "); break;
77 case FSCMOVE: proutn("=== SC Move "); break;
78 case FSCDBAS: proutn("=== SC Base Destroy "); break;
79 case FDSPROB: proutn("=== Probe Move "); break;
80 case FDISTR: proutn("=== Distress Call "); break;
81 case FENSLV: proutn("=== Enlavement "); break;
82 case FREPRO: proutn("=== Klingon Build "); break;
85 prout("%.2f", scheduled(i));
92 radio_was_broken = (game.damage[DRADIO] != 0.0);
95 /* Select earliest extraneous event, evcode==0 if no events */
97 if (game.alldone) return;
99 for (l = 1; l < NEVENTS; l++)
100 if (game.future[l].date < datemin) {
103 prout("== Event %d fires", evcode);
104 datemin = game.future[l].date;
106 xtime = datemin-game.state.date;
107 game.state.date = datemin;
108 /* Decrement Federation resources and recompute remaining time */
109 game.state.remres -= (game.state.remkl+4*game.state.remcom)*xtime;
110 game.state.remtime = game.state.remres/(game.state.remkl+4*game.state.remcom);
111 if (game.state.remtime <=0) {
115 /* Is life support adequate? */
116 if (game.damage[DLIFSUP] && game.condit != IHDOCKED) {
117 if (game.lsupres < xtime && game.damage[DLIFSUP] > game.lsupres) {
121 game.lsupres -= xtime;
122 if (game.damage[DLIFSUP] <= xtime) game.lsupres = game.inlsr;
126 if (game.condit == IHDOCKED) repair /= game.docfac;
127 /* Don't fix Deathray here */
128 for (l=0; l<NDEVICES; l++)
129 if (game.damage[l] > 0.0 && l != DDRAY)
130 game.damage[l] -= (game.damage[l]-repair > 0.0 ? repair : game.damage[l]);
131 /* If radio repaired, update star chart and attack reports */
132 if (radio_was_broken && game.damage[DRADIO] == 0.0) {
133 prout(_("Lt. Uhura- \"Captain, the sub-space radio is working and"));
134 prout(_(" surveillance reports are coming in."));
136 if (game.iseenit==0) {
141 prout(_(" The star chart is now up to date.\""));
144 /* Cause extraneous event EVCODE to occur */
145 game.optime -= xtime;
147 case FSNOVA: /* Supernova */
148 if (!ipage) pause_game(1);
151 schedule(FSNOVA, expran(0.5*game.intime));
152 if (game.state.galaxy[game.quadrant.x][game.quadrant.y].supernova) return;
154 case FSPY: /* Check with spy to see if S.C. should tractor beam */
155 if (game.state.nscrem == 0 ||
156 ictbeam+istract > 0 ||
157 game.condit==IHDOCKED || game.isatb==1 || game.iscate==1) return;
159 (game.energy < 2000 && game.torps < 4 && game.shield < 1250) ||
160 (game.damage[DPHASER]>0 && (game.damage[DPHOTON]>0 || game.torps < 4)) ||
161 (game.damage[DSHIELD] > 0 &&
162 (game.energy < 2500 || game.damage[DPHASER] > 0) &&
163 (game.torps < 5 || game.damage[DPHOTON] > 0))) {
164 /* Tractor-beam her! */
166 yank = square(game.state.kscmdr.x-game.quadrant.x) + square(game.state.kscmdr.y-game.quadrant.y);
167 /********* fall through to FTBEAM code ***********/
170 case FTBEAM: /* Tractor beam */
171 if (evcode==FTBEAM) {
172 if (game.state.remcom == 0) {
176 i = Rand()*game.state.remcom+1.0;
177 yank = square(game.state.kcmdr[i].x-game.quadrant.x) + square(game.state.kcmdr[i].y-game.quadrant.y);
178 if (istract || game.condit == IHDOCKED || yank == 0) {
179 /* Drats! Have to reschedule */
181 game.optime + expran(1.5*game.intime/game.state.remcom));
185 /* tractor beaming cases merge here */
187 if (!ipage) pause_game(1);
189 game.optime = (10.0/(7.5*7.5))*yank; /* 7.5 is yank rate (warp 7.5) */
194 prout(_(" caught in long range tractor beam--"));
195 /* If Kirk & Co. screwing around on planet, handle */
196 atover(1); /* atover(1) is Grab */
197 if (game.alldone) return;
198 if (game.icraft == 1) { /* Caught in Galileo? */
202 /* Check to see if shuttle is aboard */
203 if (game.iscraft==0) {
206 prout(_("Galileo, left on the planet surface, is captured"));
207 prout(_("by aliens and made into a flying McDonald's."));
208 game.damage[DSHUTTL] = -10;
212 prout(_("Galileo, left on the planet surface, is well hidden."));
216 game.quadrant = game.state.kscmdr;
218 game.quadrant = game.state.kcmdr[i];
219 iran(QUADSIZE, &game.sector.x, &game.sector.y);
221 proutn(_(" is pulled to "));
222 proutn(cramlc(quadrant, game.quadrant));
224 prout(cramlc(sector, game.sector));
226 prout(_("(Remainder of rest/repair period cancelled.)"));
227 game.resting = false;
230 if (game.damage[DSHIELD]==0 && game.shield > 0) {
231 doshield(2); /* Shldsup */
234 else prout(_("(Shields not currently useable.)"));
237 /* Adjust finish time to time of tractor beaming */
238 fintim = game.state.date+game.optime;
240 if (game.state.remcom <= 0) unschedule(FTBEAM);
241 else schedule(FTBEAM, game.optime+expran(1.5*game.intime/game.state.remcom));
243 case FSNAP: /* Snapshot of the universe (for time warp) */
244 game.snapsht = game.state;
246 schedule(FSNAP, expran(0.5 * game.intime));
248 case FBATTAK: /* Commander attacks starbase */
249 if (game.state.remcom==0 || game.state.rembase==0) {
258 if (same(game.state.baseq[j], game.state.kcmdr[k]) &&
259 !same(game.state.baseq[j], game.quadrant) &&
260 !same(game.state.baseq[j], game.state.kscmdr)) {
266 if (j>game.state.rembase) {
267 /* no match found -- try later */
268 schedule(FBATTAK, expran(0.3*game.intime));
272 /* commander + starbase combination found -- launch attack */
273 game.battle = game.state.baseq[j];
274 schedule(FCDBAS, 1.0+3.0*Rand());
275 if (game.isatb) /* extra time if SC already attacking */
276 postpone(FCDBAS, scheduled(FSCDBAS)-game.state.date);
277 game.future[FBATTAK].date = game.future[FCDBAS].date + expran(0.3*game.intime);
279 if (game.damage[DRADIO] != 0.0 && game.condit != IHDOCKED)
280 break; /* No warning :-( */
282 if (!ipage) pause_game(1);
285 proutn(_("Lt. Uhura- \"Captain, the starbase in "));
286 prout(cramlc(quadrant, game.battle));
287 prout(_(" reports that it is under attack and that it can"));
288 proutn(_(" hold out only until stardate %d"),
289 (int)scheduled(FCDBAS));
294 case FSCDBAS: /* Supercommander destroys base */
297 if (!game.state.galaxy[game.state.kscmdr.x][game.state.kscmdr.y].starbase)
298 break; /* WAS RETURN! */
300 game.battle = game.state.kscmdr;
302 case FCDBAS: /* Commander succeeds in destroying base */
303 if (evcode==FCDBAS) {
305 /* find the lucky pair */
307 if (same(game.state.kcmdr[i], game.battle))
309 if (i > game.state.remcom || game.state.rembase == 0 ||
310 !game.state.galaxy[game.battle.x][game.battle.y].starbase) {
311 /* No action to take after all */
312 game.battle.x = game.battle.y = 0;
316 /* Code merges here for any commander destroying base */
317 /* Not perfect, but will have to do */
318 /* Handle case where base is in same quadrant as starship */
319 if (same(game.battle, game.quadrant)) {
320 game.state.chart[game.battle.x][game.battle.y].starbase = false;
321 game.quad[game.base.x][game.base.y] = IHDOT;
322 game.base.x=game.base.y=0;
325 prout(_("Spock- \"Captain, I believe the starbase has been destroyed.\""));
327 else if (game.state.rembase != 1 &&
328 (game.damage[DRADIO] <= 0.0 || game.condit == IHDOCKED)) {
329 /* Get word via subspace radio */
330 if (!ipage) pause_game(1);
333 prout(_("Lt. Uhura- \"Captain, Starfleet Command reports that"));
334 proutn(_(" the starbase in "));
335 proutn(cramlc(quadrant, game.battle));
336 prout(_(" has been destroyed by"));
338 prout(_("the Klingon Super-Commander"));
339 else prout(_("a Klingon Commander"));
340 game.state.chart[game.battle.x][game.battle.y].starbase = false;
342 /* Remove Starbase from galaxy */
343 game.state.galaxy[game.battle.x][game.battle.y].starbase = false;
345 if (same(game.state.baseq[i], game.battle))
346 game.state.baseq[i] = game.state.baseq[game.state.rembase];
347 game.state.rembase--;
348 if (game.isatb == 2) {
349 /* reinstate a commander's base attack */
354 game.battle.x = game.battle.y = 0;
357 case FSCMOVE: /* Supercommander moves */
358 schedule(FSCMOVE, 0.2777);
359 if (game.ientesc+istract==0 &&
361 (game.iscate != 1 || !game.justin)) scom(&ipage);
363 case FDSPROB: /* Move deep space probe */
364 schedule(FDSPROB, 0.01);
365 game.probex += game.probeinx;
366 game.probey += game.probeiny;
367 i = (int)(game.probex/QUADSIZE +0.05);
368 j = (int)(game.probey/QUADSIZE + 0.05);
369 if (game.probec.x != i || game.probec.y != j) {
372 if (!VALID_QUADRANT(i, j) ||
373 game.state.galaxy[game.probec.x][game.probec.y].supernova) {
374 // Left galaxy or ran into supernova
375 if (game.damage[DRADIO]==0.0 || game.condit == IHDOCKED) {
376 if (ipage==0) pause_game(1);
379 proutn(_("Lt. Uhura- \"The deep space probe "));
380 if (!VALID_QUADRANT(j, i))
381 proutn(_("has left the galaxy"));
383 proutn(_("is no longer transmitting"));
389 if (game.damage[DRADIO]==0.0 || game.condit == IHDOCKED) {
390 if (ipage==0) pause_game(1);
393 proutn(_("Lt. Uhura- \"The deep space probe is now in "));
394 proutn(cramlc(quadrant, game.probec));
398 pdest = &game.state.galaxy[game.probec.x][game.probec.y];
399 /* Update star chart if Radio is working or have access to
401 if (game.damage[DRADIO] == 0.0 || game.condit == IHDOCKED) {
402 struct page *chp = &game.state.chart[game.probec.x][game.probec.y];
404 chp->klingons = pdest->klingons;
405 chp->starbase = pdest->starbase;
406 chp->stars = pdest->stars;
407 pdest->charted = true;
409 game.proben--; // One less to travel
410 if (game.proben == 0 && game.isarmed && pdest->stars) {
411 /* lets blow the sucker! */
414 if (game.state.galaxy[game.quadrant.x][game.quadrant.y].supernova)
418 case FDISTR: /* inhabited system issues distress call */
420 /* try a whole bunch of times to find something suitable */
423 /* need a quadrant which is not the current one,
424 which has some stars which are inhabited and
425 not already under attack, which is not
426 supernova'ed, and which has some Klingons in it */
427 iran(GALSIZE, &w.x, &w.y);
428 q = &game.state.galaxy[w.x][w.y];
430 (same(game.quadrant, w) || q->planet == NOPLANET ||
431 q->supernova || q->status!=secure || q->klingons<=0));
433 /* can't seem to find one; ignore this call */
435 prout("=== Couldn't find location for distress event.");
439 /* got one!! Schedule its enslavement */
440 ev = schedule(FENSLV, expran(game.intime));
442 q->status = distressed;
444 /* tell the captain about it if we can */
445 if (game.damage[DRADIO] == 0.0 || game.condit == IHDOCKED)
447 prout("Uhura- Captain, %s in %s reports it is under attack",
448 systemname(q->planet), cramlc(quadrant, w));
449 prout("by a Klingon invasion fleet.");
454 case FENSLV: /* starsystem is enslaved */
455 ev = unschedule(FENSLV);
456 /* see if current distress call still active */
457 q = &game.state.galaxy[ev->quadrant.x][ev->quadrant.y];
458 if (q->klingons <= 0) {
462 q->status = enslaved;
464 /* play stork and schedule the first baby */
465 ev2 = schedule(FREPRO, expran(2.0 * game.intime));
466 ev2->quadrant = ev->quadrant;
468 /* report the disaster if we can */
469 if (game.damage[DRADIO] == 0.0 || game.condit == IHDOCKED)
471 prout("Uhura- We've lost contact with starsystem %s",
472 systemname(q->planet));
473 prout("in %s.\n", cramlc(quadrant, ev->quadrant));
476 case FREPRO: /* Klingon reproduces */
478 * If we ever switch to a real event queue, we'll need to
479 * explicitly retrieve and restore the x and y.
481 ev = schedule(FREPRO, expran(1.0 * game.intime));
482 /* see if current distress call still active */
483 q = &game.state.galaxy[ev->quadrant.x][ev->quadrant.y];
484 if (q->klingons <= 0) {
488 if (game.state.remkl >=MAXKLGAME)
489 break; /* full right now */
490 /* reproduce one Klingon */
492 if (game.klhere >= MAXKLQUAD) {
493 /* this quadrant not ok, pick an adjacent one */
494 for (i = w.x - 1; i <= w.x + 1; i++)
496 for (j = w.y - 1; j <= w.y + 1; j++)
498 if (!VALID_QUADRANT(i, j))
500 q = &game.state.galaxy[w.x][w.y];
501 /* check for this quad ok (not full & no snova) */
502 if (q->klingons >= MAXKLQUAD || q->supernova)
507 break; /* search for eligible quadrant failed */
513 /* deliver the child */
516 if (same(game.quadrant, w))
517 newkling(++game.klhere, &hold);
519 /* recompute time left */
520 game.state.remtime = game.state.remres/(game.state.remkl+4*game.state.remcom);
521 /* report the disaster if we can */
522 if (game.damage[DRADIO] == 0.0 || game.condit == IHDOCKED)
524 if (same(game.quadrant, w)) {
525 prout("Spock- sensors indicate the Klingons have");
526 prout("launched a warship from %s.",systemname(q->planet));
528 prout("Uhura- Starfleet reports increased Klingon activity");
529 if (q->planet != NOPLANET)
530 proutn("near %s", systemname(q->planet));
531 prout("in %s.\n", cramlc(quadrant, w));
543 double temp, delay, origTime;
548 if (key != IHEOL) break;
549 proutn(_("How long? "));
556 origTime = delay = aaitem;
557 if (delay <= 0.0) return;
558 if (delay >= game.state.remtime || game.nenhere != 0) {
559 proutn(_("Are you sure? "));
560 if (ja() == 0) return;
563 /* Alternate resting periods (events) with attacks */
567 if (delay <= 0) game.resting = false;
569 prout(_("%d stardates left."), (int)game.state.remtime);
572 temp = game.optime = delay;
575 double rtime = 1.0 + Rand();
576 if (rtime < temp) temp = rtime;
579 if (game.optime < delay) attack(0);
580 if (game.alldone) return;
583 if (game.alldone) return;
585 /* Repair Deathray if long rest at starbase */
586 if (origTime-delay >= 9.99 && game.condit == IHDOCKED)
587 game.damage[DDRAY] = 0.0;
589 // leave if quadrant supernovas
590 (!game.state.galaxy[game.quadrant.x][game.quadrant.y].supernova);
592 game.resting = false;
596 void nova(int ix, int iy)
598 static double course[] =
599 {0.0, 10.5, 12.0, 1.5, 9.0, 0.0, 3.0, 7.5, 6.0, 4.5};
600 int bot, top, top2, hits[QUADSIZE+1][3], kount, icx, icy, mm, nn, j;
601 int iquad, iquad1, i, ll;
602 coord newc, nov, scratch;
604 nov.x = ix; nov.y = iy;
606 /* Wow! We've supernova'ed */
611 /* handle initial nova */
612 game.quad[ix][iy] = IHDOT;
613 crmena(1, IHSTAR, 2, nov);
615 game.state.galaxy[game.quadrant.x][game.quadrant.y].stars--;
618 /* Set up stack to recursively trigger adjacent stars */
619 bot = top = top2 = 1;
625 for (mm = bot; mm <= top; mm++)
626 for (nn = 1; nn <= 3; nn++) /* nn,j represents coordinates around current */
627 for (j = 1; j <= 3; j++) {
628 if (j==2 && nn== 2) continue;
629 scratch.x = hits[mm][1]+nn-2;
630 scratch.y = hits[mm][2]+j-2;
631 if (!VALID_SECTOR(scratch.y, scratch.x)) continue;
632 iquad = game.quad[scratch.x][scratch.y];
634 // case IHDOT: /* Empty space ends reaction
641 case IHSTAR: /* Affect another star */
643 /* This star supernovas */
644 snova(scratch.x,scratch.y);
648 hits[top2][1]=scratch.x;
649 hits[top2][2]=scratch.y;
650 game.state.galaxy[game.quadrant.x][game.quadrant.y].stars -= 1;
652 crmena(1, IHSTAR, 2, scratch);
654 game.quad[scratch.x][scratch.y] = IHDOT;
656 case IHP: /* Destroy planet */
657 game.state.galaxy[game.quadrant.x][game.quadrant.y].planet = NOPLANET;
658 game.state.nplankl++;
659 crmena(1, IHP, 2, scratch);
660 prout(_(" destroyed."));
661 DESTROY(&game.state.plnets[game.iplnet]);
662 game.iplnet = game.plnet.x = game.plnet.y = 0;
663 if (game.landed == 1) {
667 game.quad[scratch.x][scratch.y] = IHDOT;
669 case IHB: /* Destroy base */
670 game.state.galaxy[game.quadrant.x][game.quadrant.y].starbase = false;
672 if (game.state.baseq[i].x==game.quadrant.x && game.state.baseq[i].y==game.quadrant.y)
674 game.state.baseq[i] = game.state.baseq[game.state.rembase];
675 game.state.rembase--;
676 game.base.x = game.base.y = 0;
679 crmena(1, IHB, 2, scratch);
680 prout(_(" destroyed."));
681 game.quad[scratch.x][scratch.y] = IHDOT;
683 case IHE: /* Buffet ship */
685 prout(_("***Starship buffeted by nova."));
687 if (game.shield >= 2000.0) game.shield -= 2000.0;
689 double diff = 2000.0 - game.shield;
693 prout(_("***Shields knocked out."));
694 game.damage[DSHIELD] += 0.005*game.damfac*Rand()*diff;
697 else game.energy -= 2000.0;
698 if (game.energy <= 0) {
702 /* add in course nova contributes to kicking starship*/
703 icx += game.sector.x-hits[mm][1];
704 icy += game.sector.y-hits[mm][2];
707 case IHK: /* kill klingon */
708 deadkl(scratch,iquad, scratch.x, scratch.y);
710 case IHC: /* Damage/destroy big enemies */
713 for_local_enemies(ll)
714 if (game.ks[ll].x==scratch.x && game.ks[ll].y==scratch.y) break;
715 game.kpower[ll] -= 800.0; /* If firepower is lost, die */
716 if (game.kpower[ll] <= 0.0) {
717 deadkl(scratch, iquad, scratch.x, scratch.y);
720 newc.x = scratch.x + scratch.x - hits[mm][1];
721 newc.y = scratch.y + scratch.y - hits[mm][2];
722 crmena(1, iquad, 2, scratch);
723 proutn(_(" damaged"));
724 if (!VALID_SECTOR(newc.x, newc.y)) {
725 /* can't leave quadrant */
729 iquad1 = game.quad[newc.x][newc.y];
730 if (iquad1 == IHBLANK) {
731 proutn(_(", blasted into "));
732 crmena(0, IHBLANK, 2, newc);
734 deadkl(scratch, iquad, newc.x, newc.y);
737 if (iquad1 != IHDOT) {
738 /* can't move into something else */
742 proutn(_(", buffeted to "));
743 proutn(cramlc(sector, newc));
744 game.quad[scratch.x][scratch.y] = IHDOT;
745 game.quad[newc.x][newc.y] = iquad;
746 game.ks[ll].x = newc.x;
747 game.ks[ll].y = newc.y;
748 game.kavgd[ll] = sqrt(square(game.sector.x-newc.x)+square(game.sector.y-newc.y));
749 game.kdist[ll] = game.kavgd[ll];
762 /* Starship affected by nova -- kick it away. */
763 game.dist = kount*0.1;
764 if (icx) icx = (icx < 0 ? -1 : 1);
765 if (icy) icy = (icy < 0 ? -1 : 1);
766 game.direc = course[3*(icx+1)+icy+2];
767 if (game.direc == 0.0) game.dist = 0.0;
768 if (game.dist == 0.0) return;
769 game.optime = 10.0*game.dist/16.0;
771 prout(_("Force of nova displaces starship."));
772 game.iattak=2; /* Eliminates recursion problem */
774 game.optime = 10.0*game.dist/16.0;
779 void snova(int insx, int insy)
781 int comdead, nsx, nsy, num=0, kldead, iscdead;
792 /* NOVAMAX being used */
796 /* Scheduled supernova -- select star */
797 /* logic changed here so that we won't favor quadrants in top
799 for_quadrants(nq.x) {
800 for_quadrants(nq.y) {
801 stars += game.state.galaxy[nq.x][nq.y].stars;
804 if (stars == 0) return; /* nothing to supernova exists */
805 num = Rand()*stars + 1;
806 for_quadrants(nq.x) {
807 for_quadrants(nq.y) {
808 num -= game.state.galaxy[nq.x][nq.y].stars;
814 proutn("=== Super nova here?");
816 nq.x = game.quadrant.x;
817 nq.y = game.quadrant.y;
822 if (nq.x != game.quadrant.y || nq.y != game.quadrant.y || game.justin != 0) {
823 /* it isn't here, or we just entered (treat as inroute) */
824 if (game.damage[DRADIO] == 0.0 || game.condit == IHDOCKED) {
826 prout(_("Message from Starfleet Command Stardate %.2f"), game.state.date);
827 prout(_(" Supernova in %s; caution advised."),
828 cramlc(quadrant, nq));
832 /* we are in the quadrant! */
834 num = Rand()* game.state.galaxy[nq.x][nq.y].stars + 1;
837 if (game.quad[nsx][nsy]==IHSTAR) {
853 prouts(_("***RED ALERT! RED ALERT!"));
855 nd.x = nsx; nd.y = nsy;
856 prout(_("***Incipient supernova detected at "), cramlc(sector, nd));
858 if (square(nsx-game.sector.x) + square(nsy-game.sector.y) <= 2.1) {
859 proutn(_("Emergency override attempts t"));
860 prouts("***************");
866 /* destroy any Klingons in supernovaed quadrant */
867 kldead = game.state.galaxy[nq.x][nq.y].klingons;
868 game.state.galaxy[nq.x][nq.y].klingons = 0;
869 comdead = iscdead = 0;
870 if (same(nq, game.state.kscmdr)) {
871 /* did in the Supercommander! */
872 game.state.nscrem = game.state.kscmdr.x = game.state.kscmdr.y = game.isatb = game.iscate = 0;
877 if (game.state.remcom) {
878 int maxloop = game.state.remcom, l;
879 for (l = 1; l <= maxloop; l++) {
880 if (same(game.state.kcmdr[l], nq)) {
881 game.state.kcmdr[l] = game.state.kcmdr[game.state.remcom];
882 game.state.kcmdr[game.state.remcom].x = game.state.kcmdr[game.state.remcom].y = 0;
886 if (game.state.remcom==0) unschedule(FTBEAM);
891 game.state.remkl -= kldead;
892 /* destroy Romulans and planets in supernovaed quadrant */
893 nrmdead = game.state.galaxy[nq.x][nq.y].romulans;
894 game.state.galaxy[nq.x][nq.y].romulans = 0;
895 game.state.nromrem -= nrmdead;
896 npdead = num - nrmdead*10;
899 for (l = 0; l < game.inplan; l++)
900 if (same(game.state.plnets[l].w, nq)) {
901 DESTROY(&game.state.plnets[l]);
904 /* Destroy any base in supernovaed quadrant */
905 if (game.state.rembase) {
906 int maxloop = game.state.rembase, l;
907 for (l = 1; l <= maxloop; l++)
908 if (same(game.state.baseq[l], nq)) {
909 game.state.baseq[l] = game.state.baseq[game.state.rembase];
910 game.state.baseq[game.state.rembase].x = game.state.baseq[game.state.rembase].y = 0;
911 game.state.rembase--;
915 /* If starship caused supernova, tally up destruction */
917 game.state.starkl += game.state.galaxy[nq.x][nq.y].stars;
918 game.state.basekl += game.state.galaxy[nq.x][nq.y].starbase;
919 game.state.nplankl += npdead;
921 /* mark supernova in galaxy and in star chart */
922 if (same(game.quadrant, nq) || game.damage[DRADIO] == 0 || game.condit == IHDOCKED)
923 game.state.galaxy[nq.x][nq.y].supernova = true;
924 /* If supernova destroys last Klingons give special message */
925 if (KLINGREM==0 && (nq.x != game.quadrant.x || nq.y != game.quadrant.y)) {
927 if (insx == 0) prout(_("Lucky you!"));
928 proutn(_("A supernova in %s has just destroyed the last Klingons."),
929 cramlc(quadrant, nq));
933 /* if some Klingons remain, continue or die in supernova */
934 if (game.alldone) finish(FSNOVAED);