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, ipage = false, istract = false;
66 struct quadrant *pdest, *q;
71 prout("=== EVENTS from %.2f to %.2f:", game.state.date, fintim);
72 for (i = 1; i < NEVENTS; i++) {
74 case FSNOVA: proutn("=== Supernova "); break;
75 case FTBEAM: proutn("=== T Beam "); break;
76 case FSNAP: proutn("=== Snapshot "); break;
77 case FBATTAK: proutn("=== Base Attack "); break;
78 case FCDBAS: proutn("=== Base Destroy "); break;
79 case FSCMOVE: proutn("=== SC Move "); break;
80 case FSCDBAS: proutn("=== SC Base Destroy "); break;
81 case FDSPROB: proutn("=== Probe Move "); break;
82 case FDISTR: proutn("=== Distress Call "); break;
83 case FENSLV: proutn("=== Enlavement "); break;
84 case FREPRO: proutn("=== Klingon Build "); break;
87 prout("%.2f", scheduled(i));
94 radio_was_broken = damaged(DRADIO);
98 /* Select earliest extraneous event, evcode==0 if no events */
100 if (game.alldone) return;
102 for (l = 1; l < NEVENTS; l++)
103 if (game.future[l].date < datemin) {
106 prout("== Event %d fires", evcode);
107 datemin = game.future[l].date;
109 xtime = datemin-game.state.date;
110 game.state.date = datemin;
111 /* Decrement Federation resources and recompute remaining time */
112 game.state.remres -= (game.state.remkl+4*game.state.remcom)*xtime;
113 game.state.remtime = game.state.remres/(game.state.remkl+4*game.state.remcom);
114 if (game.state.remtime <=0) {
118 /* Any crew left alive? */
119 if (game.state.crew <=0) {
123 /* Is life support adequate? */
124 if (damaged(DLIFSUP) && game.condition != docked) {
125 if (game.lsupres < xtime && game.damage[DLIFSUP] > game.lsupres) {
129 game.lsupres -= xtime;
130 if (game.damage[DLIFSUP] <= xtime) game.lsupres = game.inlsr;
134 if (game.condition == docked) repair /= game.docfac;
135 /* Don't fix Deathray here */
136 for (l=0; l<NDEVICES; l++)
137 if (game.damage[l] > 0.0 && l != DDRAY)
138 game.damage[l] -= (game.damage[l]-repair > 0.0 ? repair : game.damage[l]);
139 /* If radio repaired, update star chart and attack reports */
140 if (radio_was_broken && !damaged(DRADIO)) {
141 prout(_("Lt. Uhura- \"Captain, the sub-space radio is working and"));
142 prout(_(" surveillance reports are coming in."));
149 prout(_(" The star chart is now up to date.\""));
152 /* Cause extraneous event EVCODE to occur */
153 game.optime -= xtime;
155 case FSNOVA: /* Supernova */
156 if (!ipage) pause_game(true);
159 schedule(FSNOVA, expran(0.5*game.intime));
160 if (game.state.galaxy[game.quadrant.x][game.quadrant.y].supernova) return;
162 case FSPY: /* Check with spy to see if S.C. should tractor beam */
163 if (game.state.nscrem == 0 ||
164 ictbeam || istract ||
165 game.condition==docked || game.isatb==1 || game.iscate) return;
167 (game.energy < 2000 && game.torps < 4 && game.shield < 1250) ||
168 (damaged(DPHASER) && (damaged(DPHOTON) || game.torps < 4)) ||
170 (game.energy < 2500 || damaged(DPHASER)) &&
171 (game.torps < 5 || damaged(DPHOTON)))) {
172 /* Tractor-beam her! */
174 yank = distance(game.state.kscmdr, game.quadrant);
175 /********* fall through to FTBEAM code ***********/
178 case FTBEAM: /* Tractor beam */
179 if (evcode==FTBEAM) {
180 if (game.state.remcom == 0) {
184 i = Rand()*game.state.remcom+1.0;
185 yank = square(game.state.kcmdr[i].x-game.quadrant.x) + square(game.state.kcmdr[i].y-game.quadrant.y);
186 if (istract || game.condition == docked || yank == 0) {
187 /* Drats! Have to reschedule */
189 game.optime + expran(1.5*game.intime/game.state.remcom));
193 /* tractor beaming cases merge here */
195 if (!ipage) pause_game(true);
197 game.optime = (10.0/(7.5*7.5))*yank; /* 7.5 is yank rate (warp 7.5) */
202 prout(_(" caught in long range tractor beam--"));
203 /* If Kirk & Co. screwing around on planet, handle */
204 atover(true); /* atover(true) is Grab */
205 if (game.alldone) return;
206 if (game.icraft) { /* Caught in Galileo? */
210 /* Check to see if shuttle is aboard */
211 if (game.iscraft == offship) {
214 prout(_("Galileo, left on the planet surface, is captured"));
215 prout(_("by aliens and made into a flying McDonald's."));
216 game.damage[DSHUTTL] = -10;
217 game.iscraft = removed;
220 prout(_("Galileo, left on the planet surface, is well hidden."));
224 game.quadrant = game.state.kscmdr;
226 game.quadrant = game.state.kcmdr[i];
227 game.sector = randplace(QUADSIZE);
229 proutn(_(" is pulled to "));
230 proutn(cramlc(quadrant, game.quadrant));
232 prout(cramlc(sector, game.sector));
234 prout(_("(Remainder of rest/repair period cancelled.)"));
235 game.resting = false;
238 if (!damaged(DSHIELD) && game.shield > 0) {
239 doshield(true); /* raise shields */
242 else prout(_("(Shields not currently useable.)"));
245 /* Adjust finish time to time of tractor beaming */
246 fintim = game.state.date+game.optime;
248 if (game.state.remcom <= 0) unschedule(FTBEAM);
249 else schedule(FTBEAM, game.optime+expran(1.5*game.intime/game.state.remcom));
251 case FSNAP: /* Snapshot of the universe (for time warp) */
252 game.snapsht = game.state;
253 game.state.snap = true;
254 schedule(FSNAP, expran(0.5 * game.intime));
256 case FBATTAK: /* Commander attacks starbase */
257 if (game.state.remcom==0 || game.state.rembase==0) {
266 if (same(game.state.baseq[j], game.state.kcmdr[k]) &&
267 !same(game.state.baseq[j], game.quadrant) &&
268 !same(game.state.baseq[j], game.state.kscmdr)) {
274 if (j>game.state.rembase) {
275 /* no match found -- try later */
276 schedule(FBATTAK, expran(0.3*game.intime));
280 /* commander + starbase combination found -- launch attack */
281 game.battle = game.state.baseq[j];
282 schedule(FCDBAS, 1.0+3.0*Rand());
283 if (game.isatb) /* extra time if SC already attacking */
284 postpone(FCDBAS, scheduled(FSCDBAS)-game.state.date);
285 game.future[FBATTAK].date = game.future[FCDBAS].date + expran(0.3*game.intime);
286 game.iseenit = false;
287 if (!damaged(DRADIO) && game.condition != docked)
288 break; /* No warning :-( */
290 if (!ipage) pause_game(true);
293 proutn(_("Lt. Uhura- \"Captain, the starbase in "));
294 prout(cramlc(quadrant, game.battle));
295 prout(_(" reports that it is under attack and that it can"));
296 proutn(_(" hold out only until stardate %d"),
297 (int)scheduled(FCDBAS));
302 case FSCDBAS: /* Supercommander destroys base */
305 if (!game.state.galaxy[game.state.kscmdr.x][game.state.kscmdr.y].starbase)
306 break; /* WAS RETURN! */
308 game.battle = game.state.kscmdr;
310 case FCDBAS: /* Commander succeeds in destroying base */
311 if (evcode==FCDBAS) {
313 /* find the lucky pair */
315 if (same(game.state.kcmdr[i], game.battle))
317 if (i > game.state.remcom || game.state.rembase == 0 ||
318 !game.state.galaxy[game.battle.x][game.battle.y].starbase) {
319 /* No action to take after all */
320 game.battle.x = game.battle.y = 0;
324 /* Code merges here for any commander destroying base */
325 /* Not perfect, but will have to do */
326 /* Handle case where base is in same quadrant as starship */
327 if (same(game.battle, game.quadrant)) {
328 game.state.chart[game.battle.x][game.battle.y].starbase = false;
329 game.quad[game.base.x][game.base.y] = IHDOT;
330 game.base.x=game.base.y=0;
333 prout(_("Spock- \"Captain, I believe the starbase has been destroyed.\""));
335 else if (game.state.rembase != 1 &&
336 (!damaged(DRADIO) || game.condition == docked)) {
337 /* Get word via subspace radio */
338 if (!ipage) pause_game(true);
341 prout(_("Lt. Uhura- \"Captain, Starfleet Command reports that"));
342 proutn(_(" the starbase in "));
343 proutn(cramlc(quadrant, game.battle));
344 prout(_(" has been destroyed by"));
346 prout(_("the Klingon Super-Commander"));
347 else prout(_("a Klingon Commander"));
348 game.state.chart[game.battle.x][game.battle.y].starbase = false;
350 /* Remove Starbase from galaxy */
351 game.state.galaxy[game.battle.x][game.battle.y].starbase = false;
353 if (same(game.state.baseq[i], game.battle))
354 game.state.baseq[i] = game.state.baseq[game.state.rembase];
355 game.state.rembase--;
356 if (game.isatb == 2) {
357 /* reinstate a commander's base attack */
362 game.battle.x = game.battle.y = 0;
365 case FSCMOVE: /* Supercommander moves */
366 schedule(FSCMOVE, 0.2777);
367 if (!game.ientesc && !istract && game.isatb != 1 &&
368 (!game.iscate || !game.justin))
371 case FDSPROB: /* Move deep space probe */
372 schedule(FDSPROB, 0.01);
373 game.probex += game.probeinx;
374 game.probey += game.probeiny;
375 i = (int)(game.probex/QUADSIZE +0.05);
376 j = (int)(game.probey/QUADSIZE + 0.05);
377 if (game.probec.x != i || game.probec.y != j) {
380 if (!VALID_QUADRANT(i, j) ||
381 game.state.galaxy[game.probec.x][game.probec.y].supernova) {
382 // Left galaxy or ran into supernova
383 if (!damaged(DRADIO) || game.condition == docked) {
384 if (!ipage) pause_game(true);
387 proutn(_("Lt. Uhura- \"The deep space probe "));
388 if (!VALID_QUADRANT(j, i))
389 proutn(_("has left the galaxy"));
391 proutn(_("is no longer transmitting"));
397 if (!damaged(DRADIO) || game.condition == docked) {
398 if (!ipage) pause_game(true);
401 proutn(_("Lt. Uhura- \"The deep space probe is now in "));
402 proutn(cramlc(quadrant, game.probec));
406 pdest = &game.state.galaxy[game.probec.x][game.probec.y];
407 /* Update star chart if Radio is working or have access to
409 if (!damaged(DRADIO) || game.condition == docked) {
410 struct page *chp = &game.state.chart[game.probec.x][game.probec.y];
412 chp->klingons = pdest->klingons;
413 chp->starbase = pdest->starbase;
414 chp->stars = pdest->stars;
415 pdest->charted = true;
417 game.proben--; // One less to travel
418 if (game.proben == 0 && game.isarmed && pdest->stars) {
419 /* lets blow the sucker! */
420 snova(true, &game.probec);
422 if (game.state.galaxy[game.quadrant.x][game.quadrant.y].supernova)
426 case FDISTR: /* inhabited system issues distress call */
428 /* try a whole bunch of times to find something suitable */
431 /* need a quadrant which is not the current one,
432 which has some stars which are inhabited and
433 not already under attack, which is not
434 supernova'ed, and which has some Klingons in it */
435 w = randplace(GALSIZE);
436 q = &game.state.galaxy[w.x][w.y];
438 (same(game.quadrant, w) || q->planet == NOPLANET ||
439 q->supernova || q->status!=secure || q->klingons<=0));
441 /* can't seem to find one; ignore this call */
443 prout("=== Couldn't find location for distress event.");
447 /* got one!! Schedule its enslavement */
448 ev = schedule(FENSLV, expran(game.intime));
450 q->status = distressed;
452 /* tell the captain about it if we can */
453 if (!damaged(DRADIO) || game.condition == docked)
455 prout("Uhura- Captain, %s in %s reports it is under attack",
456 systnames[q->planet], cramlc(quadrant, w));
457 prout("by a Klingon invasion fleet.");
462 case FENSLV: /* starsystem is enslaved */
463 ev = unschedule(FENSLV);
464 /* see if current distress call still active */
465 q = &game.state.galaxy[ev->quadrant.x][ev->quadrant.y];
466 if (q->klingons <= 0) {
470 q->status = enslaved;
472 /* play stork and schedule the first baby */
473 ev2 = schedule(FREPRO, expran(2.0 * game.intime));
474 ev2->quadrant = ev->quadrant;
476 /* report the disaster if we can */
477 if (!damaged(DRADIO) || game.condition == docked)
479 prout("Uhura- We've lost contact with starsystem %s",
480 systnames[q->planet]);
481 prout("in %s.\n", cramlc(quadrant, ev->quadrant));
484 case FREPRO: /* Klingon reproduces */
486 * If we ever switch to a real event queue, we'll need to
487 * explicitly retrieve and restore the x and y.
489 ev = schedule(FREPRO, expran(1.0 * game.intime));
490 /* see if current distress call still active */
491 q = &game.state.galaxy[ev->quadrant.x][ev->quadrant.y];
492 if (q->klingons <= 0) {
496 if (game.state.remkl >=MAXKLGAME)
497 break; /* full right now */
498 /* reproduce one Klingon */
500 if (game.klhere >= MAXKLQUAD) {
501 /* this quadrant not ok, pick an adjacent one */
502 for (i = w.x - 1; i <= w.x + 1; i++)
504 for (j = w.y - 1; j <= w.y + 1; j++)
506 if (!VALID_QUADRANT(i, j))
508 q = &game.state.galaxy[w.x][w.y];
509 /* check for this quad ok (not full & no snova) */
510 if (q->klingons >= MAXKLQUAD || q->supernova)
515 break; /* search for eligible quadrant failed */
521 /* deliver the child */
524 if (same(game.quadrant, w))
525 newkling(++game.klhere);
527 /* recompute time left */
528 game.state.remtime = game.state.remres/(game.state.remkl+4*game.state.remcom);
529 /* report the disaster if we can */
530 if (!damaged(DRADIO) || game.condition == docked)
532 if (same(game.quadrant, w)) {
533 prout("Spock- sensors indicate the Klingons have");
534 prout("launched a warship from %s.", systnames[q->planet]);
536 prout("Uhura- Starfleet reports increased Klingon activity");
537 if (q->planet != NOPLANET)
538 proutn("near %s", systnames[q->planet]);
539 prout("in %s.\n", cramlc(quadrant, w));
552 double temp, delay, origTime;
557 if (key != IHEOL) break;
558 proutn(_("How long? "));
565 origTime = delay = aaitem;
566 if (delay <= 0.0) return;
567 if (delay >= game.state.remtime || game.nenhere != 0) {
568 proutn(_("Are you sure? "));
569 if (ja() == false) return;
572 /* Alternate resting periods (events) with attacks */
576 if (delay <= 0) game.resting = false;
578 prout(_("%d stardates left."), (int)game.state.remtime);
581 temp = game.optime = delay;
584 double rtime = 1.0 + Rand();
585 if (rtime < temp) temp = rtime;
588 if (game.optime < delay) attack(false);
589 if (game.alldone) return;
592 if (game.alldone) return;
594 /* Repair Deathray if long rest at starbase */
595 if (origTime-delay >= 9.99 && game.condition == docked)
596 game.damage[DDRAY] = 0.0;
598 // leave if quadrant supernovas
599 (!game.state.galaxy[game.quadrant.x][game.quadrant.y].supernova);
601 game.resting = false;
606 * A nova occurs. It is the result of having a star hit with a
607 * photon torpedo, or possibly of a probe warhead going off.
608 * Stars that go nova cause stars which surround them to undergo
609 * the same probabilistic process. Klingons next to them are
610 * destroyed. And if the starship is next to it, it gets zapped.
611 * If the zap is too much, it gets destroyed.
616 static double course[] =
617 {0.0, 10.5, 12.0, 1.5, 9.0, 0.0, 3.0, 7.5, 6.0, 4.5};
618 int bot, top, top2, hits[QUADSIZE+1][3], kount, icx, icy, mm, nn, j;
619 int iquad, iquad1, i, ll;
623 /* Wow! We've supernova'ed */
628 /* handle initial nova */
629 game.quad[nov.x][nov.y] = IHDOT;
630 crmena(false, IHSTAR, sector, nov);
632 game.state.galaxy[game.quadrant.x][game.quadrant.y].stars--;
635 /* Set up stack to recursively trigger adjacent stars */
636 bot = top = top2 = 1;
642 for (mm = bot; mm <= top; mm++)
643 for (nn = 1; nn <= 3; nn++) /* nn,j represents coordinates around current */
644 for (j = 1; j <= 3; j++) {
645 if (j==2 && nn== 2) continue;
646 scratch.x = hits[mm][1]+nn-2;
647 scratch.y = hits[mm][2]+j-2;
648 if (!VALID_SECTOR(scratch.y, scratch.x)) continue;
649 iquad = game.quad[scratch.x][scratch.y];
651 // case IHDOT: /* Empty space ends reaction
658 case IHSTAR: /* Affect another star */
660 /* This star supernovas */
661 snova(false, &scratch);
665 hits[top2][1]=scratch.x;
666 hits[top2][2]=scratch.y;
667 game.state.galaxy[game.quadrant.x][game.quadrant.y].stars -= 1;
669 crmena(true, IHSTAR, sector, scratch);
671 game.quad[scratch.x][scratch.y] = IHDOT;
673 case IHP: /* Destroy planet */
674 game.state.galaxy[game.quadrant.x][game.quadrant.y].planet = NOPLANET;
675 game.state.nplankl++;
676 crmena(true, IHP, sector, scratch);
677 prout(_(" destroyed."));
678 DESTROY(&game.state.plnets[game.iplnet]);
679 game.iplnet = game.plnet.x = game.plnet.y = 0;
684 game.quad[scratch.x][scratch.y] = IHDOT;
686 case IHB: /* Destroy base */
687 game.state.galaxy[game.quadrant.x][game.quadrant.y].starbase = false;
689 if (same(game.state.baseq[i], game.quadrant))
691 game.state.baseq[i] = game.state.baseq[game.state.rembase];
692 game.state.rembase--;
693 game.base.x = game.base.y = 0;
696 crmena(true, IHB, sector, scratch);
697 prout(_(" destroyed."));
698 game.quad[scratch.x][scratch.y] = IHDOT;
700 case IHE: /* Buffet ship */
702 prout(_("***Starship buffeted by nova."));
704 if (game.shield >= 2000.0) game.shield -= 2000.0;
706 double diff = 2000.0 - game.shield;
710 prout(_("***Shields knocked out."));
711 game.damage[DSHIELD] += 0.005*game.damfac*Rand()*diff;
714 else game.energy -= 2000.0;
715 if (game.energy <= 0) {
719 /* add in course nova contributes to kicking starship*/
720 icx += game.sector.x-hits[mm][1];
721 icy += game.sector.y-hits[mm][2];
724 case IHK: /* kill klingon */
725 deadkl(scratch,iquad, scratch);
727 case IHC: /* Damage/destroy big enemies */
730 for_local_enemies(ll)
731 if (same(game.ks[ll], scratch)) break;
732 game.kpower[ll] -= 800.0; /* If firepower is lost, die */
733 if (game.kpower[ll] <= 0.0) {
734 deadkl(scratch, iquad, scratch);
737 newc.x = scratch.x + scratch.x - hits[mm][1];
738 newc.y = scratch.y + scratch.y - hits[mm][2];
739 crmena(true, iquad, sector, scratch);
740 proutn(_(" damaged"));
741 if (!VALID_SECTOR(newc.x, newc.y)) {
742 /* can't leave quadrant */
746 iquad1 = game.quad[newc.x][newc.y];
747 if (iquad1 == IHBLANK) {
748 proutn(_(", blasted into "));
749 crmena(false, IHBLANK, sector, newc);
751 deadkl(scratch, iquad, newc);
754 if (iquad1 != IHDOT) {
755 /* can't move into something else */
759 proutn(_(", buffeted to "));
760 proutn(cramlc(sector, newc));
761 game.quad[scratch.x][scratch.y] = IHDOT;
762 game.quad[newc.x][newc.y] = iquad;
764 game.kdist[ll] = game.kavgd[ll] = distance(game.sector, newc);
777 /* Starship affected by nova -- kick it away. */
778 game.dist = kount*0.1;
779 if (icx) icx = (icx < 0 ? -1 : 1);
780 if (icy) icy = (icy < 0 ? -1 : 1);
781 game.direc = course[3*(icx+1)+icy+2];
782 if (game.direc == 0.0) game.dist = 0.0;
783 if (game.dist == 0.0) return;
784 game.optime = 10.0*game.dist/16.0;
786 prout(_("Force of nova displaces starship."));
787 game.iattak=2; /* Eliminates recursion problem */
789 game.optime = 10.0*game.dist/16.0;
794 void snova(bool induced, coord *w)
795 /* star goes supernova */
797 int num = 0, nrmdead, npdead, kldead;
804 /* Scheduled supernova -- select star */
805 /* logic changed here so that we won't favor quadrants in top
807 for_quadrants(nq.x) {
808 for_quadrants(nq.y) {
809 stars += game.state.galaxy[nq.x][nq.y].stars;
812 if (stars == 0) return; /* nothing to supernova exists */
813 num = Rand()*stars + 1;
814 for_quadrants(nq.x) {
815 for_quadrants(nq.y) {
816 num -= game.state.galaxy[nq.x][nq.y].stars;
822 proutn("=== Super nova here?");
828 if (!same(nq, game.quadrant) || game.justin) {
829 /* it isn't here, or we just entered (treat as enroute) */
830 if (!damaged(DRADIO) || game.condition == docked) {
832 prout(_("Message from Starfleet Command Stardate %.2f"), game.state.date);
833 prout(_(" Supernova in %s; caution advised."),
834 cramlc(quadrant, nq));
839 /* we are in the quadrant! */
840 num = Rand()* game.state.galaxy[nq.x][nq.y].stars + 1;
843 if (game.quad[ns.x][ns.y]==IHSTAR) {
852 prouts(_("***RED ALERT! RED ALERT!"));
854 prout(_("***Incipient supernova detected at "), cramlc(sector, ns));
855 if (square(ns.x-game.sector.x) + square(ns.y-game.sector.y) <= 2.1) {
856 proutn(_("Emergency override attempts t"));
857 prouts("***************");
864 /* destroy any Klingons in supernovaed quadrant */
865 kldead = game.state.galaxy[nq.x][nq.y].klingons;
866 game.state.galaxy[nq.x][nq.y].klingons = 0;
867 if (same(nq, game.state.kscmdr)) {
868 /* did in the Supercommander! */
869 game.state.nscrem = game.state.kscmdr.x = game.state.kscmdr.y = game.isatb = 0;
874 if (game.state.remcom) {
875 int maxloop = game.state.remcom, l;
876 for (l = 1; l <= maxloop; l++) {
877 if (same(game.state.kcmdr[l], nq)) {
878 game.state.kcmdr[l] = game.state.kcmdr[game.state.remcom];
879 game.state.kcmdr[game.state.remcom].x = game.state.kcmdr[game.state.remcom].y = 0;
882 if (game.state.remcom==0) unschedule(FTBEAM);
887 game.state.remkl -= kldead;
888 /* destroy Romulans and planets in supernovaed quadrant */
889 nrmdead = game.state.galaxy[nq.x][nq.y].romulans;
890 game.state.galaxy[nq.x][nq.y].romulans = 0;
891 game.state.nromrem -= nrmdead;
892 npdead = num - nrmdead*10;
895 for (loop = 0; loop < game.inplan; loop++)
896 if (same(game.state.plnets[loop].w, nq)) {
897 DESTROY(&game.state.plnets[loop]);
900 /* Destroy any base in supernovaed quadrant */
901 if (game.state.rembase) {
902 int maxloop = game.state.rembase, loop;
903 for (loop = 1; loop <= maxloop; loop++)
904 if (same(game.state.baseq[loop], nq)) {
905 game.state.baseq[loop] = game.state.baseq[game.state.rembase];
906 game.state.baseq[game.state.rembase].x = game.state.baseq[game.state.rembase].y = 0;
907 game.state.rembase--;
911 /* If starship caused supernova, tally up destruction */
913 game.state.starkl += game.state.galaxy[nq.x][nq.y].stars;
914 game.state.basekl += game.state.galaxy[nq.x][nq.y].starbase;
915 game.state.nplankl += npdead;
917 /* mark supernova in galaxy and in star chart */
918 if (same(game.quadrant, nq) || !damaged(DRADIO) || game.condition == docked)
919 game.state.galaxy[nq.x][nq.y].supernova = true;
920 /* If supernova destroys last Klingons give special message */
921 if (KLINGREM==0 && !same(nq, game.quadrant)) {
923 if (!induced) prout(_("Lucky you!"));
924 proutn(_("A supernova in %s has just destroyed the last Klingons."),
925 cramlc(quadrant, nq));
929 /* if some Klingons remain, continue or die in supernova */
930 if (game.alldone) finish(FSNOVAED);