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 = damaged(DRADIO);
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 /* Any crew left alive? */
116 if (game.state.crew <=0) {
120 /* Is life support adequate? */
121 if (damaged(DLIFSUP) && game.condit != IHDOCKED) {
122 if (game.lsupres < xtime && game.damage[DLIFSUP] > game.lsupres) {
126 game.lsupres -= xtime;
127 if (game.damage[DLIFSUP] <= xtime) game.lsupres = game.inlsr;
131 if (game.condit == IHDOCKED) repair /= game.docfac;
132 /* Don't fix Deathray here */
133 for (l=0; l<NDEVICES; l++)
134 if (game.damage[l] > 0.0 && l != DDRAY)
135 game.damage[l] -= (game.damage[l]-repair > 0.0 ? repair : game.damage[l]);
136 /* If radio repaired, update star chart and attack reports */
137 if (radio_was_broken && !damaged(DRADIO)) {
138 prout(_("Lt. Uhura- \"Captain, the sub-space radio is working and"));
139 prout(_(" surveillance reports are coming in."));
141 if (game.iseenit==0) {
146 prout(_(" The star chart is now up to date.\""));
149 /* Cause extraneous event EVCODE to occur */
150 game.optime -= xtime;
152 case FSNOVA: /* Supernova */
153 if (!ipage) pause_game(1);
156 schedule(FSNOVA, expran(0.5*game.intime));
157 if (game.state.galaxy[game.quadrant.x][game.quadrant.y].supernova) return;
159 case FSPY: /* Check with spy to see if S.C. should tractor beam */
160 if (game.state.nscrem == 0 ||
161 ictbeam+istract > 0 ||
162 game.condit==IHDOCKED || game.isatb==1 || game.iscate==1) return;
164 (game.energy < 2000 && game.torps < 4 && game.shield < 1250) ||
165 (damaged(DPHASER) && (damaged(DPHOTON) || game.torps < 4)) ||
167 (game.energy < 2500 || damaged(DPHASER)) &&
168 (game.torps < 5 || damaged(DPHOTON)))) {
169 /* Tractor-beam her! */
171 yank = square(game.state.kscmdr.x-game.quadrant.x) + square(game.state.kscmdr.y-game.quadrant.y);
172 /********* fall through to FTBEAM code ***********/
175 case FTBEAM: /* Tractor beam */
176 if (evcode==FTBEAM) {
177 if (game.state.remcom == 0) {
181 i = Rand()*game.state.remcom+1.0;
182 yank = square(game.state.kcmdr[i].x-game.quadrant.x) + square(game.state.kcmdr[i].y-game.quadrant.y);
183 if (istract || game.condit == IHDOCKED || yank == 0) {
184 /* Drats! Have to reschedule */
186 game.optime + expran(1.5*game.intime/game.state.remcom));
190 /* tractor beaming cases merge here */
192 if (!ipage) pause_game(1);
194 game.optime = (10.0/(7.5*7.5))*yank; /* 7.5 is yank rate (warp 7.5) */
199 prout(_(" caught in long range tractor beam--"));
200 /* If Kirk & Co. screwing around on planet, handle */
201 atover(true); /* atover(true) is Grab */
202 if (game.alldone) return;
203 if (game.icraft == 1) { /* Caught in Galileo? */
207 /* Check to see if shuttle is aboard */
208 if (game.iscraft==0) {
211 prout(_("Galileo, left on the planet surface, is captured"));
212 prout(_("by aliens and made into a flying McDonald's."));
213 game.damage[DSHUTTL] = -10;
217 prout(_("Galileo, left on the planet surface, is well hidden."));
221 game.quadrant = game.state.kscmdr;
223 game.quadrant = game.state.kcmdr[i];
224 iran(QUADSIZE, &game.sector.x, &game.sector.y);
226 proutn(_(" is pulled to "));
227 proutn(cramlc(quadrant, game.quadrant));
229 prout(cramlc(sector, game.sector));
231 prout(_("(Remainder of rest/repair period cancelled.)"));
232 game.resting = false;
235 if (!damaged(DSHIELD) && game.shield > 0) {
236 doshield(2); /* Shldsup */
239 else prout(_("(Shields not currently useable.)"));
242 /* Adjust finish time to time of tractor beaming */
243 fintim = game.state.date+game.optime;
245 if (game.state.remcom <= 0) unschedule(FTBEAM);
246 else schedule(FTBEAM, game.optime+expran(1.5*game.intime/game.state.remcom));
248 case FSNAP: /* Snapshot of the universe (for time warp) */
249 game.snapsht = game.state;
251 schedule(FSNAP, expran(0.5 * game.intime));
253 case FBATTAK: /* Commander attacks starbase */
254 if (game.state.remcom==0 || game.state.rembase==0) {
263 if (same(game.state.baseq[j], game.state.kcmdr[k]) &&
264 !same(game.state.baseq[j], game.quadrant) &&
265 !same(game.state.baseq[j], game.state.kscmdr)) {
271 if (j>game.state.rembase) {
272 /* no match found -- try later */
273 schedule(FBATTAK, expran(0.3*game.intime));
277 /* commander + starbase combination found -- launch attack */
278 game.battle = game.state.baseq[j];
279 schedule(FCDBAS, 1.0+3.0*Rand());
280 if (game.isatb) /* extra time if SC already attacking */
281 postpone(FCDBAS, scheduled(FSCDBAS)-game.state.date);
282 game.future[FBATTAK].date = game.future[FCDBAS].date + expran(0.3*game.intime);
284 if (!damaged(DRADIO) && game.condit != IHDOCKED)
285 break; /* No warning :-( */
287 if (!ipage) pause_game(1);
290 proutn(_("Lt. Uhura- \"Captain, the starbase in "));
291 prout(cramlc(quadrant, game.battle));
292 prout(_(" reports that it is under attack and that it can"));
293 proutn(_(" hold out only until stardate %d"),
294 (int)scheduled(FCDBAS));
299 case FSCDBAS: /* Supercommander destroys base */
302 if (!game.state.galaxy[game.state.kscmdr.x][game.state.kscmdr.y].starbase)
303 break; /* WAS RETURN! */
305 game.battle = game.state.kscmdr;
307 case FCDBAS: /* Commander succeeds in destroying base */
308 if (evcode==FCDBAS) {
310 /* find the lucky pair */
312 if (same(game.state.kcmdr[i], game.battle))
314 if (i > game.state.remcom || game.state.rembase == 0 ||
315 !game.state.galaxy[game.battle.x][game.battle.y].starbase) {
316 /* No action to take after all */
317 game.battle.x = game.battle.y = 0;
321 /* Code merges here for any commander destroying base */
322 /* Not perfect, but will have to do */
323 /* Handle case where base is in same quadrant as starship */
324 if (same(game.battle, game.quadrant)) {
325 game.state.chart[game.battle.x][game.battle.y].starbase = false;
326 game.quad[game.base.x][game.base.y] = IHDOT;
327 game.base.x=game.base.y=0;
330 prout(_("Spock- \"Captain, I believe the starbase has been destroyed.\""));
332 else if (game.state.rembase != 1 &&
333 (!damaged(DRADIO) || game.condit == IHDOCKED)) {
334 /* Get word via subspace radio */
335 if (!ipage) pause_game(1);
338 prout(_("Lt. Uhura- \"Captain, Starfleet Command reports that"));
339 proutn(_(" the starbase in "));
340 proutn(cramlc(quadrant, game.battle));
341 prout(_(" has been destroyed by"));
343 prout(_("the Klingon Super-Commander"));
344 else prout(_("a Klingon Commander"));
345 game.state.chart[game.battle.x][game.battle.y].starbase = false;
347 /* Remove Starbase from galaxy */
348 game.state.galaxy[game.battle.x][game.battle.y].starbase = false;
350 if (same(game.state.baseq[i], game.battle))
351 game.state.baseq[i] = game.state.baseq[game.state.rembase];
352 game.state.rembase--;
353 if (game.isatb == 2) {
354 /* reinstate a commander's base attack */
359 game.battle.x = game.battle.y = 0;
362 case FSCMOVE: /* Supercommander moves */
363 schedule(FSCMOVE, 0.2777);
364 if (game.ientesc+istract==0 &&
366 (game.iscate != 1 || !game.justin)) scom(&ipage);
368 case FDSPROB: /* Move deep space probe */
369 schedule(FDSPROB, 0.01);
370 game.probex += game.probeinx;
371 game.probey += game.probeiny;
372 i = (int)(game.probex/QUADSIZE +0.05);
373 j = (int)(game.probey/QUADSIZE + 0.05);
374 if (game.probec.x != i || game.probec.y != j) {
377 if (!VALID_QUADRANT(i, j) ||
378 game.state.galaxy[game.probec.x][game.probec.y].supernova) {
379 // Left galaxy or ran into supernova
380 if (!damaged(DRADIO) || game.condit == IHDOCKED) {
381 if (ipage==0) pause_game(1);
384 proutn(_("Lt. Uhura- \"The deep space probe "));
385 if (!VALID_QUADRANT(j, i))
386 proutn(_("has left the galaxy"));
388 proutn(_("is no longer transmitting"));
394 if (!damaged(DRADIO) || game.condit == IHDOCKED) {
395 if (ipage==0) pause_game(1);
398 proutn(_("Lt. Uhura- \"The deep space probe is now in "));
399 proutn(cramlc(quadrant, game.probec));
403 pdest = &game.state.galaxy[game.probec.x][game.probec.y];
404 /* Update star chart if Radio is working or have access to
406 if (!damaged(DRADIO) || game.condit == IHDOCKED) {
407 struct page *chp = &game.state.chart[game.probec.x][game.probec.y];
409 chp->klingons = pdest->klingons;
410 chp->starbase = pdest->starbase;
411 chp->stars = pdest->stars;
412 pdest->charted = true;
414 game.proben--; // One less to travel
415 if (game.proben == 0 && game.isarmed && pdest->stars) {
416 /* lets blow the sucker! */
419 if (game.state.galaxy[game.quadrant.x][game.quadrant.y].supernova)
423 case FDISTR: /* inhabited system issues distress call */
425 /* try a whole bunch of times to find something suitable */
428 /* need a quadrant which is not the current one,
429 which has some stars which are inhabited and
430 not already under attack, which is not
431 supernova'ed, and which has some Klingons in it */
432 iran(GALSIZE, &w.x, &w.y);
433 q = &game.state.galaxy[w.x][w.y];
435 (same(game.quadrant, w) || q->planet == NOPLANET ||
436 q->supernova || q->status!=secure || q->klingons<=0));
438 /* can't seem to find one; ignore this call */
440 prout("=== Couldn't find location for distress event.");
444 /* got one!! Schedule its enslavement */
445 ev = schedule(FENSLV, expran(game.intime));
447 q->status = distressed;
449 /* tell the captain about it if we can */
450 if (!damaged(DRADIO) || game.condit == IHDOCKED)
452 prout("Uhura- Captain, %s in %s reports it is under attack",
453 systemname(q->planet), cramlc(quadrant, w));
454 prout("by a Klingon invasion fleet.");
459 case FENSLV: /* starsystem is enslaved */
460 ev = unschedule(FENSLV);
461 /* see if current distress call still active */
462 q = &game.state.galaxy[ev->quadrant.x][ev->quadrant.y];
463 if (q->klingons <= 0) {
467 q->status = enslaved;
469 /* play stork and schedule the first baby */
470 ev2 = schedule(FREPRO, expran(2.0 * game.intime));
471 ev2->quadrant = ev->quadrant;
473 /* report the disaster if we can */
474 if (!damaged(DRADIO) || game.condit == IHDOCKED)
476 prout("Uhura- We've lost contact with starsystem %s",
477 systemname(q->planet));
478 prout("in %s.\n", cramlc(quadrant, ev->quadrant));
481 case FREPRO: /* Klingon reproduces */
483 * If we ever switch to a real event queue, we'll need to
484 * explicitly retrieve and restore the x and y.
486 ev = schedule(FREPRO, expran(1.0 * game.intime));
487 /* see if current distress call still active */
488 q = &game.state.galaxy[ev->quadrant.x][ev->quadrant.y];
489 if (q->klingons <= 0) {
493 if (game.state.remkl >=MAXKLGAME)
494 break; /* full right now */
495 /* reproduce one Klingon */
497 if (game.klhere >= MAXKLQUAD) {
498 /* this quadrant not ok, pick an adjacent one */
499 for (i = w.x - 1; i <= w.x + 1; i++)
501 for (j = w.y - 1; j <= w.y + 1; j++)
503 if (!VALID_QUADRANT(i, j))
505 q = &game.state.galaxy[w.x][w.y];
506 /* check for this quad ok (not full & no snova) */
507 if (q->klingons >= MAXKLQUAD || q->supernova)
512 break; /* search for eligible quadrant failed */
518 /* deliver the child */
521 if (same(game.quadrant, w))
522 newkling(++game.klhere, &hold);
524 /* recompute time left */
525 game.state.remtime = game.state.remres/(game.state.remkl+4*game.state.remcom);
526 /* report the disaster if we can */
527 if (!damaged(DRADIO) || game.condit == IHDOCKED)
529 if (same(game.quadrant, w)) {
530 prout("Spock- sensors indicate the Klingons have");
531 prout("launched a warship from %s.",systemname(q->planet));
533 prout("Uhura- Starfleet reports increased Klingon activity");
534 if (q->planet != NOPLANET)
535 proutn("near %s", systemname(q->planet));
536 prout("in %s.\n", cramlc(quadrant, w));
548 double temp, delay, origTime;
553 if (key != IHEOL) break;
554 proutn(_("How long? "));
561 origTime = delay = aaitem;
562 if (delay <= 0.0) return;
563 if (delay >= game.state.remtime || game.nenhere != 0) {
564 proutn(_("Are you sure? "));
565 if (ja() == false) return;
568 /* Alternate resting periods (events) with attacks */
572 if (delay <= 0) game.resting = false;
574 prout(_("%d stardates left."), (int)game.state.remtime);
577 temp = game.optime = delay;
580 double rtime = 1.0 + Rand();
581 if (rtime < temp) temp = rtime;
584 if (game.optime < delay) attack(0);
585 if (game.alldone) return;
588 if (game.alldone) return;
590 /* Repair Deathray if long rest at starbase */
591 if (origTime-delay >= 9.99 && game.condit == IHDOCKED)
592 game.damage[DDRAY] = 0.0;
594 // leave if quadrant supernovas
595 (!game.state.galaxy[game.quadrant.x][game.quadrant.y].supernova);
597 game.resting = false;
601 void nova(int ix, int iy)
603 static double course[] =
604 {0.0, 10.5, 12.0, 1.5, 9.0, 0.0, 3.0, 7.5, 6.0, 4.5};
605 int bot, top, top2, hits[QUADSIZE+1][3], kount, icx, icy, mm, nn, j;
606 int iquad, iquad1, i, ll;
607 coord newc, nov, scratch;
609 nov.x = ix; nov.y = iy;
611 /* Wow! We've supernova'ed */
616 /* handle initial nova */
617 game.quad[ix][iy] = IHDOT;
618 crmena(false, IHSTAR, sector, nov);
620 game.state.galaxy[game.quadrant.x][game.quadrant.y].stars--;
623 /* Set up stack to recursively trigger adjacent stars */
624 bot = top = top2 = 1;
630 for (mm = bot; mm <= top; mm++)
631 for (nn = 1; nn <= 3; nn++) /* nn,j represents coordinates around current */
632 for (j = 1; j <= 3; j++) {
633 if (j==2 && nn== 2) continue;
634 scratch.x = hits[mm][1]+nn-2;
635 scratch.y = hits[mm][2]+j-2;
636 if (!VALID_SECTOR(scratch.y, scratch.x)) continue;
637 iquad = game.quad[scratch.x][scratch.y];
639 // case IHDOT: /* Empty space ends reaction
646 case IHSTAR: /* Affect another star */
648 /* This star supernovas */
649 snova(scratch.x,scratch.y);
653 hits[top2][1]=scratch.x;
654 hits[top2][2]=scratch.y;
655 game.state.galaxy[game.quadrant.x][game.quadrant.y].stars -= 1;
657 crmena(true, IHSTAR, sector, scratch);
659 game.quad[scratch.x][scratch.y] = IHDOT;
661 case IHP: /* Destroy planet */
662 game.state.galaxy[game.quadrant.x][game.quadrant.y].planet = NOPLANET;
663 game.state.nplankl++;
664 crmena(true, IHP, sector, scratch);
665 prout(_(" destroyed."));
666 DESTROY(&game.state.plnets[game.iplnet]);
667 game.iplnet = game.plnet.x = game.plnet.y = 0;
668 if (game.landed == 1) {
672 game.quad[scratch.x][scratch.y] = IHDOT;
674 case IHB: /* Destroy base */
675 game.state.galaxy[game.quadrant.x][game.quadrant.y].starbase = false;
677 if (game.state.baseq[i].x==game.quadrant.x && game.state.baseq[i].y==game.quadrant.y)
679 game.state.baseq[i] = game.state.baseq[game.state.rembase];
680 game.state.rembase--;
681 game.base.x = game.base.y = 0;
684 crmena(true, IHB, sector, scratch);
685 prout(_(" destroyed."));
686 game.quad[scratch.x][scratch.y] = IHDOT;
688 case IHE: /* Buffet ship */
690 prout(_("***Starship buffeted by nova."));
692 if (game.shield >= 2000.0) game.shield -= 2000.0;
694 double diff = 2000.0 - game.shield;
698 prout(_("***Shields knocked out."));
699 game.damage[DSHIELD] += 0.005*game.damfac*Rand()*diff;
702 else game.energy -= 2000.0;
703 if (game.energy <= 0) {
707 /* add in course nova contributes to kicking starship*/
708 icx += game.sector.x-hits[mm][1];
709 icy += game.sector.y-hits[mm][2];
712 case IHK: /* kill klingon */
713 deadkl(scratch,iquad, scratch.x, scratch.y);
715 case IHC: /* Damage/destroy big enemies */
718 for_local_enemies(ll)
719 if (game.ks[ll].x==scratch.x && game.ks[ll].y==scratch.y) break;
720 game.kpower[ll] -= 800.0; /* If firepower is lost, die */
721 if (game.kpower[ll] <= 0.0) {
722 deadkl(scratch, iquad, scratch.x, scratch.y);
725 newc.x = scratch.x + scratch.x - hits[mm][1];
726 newc.y = scratch.y + scratch.y - hits[mm][2];
727 crmena(true, iquad, sector, scratch);
728 proutn(_(" damaged"));
729 if (!VALID_SECTOR(newc.x, newc.y)) {
730 /* can't leave quadrant */
734 iquad1 = game.quad[newc.x][newc.y];
735 if (iquad1 == IHBLANK) {
736 proutn(_(", blasted into "));
737 crmena(false, IHBLANK, sector, newc);
739 deadkl(scratch, iquad, newc.x, newc.y);
742 if (iquad1 != IHDOT) {
743 /* can't move into something else */
747 proutn(_(", buffeted to "));
748 proutn(cramlc(sector, newc));
749 game.quad[scratch.x][scratch.y] = IHDOT;
750 game.quad[newc.x][newc.y] = iquad;
751 game.ks[ll].x = newc.x;
752 game.ks[ll].y = newc.y;
753 game.kavgd[ll] = sqrt(square(game.sector.x-newc.x)+square(game.sector.y-newc.y));
754 game.kdist[ll] = game.kavgd[ll];
767 /* Starship affected by nova -- kick it away. */
768 game.dist = kount*0.1;
769 if (icx) icx = (icx < 0 ? -1 : 1);
770 if (icy) icy = (icy < 0 ? -1 : 1);
771 game.direc = course[3*(icx+1)+icy+2];
772 if (game.direc == 0.0) game.dist = 0.0;
773 if (game.dist == 0.0) return;
774 game.optime = 10.0*game.dist/16.0;
776 prout(_("Force of nova displaces starship."));
777 game.iattak=2; /* Eliminates recursion problem */
779 game.optime = 10.0*game.dist/16.0;
784 void snova(int insx, int insy)
786 int comdead, nsx, nsy, num=0, kldead, iscdead;
797 /* NOVAMAX being used */
801 /* Scheduled supernova -- select star */
802 /* logic changed here so that we won't favor quadrants in top
804 for_quadrants(nq.x) {
805 for_quadrants(nq.y) {
806 stars += game.state.galaxy[nq.x][nq.y].stars;
809 if (stars == 0) return; /* nothing to supernova exists */
810 num = Rand()*stars + 1;
811 for_quadrants(nq.x) {
812 for_quadrants(nq.y) {
813 num -= game.state.galaxy[nq.x][nq.y].stars;
819 proutn("=== Super nova here?");
821 nq.x = game.quadrant.x;
822 nq.y = game.quadrant.y;
827 if (nq.x != game.quadrant.y || nq.y != game.quadrant.y || game.justin != 0) {
828 /* it isn't here, or we just entered (treat as inroute) */
829 if (!damaged(DRADIO) || game.condit == IHDOCKED) {
831 prout(_("Message from Starfleet Command Stardate %.2f"), game.state.date);
832 prout(_(" Supernova in %s; caution advised."),
833 cramlc(quadrant, nq));
837 /* we are in the quadrant! */
839 num = Rand()* game.state.galaxy[nq.x][nq.y].stars + 1;
842 if (game.quad[nsx][nsy]==IHSTAR) {
858 prouts(_("***RED ALERT! RED ALERT!"));
860 nd.x = nsx; nd.y = nsy;
861 prout(_("***Incipient supernova detected at "), cramlc(sector, nd));
863 if (square(nsx-game.sector.x) + square(nsy-game.sector.y) <= 2.1) {
864 proutn(_("Emergency override attempts t"));
865 prouts("***************");
871 /* destroy any Klingons in supernovaed quadrant */
872 kldead = game.state.galaxy[nq.x][nq.y].klingons;
873 game.state.galaxy[nq.x][nq.y].klingons = 0;
874 comdead = iscdead = 0;
875 if (same(nq, game.state.kscmdr)) {
876 /* did in the Supercommander! */
877 game.state.nscrem = game.state.kscmdr.x = game.state.kscmdr.y = game.isatb = game.iscate = 0;
882 if (game.state.remcom) {
883 int maxloop = game.state.remcom, l;
884 for (l = 1; l <= maxloop; l++) {
885 if (same(game.state.kcmdr[l], nq)) {
886 game.state.kcmdr[l] = game.state.kcmdr[game.state.remcom];
887 game.state.kcmdr[game.state.remcom].x = game.state.kcmdr[game.state.remcom].y = 0;
891 if (game.state.remcom==0) unschedule(FTBEAM);
896 game.state.remkl -= kldead;
897 /* destroy Romulans and planets in supernovaed quadrant */
898 nrmdead = game.state.galaxy[nq.x][nq.y].romulans;
899 game.state.galaxy[nq.x][nq.y].romulans = 0;
900 game.state.nromrem -= nrmdead;
901 npdead = num - nrmdead*10;
904 for (l = 0; l < game.inplan; l++)
905 if (same(game.state.plnets[l].w, nq)) {
906 DESTROY(&game.state.plnets[l]);
909 /* Destroy any base in supernovaed quadrant */
910 if (game.state.rembase) {
911 int maxloop = game.state.rembase, l;
912 for (l = 1; l <= maxloop; l++)
913 if (same(game.state.baseq[l], nq)) {
914 game.state.baseq[l] = game.state.baseq[game.state.rembase];
915 game.state.baseq[game.state.rembase].x = game.state.baseq[game.state.rembase].y = 0;
916 game.state.rembase--;
920 /* If starship caused supernova, tally up destruction */
922 game.state.starkl += game.state.galaxy[nq.x][nq.y].stars;
923 game.state.basekl += game.state.galaxy[nq.x][nq.y].starbase;
924 game.state.nplankl += npdead;
926 /* mark supernova in galaxy and in star chart */
927 if (same(game.quadrant, nq) || !damaged(DRADIO) || game.condit == IHDOCKED)
928 game.state.galaxy[nq.x][nq.y].supernova = true;
929 /* If supernova destroys last Klingons give special message */
930 if (KLINGREM==0 && (nq.x != game.quadrant.x || nq.y != game.quadrant.y)) {
932 if (insx == 0) prout(_("Lucky you!"));
933 proutn(_("A supernova in %s has just destroyed the last Klingons."),
934 cramlc(quadrant, nq));
938 /* if some Klingons remain, continue or die in supernova */
939 if (game.alldone) finish(FSNOVAED);