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 istract=0, 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;
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);
97 /* Select earliest extraneous event, evcode==0 if no events */
99 if (game.alldone) return;
101 for (l = 1; l < NEVENTS; l++)
102 if (game.future[l].date < datemin) {
105 prout("== Event %d fires", evcode);
106 datemin = game.future[l].date;
108 xtime = datemin-game.state.date;
109 game.state.date = datemin;
110 /* Decrement Federation resources and recompute remaining time */
111 game.state.remres -= (game.state.remkl+4*game.state.remcom)*xtime;
112 game.state.remtime = game.state.remres/(game.state.remkl+4*game.state.remcom);
113 if (game.state.remtime <=0) {
117 /* Any crew left alive? */
118 if (game.state.crew <=0) {
122 /* Is life support adequate? */
123 if (damaged(DLIFSUP) && game.condit != IHDOCKED) {
124 if (game.lsupres < xtime && game.damage[DLIFSUP] > game.lsupres) {
128 game.lsupres -= xtime;
129 if (game.damage[DLIFSUP] <= xtime) game.lsupres = game.inlsr;
133 if (game.condit == IHDOCKED) repair /= game.docfac;
134 /* Don't fix Deathray here */
135 for (l=0; l<NDEVICES; l++)
136 if (game.damage[l] > 0.0 && l != DDRAY)
137 game.damage[l] -= (game.damage[l]-repair > 0.0 ? repair : game.damage[l]);
138 /* If radio repaired, update star chart and attack reports */
139 if (radio_was_broken && !damaged(DRADIO)) {
140 prout(_("Lt. Uhura- \"Captain, the sub-space radio is working and"));
141 prout(_(" surveillance reports are coming in."));
143 if (game.iseenit==0) {
148 prout(_(" The star chart is now up to date.\""));
151 /* Cause extraneous event EVCODE to occur */
152 game.optime -= xtime;
154 case FSNOVA: /* Supernova */
155 if (!ipage) pause_game(1);
158 schedule(FSNOVA, expran(0.5*game.intime));
159 if (game.state.galaxy[game.quadrant.x][game.quadrant.y].supernova) return;
161 case FSPY: /* Check with spy to see if S.C. should tractor beam */
162 if (game.state.nscrem == 0 ||
163 ictbeam+istract > 0 ||
164 game.condit==IHDOCKED || game.isatb==1 || game.iscate==1) return;
166 (game.energy < 2000 && game.torps < 4 && game.shield < 1250) ||
167 (damaged(DPHASER) && (damaged(DPHOTON) || game.torps < 4)) ||
169 (game.energy < 2500 || damaged(DPHASER)) &&
170 (game.torps < 5 || damaged(DPHOTON)))) {
171 /* Tractor-beam her! */
173 yank = square(game.state.kscmdr.x-game.quadrant.x) + square(game.state.kscmdr.y-game.quadrant.y);
174 /********* fall through to FTBEAM code ***********/
177 case FTBEAM: /* Tractor beam */
178 if (evcode==FTBEAM) {
179 if (game.state.remcom == 0) {
183 i = Rand()*game.state.remcom+1.0;
184 yank = square(game.state.kcmdr[i].x-game.quadrant.x) + square(game.state.kcmdr[i].y-game.quadrant.y);
185 if (istract || game.condit == IHDOCKED || yank == 0) {
186 /* Drats! Have to reschedule */
188 game.optime + expran(1.5*game.intime/game.state.remcom));
192 /* tractor beaming cases merge here */
194 if (!ipage) pause_game(1);
196 game.optime = (10.0/(7.5*7.5))*yank; /* 7.5 is yank rate (warp 7.5) */
201 prout(_(" caught in long range tractor beam--"));
202 /* If Kirk & Co. screwing around on planet, handle */
203 atover(true); /* atover(true) is Grab */
204 if (game.alldone) return;
205 if (game.icraft == 1) { /* Caught in Galileo? */
209 /* Check to see if shuttle is aboard */
210 if (game.iscraft==0) {
213 prout(_("Galileo, left on the planet surface, is captured"));
214 prout(_("by aliens and made into a flying McDonald's."));
215 game.damage[DSHUTTL] = -10;
219 prout(_("Galileo, left on the planet surface, is well hidden."));
223 game.quadrant = game.state.kscmdr;
225 game.quadrant = game.state.kcmdr[i];
226 iran(QUADSIZE, &game.sector.x, &game.sector.y);
228 proutn(_(" is pulled to "));
229 proutn(cramlc(quadrant, game.quadrant));
231 prout(cramlc(sector, game.sector));
233 prout(_("(Remainder of rest/repair period cancelled.)"));
234 game.resting = false;
237 if (!damaged(DSHIELD) && game.shield > 0) {
238 doshield(2); /* Shldsup */
241 else prout(_("(Shields not currently useable.)"));
244 /* Adjust finish time to time of tractor beaming */
245 fintim = game.state.date+game.optime;
247 if (game.state.remcom <= 0) unschedule(FTBEAM);
248 else schedule(FTBEAM, game.optime+expran(1.5*game.intime/game.state.remcom));
250 case FSNAP: /* Snapshot of the universe (for time warp) */
251 game.snapsht = game.state;
253 schedule(FSNAP, expran(0.5 * game.intime));
255 case FBATTAK: /* Commander attacks starbase */
256 if (game.state.remcom==0 || game.state.rembase==0) {
265 if (same(game.state.baseq[j], game.state.kcmdr[k]) &&
266 !same(game.state.baseq[j], game.quadrant) &&
267 !same(game.state.baseq[j], game.state.kscmdr)) {
273 if (j>game.state.rembase) {
274 /* no match found -- try later */
275 schedule(FBATTAK, expran(0.3*game.intime));
279 /* commander + starbase combination found -- launch attack */
280 game.battle = game.state.baseq[j];
281 schedule(FCDBAS, 1.0+3.0*Rand());
282 if (game.isatb) /* extra time if SC already attacking */
283 postpone(FCDBAS, scheduled(FSCDBAS)-game.state.date);
284 game.future[FBATTAK].date = game.future[FCDBAS].date + expran(0.3*game.intime);
286 if (!damaged(DRADIO) && game.condit != IHDOCKED)
287 break; /* No warning :-( */
289 if (!ipage) pause_game(1);
292 proutn(_("Lt. Uhura- \"Captain, the starbase in "));
293 prout(cramlc(quadrant, game.battle));
294 prout(_(" reports that it is under attack and that it can"));
295 proutn(_(" hold out only until stardate %d"),
296 (int)scheduled(FCDBAS));
301 case FSCDBAS: /* Supercommander destroys base */
304 if (!game.state.galaxy[game.state.kscmdr.x][game.state.kscmdr.y].starbase)
305 break; /* WAS RETURN! */
307 game.battle = game.state.kscmdr;
309 case FCDBAS: /* Commander succeeds in destroying base */
310 if (evcode==FCDBAS) {
312 /* find the lucky pair */
314 if (same(game.state.kcmdr[i], game.battle))
316 if (i > game.state.remcom || game.state.rembase == 0 ||
317 !game.state.galaxy[game.battle.x][game.battle.y].starbase) {
318 /* No action to take after all */
319 game.battle.x = game.battle.y = 0;
323 /* Code merges here for any commander destroying base */
324 /* Not perfect, but will have to do */
325 /* Handle case where base is in same quadrant as starship */
326 if (same(game.battle, game.quadrant)) {
327 game.state.chart[game.battle.x][game.battle.y].starbase = false;
328 game.quad[game.base.x][game.base.y] = IHDOT;
329 game.base.x=game.base.y=0;
332 prout(_("Spock- \"Captain, I believe the starbase has been destroyed.\""));
334 else if (game.state.rembase != 1 &&
335 (!damaged(DRADIO) || game.condit == IHDOCKED)) {
336 /* Get word via subspace radio */
337 if (!ipage) pause_game(1);
340 prout(_("Lt. Uhura- \"Captain, Starfleet Command reports that"));
341 proutn(_(" the starbase in "));
342 proutn(cramlc(quadrant, game.battle));
343 prout(_(" has been destroyed by"));
345 prout(_("the Klingon Super-Commander"));
346 else prout(_("a Klingon Commander"));
347 game.state.chart[game.battle.x][game.battle.y].starbase = false;
349 /* Remove Starbase from galaxy */
350 game.state.galaxy[game.battle.x][game.battle.y].starbase = false;
352 if (same(game.state.baseq[i], game.battle))
353 game.state.baseq[i] = game.state.baseq[game.state.rembase];
354 game.state.rembase--;
355 if (game.isatb == 2) {
356 /* reinstate a commander's base attack */
361 game.battle.x = game.battle.y = 0;
364 case FSCMOVE: /* Supercommander moves */
365 schedule(FSCMOVE, 0.2777);
366 if (game.ientesc+istract==0 &&
368 (game.iscate != 1 || !game.justin)) scom(&ipage);
370 case FDSPROB: /* Move deep space probe */
371 schedule(FDSPROB, 0.01);
372 game.probex += game.probeinx;
373 game.probey += game.probeiny;
374 i = (int)(game.probex/QUADSIZE +0.05);
375 j = (int)(game.probey/QUADSIZE + 0.05);
376 if (game.probec.x != i || game.probec.y != j) {
379 if (!VALID_QUADRANT(i, j) ||
380 game.state.galaxy[game.probec.x][game.probec.y].supernova) {
381 // Left galaxy or ran into supernova
382 if (!damaged(DRADIO) || game.condit == IHDOCKED) {
383 if (ipage==0) pause_game(1);
386 proutn(_("Lt. Uhura- \"The deep space probe "));
387 if (!VALID_QUADRANT(j, i))
388 proutn(_("has left the galaxy"));
390 proutn(_("is no longer transmitting"));
396 if (!damaged(DRADIO) || game.condit == IHDOCKED) {
397 if (ipage==0) pause_game(1);
400 proutn(_("Lt. Uhura- \"The deep space probe is now in "));
401 proutn(cramlc(quadrant, game.probec));
405 pdest = &game.state.galaxy[game.probec.x][game.probec.y];
406 /* Update star chart if Radio is working or have access to
408 if (!damaged(DRADIO) || game.condit == IHDOCKED) {
409 struct page *chp = &game.state.chart[game.probec.x][game.probec.y];
411 chp->klingons = pdest->klingons;
412 chp->starbase = pdest->starbase;
413 chp->stars = pdest->stars;
414 pdest->charted = true;
416 game.proben--; // One less to travel
417 if (game.proben == 0 && game.isarmed && pdest->stars) {
418 /* lets blow the sucker! */
421 if (game.state.galaxy[game.quadrant.x][game.quadrant.y].supernova)
425 case FDISTR: /* inhabited system issues distress call */
427 /* try a whole bunch of times to find something suitable */
430 /* need a quadrant which is not the current one,
431 which has some stars which are inhabited and
432 not already under attack, which is not
433 supernova'ed, and which has some Klingons in it */
434 iran(GALSIZE, &w.x, &w.y);
435 q = &game.state.galaxy[w.x][w.y];
437 (same(game.quadrant, w) || q->planet == NOPLANET ||
438 q->supernova || q->status!=secure || q->klingons<=0));
440 /* can't seem to find one; ignore this call */
442 prout("=== Couldn't find location for distress event.");
446 /* got one!! Schedule its enslavement */
447 ev = schedule(FENSLV, expran(game.intime));
449 q->status = distressed;
451 /* tell the captain about it if we can */
452 if (!damaged(DRADIO) || game.condit == IHDOCKED)
454 prout("Uhura- Captain, %s in %s reports it is under attack",
455 systemname(q->planet), cramlc(quadrant, w));
456 prout("by a Klingon invasion fleet.");
461 case FENSLV: /* starsystem is enslaved */
462 ev = unschedule(FENSLV);
463 /* see if current distress call still active */
464 q = &game.state.galaxy[ev->quadrant.x][ev->quadrant.y];
465 if (q->klingons <= 0) {
469 q->status = enslaved;
471 /* play stork and schedule the first baby */
472 ev2 = schedule(FREPRO, expran(2.0 * game.intime));
473 ev2->quadrant = ev->quadrant;
475 /* report the disaster if we can */
476 if (!damaged(DRADIO) || game.condit == IHDOCKED)
478 prout("Uhura- We've lost contact with starsystem %s",
479 systemname(q->planet));
480 prout("in %s.\n", cramlc(quadrant, ev->quadrant));
483 case FREPRO: /* Klingon reproduces */
485 * If we ever switch to a real event queue, we'll need to
486 * explicitly retrieve and restore the x and y.
488 ev = schedule(FREPRO, expran(1.0 * game.intime));
489 /* see if current distress call still active */
490 q = &game.state.galaxy[ev->quadrant.x][ev->quadrant.y];
491 if (q->klingons <= 0) {
495 if (game.state.remkl >=MAXKLGAME)
496 break; /* full right now */
497 /* reproduce one Klingon */
499 if (game.klhere >= MAXKLQUAD) {
500 /* this quadrant not ok, pick an adjacent one */
501 for (i = w.x - 1; i <= w.x + 1; i++)
503 for (j = w.y - 1; j <= w.y + 1; j++)
505 if (!VALID_QUADRANT(i, j))
507 q = &game.state.galaxy[w.x][w.y];
508 /* check for this quad ok (not full & no snova) */
509 if (q->klingons >= MAXKLQUAD || q->supernova)
514 break; /* search for eligible quadrant failed */
520 /* deliver the child */
523 if (same(game.quadrant, w))
524 newkling(++game.klhere, &hold);
526 /* recompute time left */
527 game.state.remtime = game.state.remres/(game.state.remkl+4*game.state.remcom);
528 /* report the disaster if we can */
529 if (!damaged(DRADIO) || game.condit == IHDOCKED)
531 if (same(game.quadrant, w)) {
532 prout("Spock- sensors indicate the Klingons have");
533 prout("launched a warship from %s.",systemname(q->planet));
535 prout("Uhura- Starfleet reports increased Klingon activity");
536 if (q->planet != NOPLANET)
537 proutn("near %s", systemname(q->planet));
538 prout("in %s.\n", cramlc(quadrant, w));
551 double temp, delay, origTime;
556 if (key != IHEOL) break;
557 proutn(_("How long? "));
564 origTime = delay = aaitem;
565 if (delay <= 0.0) return;
566 if (delay >= game.state.remtime || game.nenhere != 0) {
567 proutn(_("Are you sure? "));
568 if (ja() == false) return;
571 /* Alternate resting periods (events) with attacks */
575 if (delay <= 0) game.resting = false;
577 prout(_("%d stardates left."), (int)game.state.remtime);
580 temp = game.optime = delay;
583 double rtime = 1.0 + Rand();
584 if (rtime < temp) temp = rtime;
587 if (game.optime < delay) attack(0);
588 if (game.alldone) return;
591 if (game.alldone) return;
593 /* Repair Deathray if long rest at starbase */
594 if (origTime-delay >= 9.99 && game.condit == IHDOCKED)
595 game.damage[DDRAY] = 0.0;
597 // leave if quadrant supernovas
598 (!game.state.galaxy[game.quadrant.x][game.quadrant.y].supernova);
600 game.resting = false;
604 void nova(int ix, int iy)
607 static double course[] =
608 {0.0, 10.5, 12.0, 1.5, 9.0, 0.0, 3.0, 7.5, 6.0, 4.5};
609 int bot, top, top2, hits[QUADSIZE+1][3], kount, icx, icy, mm, nn, j;
610 int iquad, iquad1, i, ll;
611 coord newc, nov, scratch;
613 nov.x = ix; nov.y = iy;
615 /* Wow! We've supernova'ed */
620 /* handle initial nova */
621 game.quad[ix][iy] = IHDOT;
622 crmena(false, IHSTAR, sector, nov);
624 game.state.galaxy[game.quadrant.x][game.quadrant.y].stars--;
627 /* Set up stack to recursively trigger adjacent stars */
628 bot = top = top2 = 1;
634 for (mm = bot; mm <= top; mm++)
635 for (nn = 1; nn <= 3; nn++) /* nn,j represents coordinates around current */
636 for (j = 1; j <= 3; j++) {
637 if (j==2 && nn== 2) continue;
638 scratch.x = hits[mm][1]+nn-2;
639 scratch.y = hits[mm][2]+j-2;
640 if (!VALID_SECTOR(scratch.y, scratch.x)) continue;
641 iquad = game.quad[scratch.x][scratch.y];
643 // case IHDOT: /* Empty space ends reaction
650 case IHSTAR: /* Affect another star */
652 /* This star supernovas */
653 snova(scratch.x,scratch.y);
657 hits[top2][1]=scratch.x;
658 hits[top2][2]=scratch.y;
659 game.state.galaxy[game.quadrant.x][game.quadrant.y].stars -= 1;
661 crmena(true, IHSTAR, sector, scratch);
663 game.quad[scratch.x][scratch.y] = IHDOT;
665 case IHP: /* Destroy planet */
666 game.state.galaxy[game.quadrant.x][game.quadrant.y].planet = NOPLANET;
667 game.state.nplankl++;
668 crmena(true, IHP, sector, scratch);
669 prout(_(" destroyed."));
670 DESTROY(&game.state.plnets[game.iplnet]);
671 game.iplnet = game.plnet.x = game.plnet.y = 0;
672 if (game.landed == 1) {
676 game.quad[scratch.x][scratch.y] = IHDOT;
678 case IHB: /* Destroy base */
679 game.state.galaxy[game.quadrant.x][game.quadrant.y].starbase = false;
681 if (game.state.baseq[i].x==game.quadrant.x && game.state.baseq[i].y==game.quadrant.y)
683 game.state.baseq[i] = game.state.baseq[game.state.rembase];
684 game.state.rembase--;
685 game.base.x = game.base.y = 0;
688 crmena(true, IHB, sector, scratch);
689 prout(_(" destroyed."));
690 game.quad[scratch.x][scratch.y] = IHDOT;
692 case IHE: /* Buffet ship */
694 prout(_("***Starship buffeted by nova."));
696 if (game.shield >= 2000.0) game.shield -= 2000.0;
698 double diff = 2000.0 - game.shield;
702 prout(_("***Shields knocked out."));
703 game.damage[DSHIELD] += 0.005*game.damfac*Rand()*diff;
706 else game.energy -= 2000.0;
707 if (game.energy <= 0) {
711 /* add in course nova contributes to kicking starship*/
712 icx += game.sector.x-hits[mm][1];
713 icy += game.sector.y-hits[mm][2];
716 case IHK: /* kill klingon */
717 deadkl(scratch,iquad, scratch.x, scratch.y);
719 case IHC: /* Damage/destroy big enemies */
722 for_local_enemies(ll)
723 if (game.ks[ll].x==scratch.x && game.ks[ll].y==scratch.y) break;
724 game.kpower[ll] -= 800.0; /* If firepower is lost, die */
725 if (game.kpower[ll] <= 0.0) {
726 deadkl(scratch, iquad, scratch.x, scratch.y);
729 newc.x = scratch.x + scratch.x - hits[mm][1];
730 newc.y = scratch.y + scratch.y - hits[mm][2];
731 crmena(true, iquad, sector, scratch);
732 proutn(_(" damaged"));
733 if (!VALID_SECTOR(newc.x, newc.y)) {
734 /* can't leave quadrant */
738 iquad1 = game.quad[newc.x][newc.y];
739 if (iquad1 == IHBLANK) {
740 proutn(_(", blasted into "));
741 crmena(false, IHBLANK, sector, newc);
743 deadkl(scratch, iquad, newc.x, newc.y);
746 if (iquad1 != IHDOT) {
747 /* can't move into something else */
751 proutn(_(", buffeted to "));
752 proutn(cramlc(sector, newc));
753 game.quad[scratch.x][scratch.y] = IHDOT;
754 game.quad[newc.x][newc.y] = iquad;
755 game.ks[ll].x = newc.x;
756 game.ks[ll].y = newc.y;
757 game.kavgd[ll] = sqrt(square(game.sector.x-newc.x)+square(game.sector.y-newc.y));
758 game.kdist[ll] = game.kavgd[ll];
771 /* Starship affected by nova -- kick it away. */
772 game.dist = kount*0.1;
773 if (icx) icx = (icx < 0 ? -1 : 1);
774 if (icy) icy = (icy < 0 ? -1 : 1);
775 game.direc = course[3*(icx+1)+icy+2];
776 if (game.direc == 0.0) game.dist = 0.0;
777 if (game.dist == 0.0) return;
778 game.optime = 10.0*game.dist/16.0;
780 prout(_("Force of nova displaces starship."));
781 game.iattak=2; /* Eliminates recursion problem */
783 game.optime = 10.0*game.dist/16.0;
788 void snova(int insx, int insy)
789 /* star goes supernova */
791 int comdead, nsx, nsy, num=0, kldead, iscdead;
793 bool incipient = false;
802 /* NOVAMAX being used */
806 /* Scheduled supernova -- select star */
807 /* logic changed here so that we won't favor quadrants in top
809 for_quadrants(nq.x) {
810 for_quadrants(nq.y) {
811 stars += game.state.galaxy[nq.x][nq.y].stars;
814 if (stars == 0) return; /* nothing to supernova exists */
815 num = Rand()*stars + 1;
816 for_quadrants(nq.x) {
817 for_quadrants(nq.y) {
818 num -= game.state.galaxy[nq.x][nq.y].stars;
824 proutn("=== Super nova here?");
826 nq.x = game.quadrant.x;
827 nq.y = game.quadrant.y;
832 if (nq.x != game.quadrant.y || nq.y != game.quadrant.y || game.justin != 0) {
833 /* it isn't here, or we just entered (treat as inroute) */
834 if (!damaged(DRADIO) || game.condit == IHDOCKED) {
836 prout(_("Message from Starfleet Command Stardate %.2f"), game.state.date);
837 prout(_(" Supernova in %s; caution advised."),
838 cramlc(quadrant, nq));
842 /* we are in the quadrant! */
844 num = Rand()* game.state.galaxy[nq.x][nq.y].stars + 1;
847 if (game.quad[nsx][nsy]==IHSTAR) {
863 prouts(_("***RED ALERT! RED ALERT!"));
865 nd.x = nsx; nd.y = nsy;
866 prout(_("***Incipient supernova detected at "), cramlc(sector, nd));
868 if (square(nsx-game.sector.x) + square(nsy-game.sector.y) <= 2.1) {
869 proutn(_("Emergency override attempts t"));
870 prouts("***************");
876 /* destroy any Klingons in supernovaed quadrant */
877 kldead = game.state.galaxy[nq.x][nq.y].klingons;
878 game.state.galaxy[nq.x][nq.y].klingons = 0;
879 comdead = iscdead = 0;
880 if (same(nq, game.state.kscmdr)) {
881 /* did in the Supercommander! */
882 game.state.nscrem = game.state.kscmdr.x = game.state.kscmdr.y = game.isatb = game.iscate = 0;
887 if (game.state.remcom) {
888 int maxloop = game.state.remcom, l;
889 for (l = 1; l <= maxloop; l++) {
890 if (same(game.state.kcmdr[l], nq)) {
891 game.state.kcmdr[l] = game.state.kcmdr[game.state.remcom];
892 game.state.kcmdr[game.state.remcom].x = game.state.kcmdr[game.state.remcom].y = 0;
896 if (game.state.remcom==0) unschedule(FTBEAM);
901 game.state.remkl -= kldead;
902 /* destroy Romulans and planets in supernovaed quadrant */
903 nrmdead = game.state.galaxy[nq.x][nq.y].romulans;
904 game.state.galaxy[nq.x][nq.y].romulans = 0;
905 game.state.nromrem -= nrmdead;
906 npdead = num - nrmdead*10;
909 for (loop = 0; loop < game.inplan; loop++)
910 if (same(game.state.plnets[loop].w, nq)) {
911 DESTROY(&game.state.plnets[loop]);
914 /* Destroy any base in supernovaed quadrant */
915 if (game.state.rembase) {
916 int maxloop = game.state.rembase, loop;
917 for (loop = 1; loop <= maxloop; loop++)
918 if (same(game.state.baseq[loop], nq)) {
919 game.state.baseq[loop] = game.state.baseq[game.state.rembase];
920 game.state.baseq[game.state.rembase].x = game.state.baseq[game.state.rembase].y = 0;
921 game.state.rembase--;
925 /* If starship caused supernova, tally up destruction */
927 game.state.starkl += game.state.galaxy[nq.x][nq.y].stars;
928 game.state.basekl += game.state.galaxy[nq.x][nq.y].starbase;
929 game.state.nplankl += npdead;
931 /* mark supernova in galaxy and in star chart */
932 if (same(game.quadrant, nq) || !damaged(DRADIO) || game.condit == IHDOCKED)
933 game.state.galaxy[nq.x][nq.y].supernova = true;
934 /* If supernova destroys last Klingons give special message */
935 if (KLINGREM==0 && !same(nq, game.quadrant)) {
937 if (insx == 0) prout(_("Lucky you!"));
938 proutn(_("A supernova in %s has just destroyed the last Klingons."),
939 cramlc(quadrant, nq));
943 /* if some Klingons remain, continue or die in supernova */
944 if (game.alldone) finish(FSNOVAED);