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);
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 ||
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) { /* 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 && game.isatb != 1 &&
367 (game.iscate != 1 || !game.justin))
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! */
419 snova(true, &game.probec);
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;
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;
614 /* Wow! We've supernova'ed */
619 /* handle initial nova */
620 game.quad[nov.x][nov.y] = IHDOT;
621 crmena(false, IHSTAR, sector, nov);
623 game.state.galaxy[game.quadrant.x][game.quadrant.y].stars--;
626 /* Set up stack to recursively trigger adjacent stars */
627 bot = top = top2 = 1;
633 for (mm = bot; mm <= top; mm++)
634 for (nn = 1; nn <= 3; nn++) /* nn,j represents coordinates around current */
635 for (j = 1; j <= 3; j++) {
636 if (j==2 && nn== 2) continue;
637 scratch.x = hits[mm][1]+nn-2;
638 scratch.y = hits[mm][2]+j-2;
639 if (!VALID_SECTOR(scratch.y, scratch.x)) continue;
640 iquad = game.quad[scratch.x][scratch.y];
642 // case IHDOT: /* Empty space ends reaction
649 case IHSTAR: /* Affect another star */
651 /* This star supernovas */
652 snova(false, &scratch);
656 hits[top2][1]=scratch.x;
657 hits[top2][2]=scratch.y;
658 game.state.galaxy[game.quadrant.x][game.quadrant.y].stars -= 1;
660 crmena(true, IHSTAR, sector, scratch);
662 game.quad[scratch.x][scratch.y] = IHDOT;
664 case IHP: /* Destroy planet */
665 game.state.galaxy[game.quadrant.x][game.quadrant.y].planet = NOPLANET;
666 game.state.nplankl++;
667 crmena(true, IHP, sector, scratch);
668 prout(_(" destroyed."));
669 DESTROY(&game.state.plnets[game.iplnet]);
670 game.iplnet = game.plnet.x = game.plnet.y = 0;
671 if (game.landed == 1) {
675 game.quad[scratch.x][scratch.y] = IHDOT;
677 case IHB: /* Destroy base */
678 game.state.galaxy[game.quadrant.x][game.quadrant.y].starbase = false;
680 if (same(game.state.baseq[i], game.quadrant))
682 game.state.baseq[i] = game.state.baseq[game.state.rembase];
683 game.state.rembase--;
684 game.base.x = game.base.y = 0;
687 crmena(true, IHB, sector, scratch);
688 prout(_(" destroyed."));
689 game.quad[scratch.x][scratch.y] = IHDOT;
691 case IHE: /* Buffet ship */
693 prout(_("***Starship buffeted by nova."));
695 if (game.shield >= 2000.0) game.shield -= 2000.0;
697 double diff = 2000.0 - game.shield;
701 prout(_("***Shields knocked out."));
702 game.damage[DSHIELD] += 0.005*game.damfac*Rand()*diff;
705 else game.energy -= 2000.0;
706 if (game.energy <= 0) {
710 /* add in course nova contributes to kicking starship*/
711 icx += game.sector.x-hits[mm][1];
712 icy += game.sector.y-hits[mm][2];
715 case IHK: /* kill klingon */
716 deadkl(scratch,iquad, scratch.x, scratch.y);
718 case IHC: /* Damage/destroy big enemies */
721 for_local_enemies(ll)
722 if (same(game.ks[ll], scratch)) break;
723 game.kpower[ll] -= 800.0; /* If firepower is lost, die */
724 if (game.kpower[ll] <= 0.0) {
725 deadkl(scratch, iquad, scratch.x, scratch.y);
728 newc.x = scratch.x + scratch.x - hits[mm][1];
729 newc.y = scratch.y + scratch.y - hits[mm][2];
730 crmena(true, iquad, sector, scratch);
731 proutn(_(" damaged"));
732 if (!VALID_SECTOR(newc.x, newc.y)) {
733 /* can't leave quadrant */
737 iquad1 = game.quad[newc.x][newc.y];
738 if (iquad1 == IHBLANK) {
739 proutn(_(", blasted into "));
740 crmena(false, IHBLANK, sector, newc);
742 deadkl(scratch, iquad, newc.x, newc.y);
745 if (iquad1 != IHDOT) {
746 /* can't move into something else */
750 proutn(_(", buffeted to "));
751 proutn(cramlc(sector, newc));
752 game.quad[scratch.x][scratch.y] = IHDOT;
753 game.quad[newc.x][newc.y] = iquad;
755 game.kavgd[ll] = sqrt(square(game.sector.x-newc.x)+square(game.sector.y-newc.y));
756 game.kdist[ll] = game.kavgd[ll];
769 /* Starship affected by nova -- kick it away. */
770 game.dist = kount*0.1;
771 if (icx) icx = (icx < 0 ? -1 : 1);
772 if (icy) icy = (icy < 0 ? -1 : 1);
773 game.direc = course[3*(icx+1)+icy+2];
774 if (game.direc == 0.0) game.dist = 0.0;
775 if (game.dist == 0.0) return;
776 game.optime = 10.0*game.dist/16.0;
778 prout(_("Force of nova displaces starship."));
779 game.iattak=2; /* Eliminates recursion problem */
781 game.optime = 10.0*game.dist/16.0;
786 void snova(bool induced, coord *w)
787 /* star goes supernova */
789 int num = 0, nrmdead, npdead, kldead;
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?");
820 if (!same(nq, game.quadrant) || game.justin) {
821 /* it isn't here, or we just entered (treat as enroute) */
822 if (!damaged(DRADIO) || game.condit == IHDOCKED) {
824 prout(_("Message from Starfleet Command Stardate %.2f"), game.state.date);
825 prout(_(" Supernova in %s; caution advised."),
826 cramlc(quadrant, nq));
831 /* we are in the quadrant! */
832 num = Rand()* game.state.galaxy[nq.x][nq.y].stars + 1;
835 if (game.quad[ns.x][ns.y]==IHSTAR) {
844 prouts(_("***RED ALERT! RED ALERT!"));
846 prout(_("***Incipient supernova detected at "), cramlc(sector, ns));
847 if (square(ns.x-game.sector.x) + square(ns.y-game.sector.y) <= 2.1) {
848 proutn(_("Emergency override attempts t"));
849 prouts("***************");
856 /* destroy any Klingons in supernovaed quadrant */
857 kldead = game.state.galaxy[nq.x][nq.y].klingons;
858 game.state.galaxy[nq.x][nq.y].klingons = 0;
859 if (same(nq, game.state.kscmdr)) {
860 /* did in the Supercommander! */
861 game.state.nscrem = game.state.kscmdr.x = game.state.kscmdr.y = game.isatb = game.iscate = 0;
865 if (game.state.remcom) {
866 int maxloop = game.state.remcom, l;
867 for (l = 1; l <= maxloop; l++) {
868 if (same(game.state.kcmdr[l], nq)) {
869 game.state.kcmdr[l] = game.state.kcmdr[game.state.remcom];
870 game.state.kcmdr[game.state.remcom].x = game.state.kcmdr[game.state.remcom].y = 0;
873 if (game.state.remcom==0) unschedule(FTBEAM);
878 game.state.remkl -= kldead;
879 /* destroy Romulans and planets in supernovaed quadrant */
880 nrmdead = game.state.galaxy[nq.x][nq.y].romulans;
881 game.state.galaxy[nq.x][nq.y].romulans = 0;
882 game.state.nromrem -= nrmdead;
883 npdead = num - nrmdead*10;
886 for (loop = 0; loop < game.inplan; loop++)
887 if (same(game.state.plnets[loop].w, nq)) {
888 DESTROY(&game.state.plnets[loop]);
891 /* Destroy any base in supernovaed quadrant */
892 if (game.state.rembase) {
893 int maxloop = game.state.rembase, loop;
894 for (loop = 1; loop <= maxloop; loop++)
895 if (same(game.state.baseq[loop], nq)) {
896 game.state.baseq[loop] = game.state.baseq[game.state.rembase];
897 game.state.baseq[game.state.rembase].x = game.state.baseq[game.state.rembase].y = 0;
898 game.state.rembase--;
902 /* If starship caused supernova, tally up destruction */
904 game.state.starkl += game.state.galaxy[nq.x][nq.y].stars;
905 game.state.basekl += game.state.galaxy[nq.x][nq.y].starbase;
906 game.state.nplankl += npdead;
908 /* mark supernova in galaxy and in star chart */
909 if (same(game.quadrant, nq) || !damaged(DRADIO) || game.condit == IHDOCKED)
910 game.state.galaxy[nq.x][nq.y].supernova = true;
911 /* If supernova destroys last Klingons give special message */
912 if (KLINGREM==0 && !same(nq, game.quadrant)) {
914 if (!induced) prout(_("Lucky you!"));
915 proutn(_("A supernova in %s has just destroyed the last Klingons."),
916 cramlc(quadrant, nq));
920 /* if some Klingons remain, continue or die in supernova */
921 if (game.alldone) finish(FSNOVAED);