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)
45 /* rest period is interrupted by event */
49 proutn(_("Mr. Spock- \"Captain, shall we cancel the rest period?\""));
61 /* run through the event queue looking for things to do */
63 int evcode, i=0, j, k, l;
64 double fintim = game.state.date + game.optime, datemin, xtime, repair, yank=0;
65 bool radio_was_broken, ictbeam = false, istract = false;
66 struct quadrant *pdest, *q;
73 prout("=== EVENTS from %.2f to %.2f:", game.state.date, fintim);
74 for (i = 1; i < NEVENTS; i++) {
76 case FSNOVA: proutn("=== Supernova "); break;
77 case FTBEAM: proutn("=== T Beam "); break;
78 case FSNAP: proutn("=== Snapshot "); break;
79 case FBATTAK: proutn("=== Base Attack "); break;
80 case FCDBAS: proutn("=== Base Destroy "); break;
81 case FSCMOVE: proutn("=== SC Move "); break;
82 case FSCDBAS: proutn("=== SC Base Destroy "); break;
83 case FDSPROB: proutn("=== Probe Move "); break;
84 case FDISTR: proutn("=== Distress Call "); break;
85 case FENSLV: proutn("=== Enlavement "); break;
86 case FREPRO: proutn("=== Klingon Build "); break;
89 prout("%.2f", scheduled(i));
96 radio_was_broken = damaged(DRADIO);
100 /* Select earliest extraneous event, evcode==0 if no events */
105 for (l = 1; l < NEVENTS; l++)
106 if (game.future[l].date < datemin) {
109 prout("== Event %d fires", evcode);
110 datemin = game.future[l].date;
112 xtime = datemin-game.state.date;
113 game.state.date = datemin;
114 /* Decrement Federation resources and recompute remaining time */
115 game.state.remres -= (game.state.remkl+4*game.state.remcom)*xtime;
116 game.state.remtime = game.state.remres/(game.state.remkl+4*game.state.remcom);
117 if (game.state.remtime <=0) {
121 /* Any crew left alive? */
122 if (game.state.crew <=0) {
126 /* Is life support adequate? */
127 if (damaged(DLIFSUP) && game.condition != docked) {
128 if (game.lsupres < xtime && game.damage[DLIFSUP] > game.lsupres) {
132 game.lsupres -= xtime;
133 if (game.damage[DLIFSUP] <= xtime)
134 game.lsupres = game.inlsr;
138 if (game.condition == docked)
139 repair /= game.docfac;
140 /* Don't fix Deathray here */
141 for (l=0; l<NDEVICES; l++)
142 if (game.damage[l] > 0.0 && l != DDRAY)
143 game.damage[l] -= (game.damage[l]-repair > 0.0 ? repair : game.damage[l]);
144 /* If radio repaired, update star chart and attack reports */
145 if (radio_was_broken && !damaged(DRADIO)) {
146 prout(_("Lt. Uhura- \"Captain, the sub-space radio is working and"));
147 prout(_(" surveillance reports are coming in."));
154 prout(_(" The star chart is now up to date.\""));
157 /* Cause extraneous event EVCODE to occur */
158 game.optime -= xtime;
160 case FSNOVA: /* Supernova */
163 schedule(FSNOVA, expran(0.5*game.intime));
164 if (game.state.galaxy[game.quadrant.x][game.quadrant.y].supernova)
167 case FSPY: /* Check with spy to see if S.C. should tractor beam */
168 if (game.state.nscrem == 0 ||
169 ictbeam || istract ||
170 game.condition==docked || game.isatb==1 || game.iscate) return;
172 (game.energy < 2000 && game.torps < 4 && game.shield < 1250) ||
173 (damaged(DPHASER) && (damaged(DPHOTON) || game.torps < 4)) ||
175 (game.energy < 2500 || damaged(DPHASER)) &&
176 (game.torps < 5 || damaged(DPHOTON)))) {
177 /* Tractor-beam her! */
179 yank = distance(game.state.kscmdr, game.quadrant);
180 /********* fall through to FTBEAM code ***********/
184 case FTBEAM: /* Tractor beam */
185 if (evcode==FTBEAM) {
186 if (game.state.remcom == 0) {
190 i = Rand()*game.state.remcom+1.0;
191 yank = square(game.state.kcmdr[i].x-game.quadrant.x) + square(game.state.kcmdr[i].y-game.quadrant.y);
192 if (istract || game.condition == docked || yank == 0) {
193 /* Drats! Have to reschedule */
195 game.optime + expran(1.5*game.intime/game.state.remcom));
199 /* tractor beaming cases merge here */
202 game.optime = (10.0/(7.5*7.5))*yank; /* 7.5 is yank rate (warp 7.5) */
207 prout(_(" caught in long range tractor beam--"));
208 /* If Kirk & Co. screwing around on planet, handle */
209 atover(true); /* atover(true) is Grab */
212 if (game.icraft) { /* Caught in Galileo? */
216 /* Check to see if shuttle is aboard */
217 if (game.iscraft == offship) {
220 prout(_("Galileo, left on the planet surface, is captured"));
221 prout(_("by aliens and made into a flying McDonald's."));
222 game.damage[DSHUTTL] = -10;
223 game.iscraft = removed;
226 prout(_("Galileo, left on the planet surface, is well hidden."));
230 game.quadrant = game.state.kscmdr;
232 game.quadrant = game.state.kcmdr[i];
233 game.sector = randplace(QUADSIZE);
235 proutn(_(" is pulled to "));
236 proutn(cramlc(quadrant, game.quadrant));
238 prout(cramlc(sector, game.sector));
240 prout(_("(Remainder of rest/repair period cancelled.)"));
241 game.resting = false;
244 if (!damaged(DSHIELD) && game.shield > 0) {
245 doshield(true); /* raise shields */
249 prout(_("(Shields not currently useable.)"));
252 /* Adjust finish time to time of tractor beaming */
253 fintim = game.state.date+game.optime;
255 if (game.state.remcom <= 0)
258 schedule(FTBEAM, game.optime+expran(1.5*game.intime/game.state.remcom));
260 case FSNAP: /* Snapshot of the universe (for time warp) */
261 game.snapsht = game.state;
262 game.state.snap = true;
263 schedule(FSNAP, expran(0.5 * game.intime));
265 case FBATTAK: /* Commander attacks starbase */
266 if (game.state.remcom==0 || game.state.rembase==0) {
275 if (same(game.state.baseq[j], game.state.kcmdr[k]) &&
276 !same(game.state.baseq[j], game.quadrant) &&
277 !same(game.state.baseq[j], game.state.kscmdr)) {
284 if (j>game.state.rembase) {
285 /* no match found -- try later */
286 schedule(FBATTAK, expran(0.3*game.intime));
290 /* commander + starbase combination found -- launch attack */
291 game.battle = game.state.baseq[j];
292 schedule(FCDBAS, 1.0+3.0*Rand());
293 if (game.isatb) /* extra time if SC already attacking */
294 postpone(FCDBAS, scheduled(FSCDBAS)-game.state.date);
295 game.future[FBATTAK].date = game.future[FCDBAS].date + expran(0.3*game.intime);
296 game.iseenit = false;
297 if (!damaged(DRADIO) && game.condition != docked)
298 break; /* No warning :-( */
302 proutn(_("Lt. Uhura- \"Captain, the starbase in "));
303 prout(cramlc(quadrant, game.battle));
304 prout(_(" reports that it is under attack and that it can"));
305 proutn(_(" hold out only until stardate %d"),
306 (int)scheduled(FCDBAS));
311 case FSCDBAS: /* Supercommander destroys base */
314 if (!game.state.galaxy[game.state.kscmdr.x][game.state.kscmdr.y].starbase)
315 break; /* WAS RETURN! */
317 game.battle = game.state.kscmdr;
319 case FCDBAS: /* Commander succeeds in destroying base */
320 if (evcode==FCDBAS) {
322 /* find the lucky pair */
324 if (same(game.state.kcmdr[i], game.battle))
326 if (i > game.state.remcom || game.state.rembase == 0 ||
327 !game.state.galaxy[game.battle.x][game.battle.y].starbase) {
328 /* No action to take after all */
329 invalidate(game.battle);
333 /* Code merges here for any commander destroying base */
334 /* Not perfect, but will have to do */
335 /* Handle case where base is in same quadrant as starship */
336 if (same(game.battle, game.quadrant)) {
337 game.state.chart[game.battle.x][game.battle.y].starbase = false;
338 game.quad[game.base.x][game.base.y] = IHDOT;
339 game.base.x=game.base.y=0;
342 prout(_("Spock- \"Captain, I believe the starbase has been destroyed.\""));
344 else if (game.state.rembase != 1 &&
345 (!damaged(DRADIO) || game.condition == docked)) {
346 /* Get word via subspace radio */
349 prout(_("Lt. Uhura- \"Captain, Starfleet Command reports that"));
350 proutn(_(" the starbase in "));
351 proutn(cramlc(quadrant, game.battle));
352 prout(_(" has been destroyed by"));
354 prout(_("the Klingon Super-Commander"));
356 prout(_("a Klingon Commander"));
357 game.state.chart[game.battle.x][game.battle.y].starbase = false;
359 /* Remove Starbase from galaxy */
360 game.state.galaxy[game.battle.x][game.battle.y].starbase = false;
362 if (same(game.state.baseq[i], game.battle))
363 game.state.baseq[i] = game.state.baseq[game.state.rembase];
364 game.state.rembase--;
365 if (game.isatb == 2) {
366 /* reinstate a commander's base attack */
371 invalidate(game.battle);
373 case FSCMOVE: /* Supercommander moves */
374 schedule(FSCMOVE, 0.2777);
375 if (!game.ientesc && !istract && game.isatb != 1 &&
376 (!game.iscate || !game.justin))
379 case FDSPROB: /* Move deep space probe */
380 schedule(FDSPROB, 0.01);
381 game.probex += game.probeinx;
382 game.probey += game.probeiny;
383 i = (int)(game.probex/QUADSIZE +0.05);
384 j = (int)(game.probey/QUADSIZE + 0.05);
385 if (game.probec.x != i || game.probec.y != j) {
388 if (!VALID_QUADRANT(i, j) ||
389 game.state.galaxy[game.probec.x][game.probec.y].supernova) {
390 // Left galaxy or ran into supernova
391 if (!damaged(DRADIO) || game.condition == docked) {
394 proutn(_("Lt. Uhura- \"The deep space probe "));
395 if (!VALID_QUADRANT(j, i))
396 proutn(_("has left the galaxy"));
398 proutn(_("is no longer transmitting"));
404 if (!damaged(DRADIO) || game.condition == docked) {
407 proutn(_("Lt. Uhura- \"The deep space probe is now in "));
408 proutn(cramlc(quadrant, game.probec));
412 pdest = &game.state.galaxy[game.probec.x][game.probec.y];
413 /* Update star chart if Radio is working or have access to
415 if (!damaged(DRADIO) || game.condition == docked) {
416 struct page *chp = &game.state.chart[game.probec.x][game.probec.y];
418 chp->klingons = pdest->klingons;
419 chp->starbase = pdest->starbase;
420 chp->stars = pdest->stars;
421 pdest->charted = true;
423 game.proben--; // One less to travel
424 if (game.proben == 0 && game.isarmed && pdest->stars) {
425 /* lets blow the sucker! */
426 snova(true, &game.probec);
428 if (game.state.galaxy[game.quadrant.x][game.quadrant.y].supernova)
432 case FDISTR: /* inhabited system issues distress call */
434 /* try a whole bunch of times to find something suitable */
437 /* need a quadrant which is not the current one,
438 which has some stars which are inhabited and
439 not already under attack, which is not
440 supernova'ed, and which has some Klingons in it */
441 w = randplace(GALSIZE);
442 q = &game.state.galaxy[w.x][w.y];
444 (same(game.quadrant, w) || q->planet == NOPLANET ||
445 q->supernova || q->status!=secure || q->klingons<=0));
447 /* can't seem to find one; ignore this call */
449 prout("=== Couldn't find location for distress event.");
453 /* got one!! Schedule its enslavement */
454 ev = schedule(FENSLV, expran(game.intime));
456 q->status = distressed;
458 /* tell the captain about it if we can */
459 if (!damaged(DRADIO) || game.condition == docked)
461 prout("Uhura- Captain, %s in %s reports it is under attack",
462 systnames[q->planet], cramlc(quadrant, w));
463 prout("by a Klingon invasion fleet.");
468 case FENSLV: /* starsystem is enslaved */
469 ev = unschedule(FENSLV);
470 /* see if current distress call still active */
471 q = &game.state.galaxy[ev->quadrant.x][ev->quadrant.y];
472 if (q->klingons <= 0) {
476 q->status = enslaved;
478 /* play stork and schedule the first baby */
479 ev2 = schedule(FREPRO, expran(2.0 * game.intime));
480 ev2->quadrant = ev->quadrant;
482 /* report the disaster if we can */
483 if (!damaged(DRADIO) || game.condition == docked)
485 prout("Uhura- We've lost contact with starsystem %s",
486 systnames[q->planet]);
487 prout("in %s.\n", cramlc(quadrant, ev->quadrant));
490 case FREPRO: /* Klingon reproduces */
492 * If we ever switch to a real event queue, we'll need to
493 * explicitly retrieve and restore the x and y.
495 ev = schedule(FREPRO, expran(1.0 * game.intime));
496 /* see if current distress call still active */
497 q = &game.state.galaxy[ev->quadrant.x][ev->quadrant.y];
498 if (q->klingons <= 0) {
502 if (game.state.remkl >=MAXKLGAME)
503 break; /* full right now */
504 /* reproduce one Klingon */
506 if (game.klhere >= MAXKLQUAD) {
507 /* this quadrant not ok, pick an adjacent one */
508 for (i = w.x - 1; i <= w.x + 1; i++)
510 for (j = w.y - 1; j <= w.y + 1; j++)
512 if (!VALID_QUADRANT(i, j))
514 q = &game.state.galaxy[w.x][w.y];
515 /* check for this quad ok (not full & no snova) */
516 if (q->klingons >= MAXKLQUAD || q->supernova)
521 break; /* search for eligible quadrant failed */
527 /* deliver the child */
530 if (same(game.quadrant, w))
531 newkling(++game.klhere);
533 /* recompute time left */
534 game.state.remtime = game.state.remres/(game.state.remkl+4*game.state.remcom);
535 /* report the disaster if we can */
536 if (!damaged(DRADIO) || game.condition == docked)
538 if (same(game.quadrant, w)) {
539 prout("Spock- sensors indicate the Klingons have");
540 prout("launched a warship from %s.", systnames[q->planet]);
542 prout("Uhura- Starfleet reports increased Klingon activity");
543 if (q->planet != NOPLANET)
544 proutn("near %s", systnames[q->planet]);
545 prout("in %s.\n", cramlc(quadrant, w));
558 double temp, delay, origTime;
565 proutn(_("How long? "));
572 origTime = delay = aaitem;
575 if (delay >= game.state.remtime || game.nenhere != 0) {
576 proutn(_("Are you sure? "));
581 /* Alternate resting periods (events) with attacks */
586 game.resting = false;
588 prout(_("%d stardates left."), (int)game.state.remtime);
591 temp = game.optime = delay;
594 double rtime = 1.0 + Rand();
599 if (game.optime < delay)
608 /* Repair Deathray if long rest at starbase */
609 if (origTime-delay >= 9.99 && game.condition == docked)
610 game.damage[DDRAY] = 0.0;
612 // leave if quadrant supernovas
613 (!game.state.galaxy[game.quadrant.x][game.quadrant.y].supernova);
615 game.resting = false;
620 * A nova occurs. It is the result of having a star hit with a
621 * photon torpedo, or possibly of a probe warhead going off.
622 * Stars that go nova cause stars which surround them to undergo
623 * the same probabilistic process. Klingons next to them are
624 * destroyed. And if the starship is next to it, it gets zapped.
625 * If the zap is too much, it gets destroyed.
630 static double course[] =
631 {0.0, 10.5, 12.0, 1.5, 9.0, 0.0, 3.0, 7.5, 6.0, 4.5};
632 int bot, top, top2, hits[QUADSIZE+1][3], kount, icx, icy, mm, nn, j;
633 int iquad, iquad1, i, ll;
637 /* Wow! We've supernova'ed */
642 /* handle initial nova */
643 game.quad[nov.x][nov.y] = IHDOT;
644 crmena(false, IHSTAR, sector, nov);
646 game.state.galaxy[game.quadrant.x][game.quadrant.y].stars--;
649 /* Set up stack to recursively trigger adjacent stars */
650 bot = top = top2 = 1;
656 for (mm = bot; mm <= top; mm++)
657 for (nn = 1; nn <= 3; nn++) /* nn,j represents coordinates around current */
658 for (j = 1; j <= 3; j++) {
661 scratch.x = hits[mm][1]+nn-2;
662 scratch.y = hits[mm][2]+j-2;
663 if (!VALID_SECTOR(scratch.y, scratch.x))
665 iquad = game.quad[scratch.x][scratch.y];
667 // case IHDOT: /* Empty space ends reaction
674 case IHSTAR: /* Affect another star */
676 /* This star supernovas */
677 snova(false, &scratch);
681 hits[top2][1]=scratch.x;
682 hits[top2][2]=scratch.y;
683 game.state.galaxy[game.quadrant.x][game.quadrant.y].stars -= 1;
685 crmena(true, IHSTAR, sector, scratch);
687 game.quad[scratch.x][scratch.y] = IHDOT;
689 case IHP: /* Destroy planet */
690 game.state.galaxy[game.quadrant.x][game.quadrant.y].planet = NOPLANET;
691 game.state.nplankl++;
692 crmena(true, IHP, sector, scratch);
693 prout(_(" destroyed."));
694 DESTROY(&game.state.planets[game.iplnet]);
696 invalidate(game.plnet);
701 game.quad[scratch.x][scratch.y] = IHDOT;
703 case IHB: /* Destroy base */
704 game.state.galaxy[game.quadrant.x][game.quadrant.y].starbase = false;
706 if (same(game.state.baseq[i], game.quadrant))
708 game.state.baseq[i] = game.state.baseq[game.state.rembase];
709 game.state.rembase--;
710 invalidate(game.base);
713 crmena(true, IHB, sector, scratch);
714 prout(_(" destroyed."));
715 game.quad[scratch.x][scratch.y] = IHDOT;
717 case IHE: /* Buffet ship */
719 prout(_("***Starship buffeted by nova."));
721 if (game.shield >= 2000.0)
722 game.shield -= 2000.0;
724 double diff = 2000.0 - game.shield;
728 prout(_("***Shields knocked out."));
729 game.damage[DSHIELD] += 0.005*game.damfac*Rand()*diff;
733 game.energy -= 2000.0;
734 if (game.energy <= 0) {
738 /* add in course nova contributes to kicking starship*/
739 icx += game.sector.x-hits[mm][1];
740 icy += game.sector.y-hits[mm][2];
743 case IHK: /* kill klingon */
744 deadkl(scratch,iquad, scratch);
746 case IHC: /* Damage/destroy big enemies */
749 for_local_enemies(ll)
750 if (same(game.ks[ll], scratch))
752 game.kpower[ll] -= 800.0; /* If firepower is lost, die */
753 if (game.kpower[ll] <= 0.0) {
754 deadkl(scratch, iquad, scratch);
757 newc.x = scratch.x + scratch.x - hits[mm][1];
758 newc.y = scratch.y + scratch.y - hits[mm][2];
759 crmena(true, iquad, sector, scratch);
760 proutn(_(" damaged"));
761 if (!VALID_SECTOR(newc.x, newc.y)) {
762 /* can't leave quadrant */
766 iquad1 = game.quad[newc.x][newc.y];
767 if (iquad1 == IHBLANK) {
768 proutn(_(", blasted into "));
769 crmena(false, IHBLANK, sector, newc);
771 deadkl(scratch, iquad, newc);
774 if (iquad1 != IHDOT) {
775 /* can't move into something else */
779 proutn(_(", buffeted to "));
780 proutn(cramlc(sector, newc));
781 game.quad[scratch.x][scratch.y] = IHDOT;
782 game.quad[newc.x][newc.y] = iquad;
784 game.kdist[ll] = game.kavgd[ll] = distance(game.sector, newc);
797 /* Starship affected by nova -- kick it away. */
798 game.dist = kount*0.1;
800 icx = (icx < 0 ? -1 : 1);
802 icy = (icy < 0 ? -1 : 1);
803 game.direc = course[3*(icx+1)+icy+2];
804 if (game.direc == 0.0)
806 if (game.dist == 0.0)
808 game.optime = 10.0*game.dist/16.0;
810 prout(_("Force of nova displaces starship."));
812 game.optime = 10.0*game.dist/16.0;
817 void snova(bool induced, coord *w)
818 /* star goes supernova */
820 int num = 0, nrmdead, npdead, kldead;
827 /* Scheduled supernova -- select star */
828 /* logic changed here so that we won't favor quadrants in top
830 for_quadrants(nq.x) {
831 for_quadrants(nq.y) {
832 stars += game.state.galaxy[nq.x][nq.y].stars;
835 if (stars == 0) return; /* nothing to supernova exists */
836 num = Rand()*stars + 1;
837 for_quadrants(nq.x) {
838 for_quadrants(nq.y) {
839 num -= game.state.galaxy[nq.x][nq.y].stars;
847 proutn("=== Super nova here?");
853 if (!same(nq, game.quadrant) || game.justin) {
854 /* it isn't here, or we just entered (treat as enroute) */
855 if (!damaged(DRADIO) || game.condition == docked) {
857 prout(_("Message from Starfleet Command Stardate %.2f"), game.state.date);
858 prout(_(" Supernova in %s; caution advised."),
859 cramlc(quadrant, nq));
864 /* we are in the quadrant! */
865 num = Rand()* game.state.galaxy[nq.x][nq.y].stars + 1;
868 if (game.quad[ns.x][ns.y]==IHSTAR) {
879 prouts(_("***RED ALERT! RED ALERT!"));
881 prout(_("***Incipient supernova detected at %s"), cramlc(sector, ns));
882 if (square(ns.x-game.sector.x) + square(ns.y-game.sector.y) <= 2.1) {
883 proutn(_("Emergency override attempts t"));
884 prouts("***************");
891 /* destroy any Klingons in supernovaed quadrant */
892 kldead = game.state.galaxy[nq.x][nq.y].klingons;
893 game.state.galaxy[nq.x][nq.y].klingons = 0;
894 if (same(nq, game.state.kscmdr)) {
895 /* did in the Supercommander! */
896 game.state.nscrem = game.state.kscmdr.x = game.state.kscmdr.y = game.isatb = 0;
901 if (game.state.remcom) {
902 int maxloop = game.state.remcom, l;
903 for (l = 1; l <= maxloop; l++) {
904 if (same(game.state.kcmdr[l], nq)) {
905 game.state.kcmdr[l] = game.state.kcmdr[game.state.remcom];
906 invalidate(game.state.kcmdr[game.state.remcom]);
909 if (game.state.remcom==0)
915 game.state.remkl -= kldead;
916 /* destroy Romulans and planets in supernovaed quadrant */
917 nrmdead = game.state.galaxy[nq.x][nq.y].romulans;
918 game.state.galaxy[nq.x][nq.y].romulans = 0;
919 game.state.nromrem -= nrmdead;
920 npdead = num - nrmdead*10;
923 for (loop = 0; loop < game.inplan; loop++)
924 if (same(game.state.planets[loop].w, nq)) {
925 DESTROY(&game.state.planets[loop]);
928 /* Destroy any base in supernovaed quadrant */
929 if (game.state.rembase) {
930 int maxloop = game.state.rembase, loop;
931 for (loop = 1; loop <= maxloop; loop++)
932 if (same(game.state.baseq[loop], nq)) {
933 game.state.baseq[loop] = game.state.baseq[game.state.rembase];
934 invalidate(game.state.baseq[game.state.rembase]);
935 game.state.rembase--;
939 /* If starship caused supernova, tally up destruction */
941 game.state.starkl += game.state.galaxy[nq.x][nq.y].stars;
942 game.state.basekl += game.state.galaxy[nq.x][nq.y].starbase;
943 game.state.nplankl += npdead;
945 /* mark supernova in galaxy and in star chart */
946 if (same(game.quadrant, nq) || !damaged(DRADIO) || game.condition == docked)
947 game.state.galaxy[nq.x][nq.y].supernova = true;
948 /* If supernova destroys last Klingons give special message */
949 if (KLINGREM==0 && !same(nq, game.quadrant)) {
952 prout(_("Lucky you!"));
953 proutn(_("A supernova in %s has just destroyed the last Klingons."),
954 cramlc(quadrant, nq));
958 /* if some Klingons remain, continue or die in supernova */