6 int ictbeam=0, ipage=0, istract=0, line, i=0, j, k, l, ixhold=0, iyhold=0;
7 double fintim = game.state.date + Time, datemin, xtime, repair, yank=0;
11 if (idebug) prout("EVENTS");
14 radio_was_broken = (game.damage[DRADIO] != 0.0);
17 /* Select earliest extraneous event, line==0 if no events */
21 for (l = 1; l < NEVENTS; l++)
22 if (game.future[l] < datemin) {
24 datemin = game.future[l];
26 xtime = datemin-game.state.date;
27 game.state.date = datemin;
28 /* Decrement Federation resources and recompute remaining time */
29 game.state.remres -= (game.state.remkl+4*game.state.remcom)*xtime;
30 game.state.remtime = game.state.remres/(game.state.remkl+4*game.state.remcom);
31 if (game.state.remtime <=0) {
35 /* Is life support adequate? */
36 if (game.damage[DLIFSUP] && condit != IHDOCKED) {
37 if (lsupres < xtime && game.damage[DLIFSUP] > lsupres) {
42 if (game.damage[DLIFSUP] <= xtime) lsupres = inlsr;
46 if (condit == IHDOCKED) repair /= docfac;
47 /* Don't fix Deathray here */
48 for (l=0; l<NDEVICES; l++)
49 if (game.damage[l] > 0.0 && l != DDRAY)
50 game.damage[l] -= (game.damage[l]-repair > 0.0 ? repair : game.damage[l]);
51 /* If radio repaired, update star chart and attack reports */
52 if (radio_was_broken && game.damage[DRADIO] == 0.0) {
53 prout("Lt. Uhura- \"Captain, the sub-space radio is working and");
54 prout(" surveillance reports are coming in.");
61 prout(" The star chart is now up to date.\"");
64 /* Cause extraneous event LINE to occur */
67 case FSNOVA: /* Supernova */
68 if (ipage==0) pause_game(1);
71 game.future[FSNOVA] = game.state.date + expran(0.5*intime);
72 if (game.state.galaxy[quadx][quady].supernova) return;
74 case FSPY: /* Check with spy to see if S.C. should tractor beam */
75 if (game.state.nscrem == 0 ||
76 ictbeam+istract > 0 ||
77 condit==IHDOCKED || isatb==1 || iscate==1) return;
79 (energy < 2000 && torps < 4 && shield < 1250) ||
80 (game.damage[DPHASER]>0 && (game.damage[DPHOTON]>0 || torps < 4)) ||
81 (game.damage[DSHIELD] > 0 &&
82 (energy < 2500 || game.damage[DPHASER] > 0) &&
83 (torps < 5 || game.damage[DPHOTON] > 0))) {
84 /* Tractor-beam her! */
86 yank = square(game.state.isx-quadx) + square(game.state.isy-quady);
87 /********* fall through to FTBEAM code ***********/
90 case FTBEAM: /* Tractor beam */
92 if (game.state.remcom == 0) {
93 game.future[FTBEAM] = FOREVER;
96 i = Rand()*game.state.remcom+1.0;
97 yank = square(game.state.cx[i]-quadx) + square(game.state.cy[i]-quady);
98 if (istract || condit == IHDOCKED || yank == 0) {
99 /* Drats! Have to reschedule */
100 game.future[FTBEAM] = game.state.date + Time +
101 expran(1.5*intime/game.state.remcom);
105 /* tractor beaming cases merge here */
107 if (ipage==0) pause_game(1);
109 Time = (10.0/(7.5*7.5))*yank; /* 7.5 is yank rate (warp 7.5) */
114 prout(" caught in long range tractor beam--");
115 /* If Kirk & Co. screwing around on planet, handle */
116 atover(1); /* atover(1) is Grab */
118 if (icraft == 1) { /* Caught in Galileo? */
122 /* Check to see if shuttle is aboard */
126 prout("Galileo, left on the planet surface, is captured");
127 prout("by aliens and made into a flying McDonald's.");
128 game.damage[DSHUTTL] = -10;
132 prout("Galileo, left on the planet surface, is well hidden.");
136 quadx = game.state.isx;
137 quady = game.state.isy;
140 quadx = game.state.cx[i];
141 quady = game.state.cy[i];
143 iran(QUADSIZE, §x, §y);
145 proutn(" is pulled to ");
146 proutn(cramlc(quadrant, quadx, quady));
148 prout(cramlc(sector, sectx, secty));
150 prout("(Remainder of rest/repair period cancelled.)");
154 if (game.damage[DSHIELD]==0 && shield > 0) {
155 doshield(2); /* Shldsup */
158 else prout("(Shields not currently useable.)");
161 /* Adjust finish time to time of tractor beaming */
162 fintim = game.state.date+Time;
164 if (game.state.remcom <= 0) game.future[FTBEAM] = FOREVER;
165 else game.future[FTBEAM] = game.state.date+Time+expran(1.5*intime/game.state.remcom);
167 case FSNAP: /* Snapshot of the universe (for time warp) */
168 game.snapsht = game.state;
170 game.future[FSNAP] = game.state.date + expran(0.5 * intime);
172 case FBATTAK: /* Commander attacks starbase */
173 if (game.state.remcom==0 || game.state.rembase==0) {
175 game.future[FBATTAK] = game.future[FCDBAS] = FOREVER;
181 if (game.state.baseqx[j]==game.state.cx[k] && game.state.baseqy[j]==game.state.cy[k] &&
182 (game.state.baseqx[j]!=quadx || game.state.baseqy[j]!=quady) &&
183 (game.state.baseqx[j]!=game.state.isx || game.state.baseqy[j]!=game.state.isy)) {
189 if (j>game.state.rembase) {
190 /* no match found -- try later */
191 game.future[FBATTAK] = game.state.date + expran(0.3*intime);
192 game.future[FCDBAS] = FOREVER;
195 /* commander + starbase combination found -- launch attack */
196 batx = game.state.baseqx[j];
197 baty = game.state.baseqy[j];
198 game.future[FCDBAS] = game.state.date+1.0+3.0*Rand();
199 if (isatb) /* extra time if SC already attacking */
200 game.future[FCDBAS] += game.future[FSCDBAS]-game.state.date;
201 game.future[FBATTAK] = game.future[FCDBAS] +expran(0.3*intime);
203 if (game.damage[DRADIO] != 0.0 &&
204 condit != IHDOCKED) break; /* No warning :-( */
206 if (ipage==0) pause_game(1);
209 proutn("Lt. Uhura- \"Captain, the starbase in ");
210 prout(cramlc(quadrant, batx, baty));
211 prout(" reports that it is under attack and that it can");
212 proutn(" hold out only until stardate %d",
213 (int)game.future[FCDBAS]);
217 proutn("Mr. Spock- \"Captain, shall we cancel the rest period?\" ");
225 case FSCDBAS: /* Supercommander destroys base */
226 game.future[FSCDBAS] = FOREVER;
228 if (!game.state.galaxy[game.state.isx][game.state.isy].starbase)
229 break; /* WAS RETURN! */
232 batx = game.state.isx;
233 baty = game.state.isy;
234 case FCDBAS: /* Commander succeeds in destroying base */
236 game.future[FCDBAS] = FOREVER;
237 /* find the lucky pair */
239 if (game.state.cx[i]==batx && game.state.cy[i]==baty)
241 if (i > game.state.remcom || game.state.rembase == 0 ||
242 !game.state.galaxy[batx][baty].starbase) {
243 /* No action to take after all */
248 /* Code merges here for any commander destroying base */
249 /* Not perfect, but will have to do */
250 /* Handle case where base is in same quadrant as starship */
251 if (batx==quadx && baty==quady) {
252 game.state.chart[batx][baty].starbase = FALSE;
253 game.quad[basex][basey]= IHDOT;
257 prout("Spock- \"Captain, I believe the starbase has been destroyegame.state.\"");
259 else if (game.state.rembase != 1 &&
260 (game.damage[DRADIO] <= 0.0 || condit == IHDOCKED)) {
261 /* Get word via subspace radio */
262 if (ipage==0) pause_game(1);
265 prout("Lt. Uhura- \"Captain, Starfleet Command reports that");
266 proutn(" the starbase in ");
267 proutn(cramlc(quadrant, batx, baty));
268 prout(" has been destroyed by");
269 if (isatb==2) prout("the Klingon Super-Commander");
270 else prout("a Klingon Commander");
271 game.state.chart[batx][baty].starbase = FALSE;
273 /* Remove Starbase from galaxy */
274 game.state.galaxy[batx][baty].starbase = FALSE;
276 if (game.state.baseqx[i]==batx && game.state.baseqy[i]==baty) {
277 game.state.baseqx[i]=game.state.baseqx[game.state.rembase];
278 game.state.baseqy[i]=game.state.baseqy[game.state.rembase];
280 game.state.rembase--;
282 /* reinstate a commander's base attack */
291 case FSCMOVE: /* Supercommander moves */
292 game.future[FSCMOVE] = game.state.date+0.2777;
293 if (ientesc+istract==0 &&
295 (iscate!=1 || justin==1)) scom(&ipage);
297 case FDSPROB: /* Move deep space probe */
298 game.future[FDSPROB] = game.state.date + 0.01;
301 i = (int)(probex/QUADSIZE +0.05);
302 j = (int)(probey/QUADSIZE + 0.05);
303 if (probecx != i || probecy != j) {
306 if (!VALID_QUADRANT(i, j) ||
307 game.state.galaxy[probecx][probecy].supernova) {
308 // Left galaxy or ran into supernova
309 if (game.damage[DRADIO]==0.0 || condit == IHDOCKED) {
310 if (ipage==0) pause_game(1);
313 proutn("Lt. Uhura- \"The deep space probe ");
314 if (!VALID_QUADRANT(j, i))
315 proutn("has left the galaxy");
317 proutn("is no longer transmitting");
320 game.future[FDSPROB] = FOREVER;
323 if (game.damage[DRADIO]==0.0 || condit == IHDOCKED) {
324 if (ipage==0) pause_game(1);
327 proutn("Lt. Uhura- \"The deep space probe is now in ");
328 proutn(cramlc(quadrant, probecx, probecy));
332 /* Update star chart if Radio is working or have access to
334 if (game.damage[DRADIO] == 0.0 || condit == IHDOCKED) {
335 game.state.chart[probecx][probecy].klingons = game.state.galaxy[probecx][probecy].klingons;
336 game.state.chart[probecx][probecy].starbase = game.state.galaxy[probecx][probecy].starbase;
337 game.state.chart[probecx][probecy].stars = game.state.galaxy[probecx][probecy].stars;
338 game.state.galaxy[probecx][probecy].charted = TRUE;
340 proben--; // One less to travel
341 if (proben == 0 && isarmed &&
342 game.state.galaxy[probecx][probecy].stars) {
343 /* lets blow the sucker! */
345 game.future[FDSPROB] = FOREVER;
346 if (game.state.galaxy[quadx][quady].supernova)
358 double temp, delay, origTime;
363 if (key != IHEOL) break;
364 proutn("How long? ");
371 origTime = delay = aaitem;
372 if (delay <= 0.0) return;
373 if (delay >= game.state.remtime || nenhere != 0) {
374 proutn("Are you sure? ");
375 if (ja() == 0) return;
378 /* Alternate resting periods (events) with attacks */
382 if (delay <= 0) resting = 0;
384 prout("%d stardates left.", (int)game.state.remtime);
390 double rtime = 1.0 + Rand();
391 if (rtime < temp) temp = rtime;
394 if (Time < delay) attack(0);
400 /* Repair Deathray if long rest at starbase */
401 if (origTime-delay >= 9.99 && condit == IHDOCKED)
402 game.damage[DDRAY] = 0.0;
404 // leave if quadrant supernovas
405 (!game.state.galaxy[quadx][quady].supernova);
411 void nova(int ix, int iy)
413 static double course[] =
414 {0.0, 10.5, 12.0, 1.5, 9.0, 0.0, 3.0, 7.5, 6.0, 4.5};
415 int bot, top, top2, hits[QUADSIZE+1][3], kount, icx, icy, mm, nn, j;
416 int iquad, iquad1, i, ll, newcx, newcy, ii, jj;
418 /* Wow! We've supernova'ed */
423 /* handle initial nova */
424 game.quad[ix][iy] = IHDOT;
425 crmena(1, IHSTAR, 2, ix, iy);
427 game.state.galaxy[quadx][quady].stars--;
430 /* Set up stack to recursively trigger adjacent stars */
431 bot = top = top2 = 1;
437 for (mm = bot; mm <= top; mm++)
438 for (nn = 1; nn <= 3; nn++) /* nn,j represents coordinates around current */
439 for (j = 1; j <= 3; j++) {
440 if (j==2 && nn== 2) continue;
441 ii = hits[mm][1]+nn-2;
442 jj = hits[mm][2]+j-2;
443 if (!VALID_SECTOR(jj, ii)) continue;
444 iquad = game.quad[ii][jj];
446 // case IHDOT: /* Empty space ends reaction
453 case IHSTAR: /* Affect another star */
455 /* This star supernovas */
462 game.state.galaxy[quadx][quady].stars -= 1;
464 crmena(1, IHSTAR, 2, ii, jj);
466 game.quad[ii][jj] = IHDOT;
468 case IHP: /* Destroy planet */
469 game.state.galaxy[quadx][quady].planets -= 1;
470 game.state.nplankl++;
471 crmena(1, IHP, 2, ii, jj);
472 prout(" destroyed.");
473 DESTROY(&game.state.plnets[iplnet]);
474 iplnet = plnetx = plnety = 0;
479 game.quad[ii][jj] = IHDOT;
481 case IHB: /* Destroy base */
482 game.state.galaxy[quadx][quady].starbase = FALSE;
484 if (game.state.baseqx[i]==quadx && game.state.baseqy[i]==quady)
486 game.state.baseqx[i] = game.state.baseqx[game.state.rembase];
487 game.state.baseqy[i] = game.state.baseqy[game.state.rembase];
488 game.state.rembase--;
492 crmena(1, IHB, 2, ii, jj);
493 prout(" destroyed.");
494 game.quad[ii][jj] = IHDOT;
496 case IHE: /* Buffet ship */
498 prout("***Starship buffeted by nova.");
500 if (shield >= 2000.0) shield -= 2000.0;
502 double diff = 2000.0 - shield;
506 prout("***Shields knocked out.");
507 game.damage[DSHIELD] += 0.005*damfac*Rand()*diff;
510 else energy -= 2000.0;
515 /* add in course nova contributes to kicking starship*/
516 icx += sectx-hits[mm][1];
517 icy += secty-hits[mm][2];
520 case IHK: /* kill klingon */
521 deadkl(ii,jj,iquad, ii, jj);
523 case IHC: /* Damage/destroy big enemies */
526 for_local_enemies(ll)
527 if (game.kx[ll]==ii && game.ky[ll]==jj) break;
528 game.kpower[ll] -= 800.0; /* If firepower is lost, die */
529 if (game.kpower[ll] <= 0.0) {
530 deadkl(ii, jj, iquad, ii, jj);
533 newcx = ii + ii - hits[mm][1];
534 newcy = jj + jj - hits[mm][2];
535 crmena(1, iquad, 2, ii, jj);
537 if (!VALID_SECTOR(newcx, newcy)) {
538 /* can't leave quadrant */
542 iquad1 = game.quad[newcx][newcy];
543 if (iquad1 == IHBLANK) {
544 proutn(", blasted into ");
545 crmena(0, IHBLANK, 2, newcx, newcy);
547 deadkl(ii, jj, iquad, newcx, newcy);
550 if (iquad1 != IHDOT) {
551 /* can't move into something else */
555 proutn(", buffeted to ");
556 proutn(cramlc(sector, newcx, newcy));
557 game.quad[ii][jj] = IHDOT;
558 game.quad[newcx][newcy] = iquad;
561 game.kavgd[ll] = sqrt(square(sectx-newcx)+square(secty-newcy));
562 game.kdist[ll] = game.kavgd[ll];
575 /* Starship affected by nova -- kick it away. */
577 if (icx) icx = (icx < 0 ? -1 : 1);
578 if (icy) icy = (icy < 0 ? -1 : 1);
579 direc = course[3*(icx+1)+icy+2];
580 if (direc == 0.0) dist = 0.0;
581 if (dist == 0.0) return;
582 Time = 10.0*dist/16.0;
584 prout("Force of nova displaces starship.");
585 iattak=2; /* Eliminates recursion problem */
587 Time = 10.0*dist/16.0;
592 void snova(int insx, int insy)
594 int comdead, nqx=0, nqy=0, nsx, nsy, num=0, kldead, iscdead;
603 /* NOVAMAX being used */
609 /* Scheduled supernova -- select star */
610 /* logic changed here so that we won't favor quadrants in top
614 stars += game.state.galaxy[nqx][nqy].stars;
617 if (stars == 0) return; /* nothing to supernova exists */
618 num = Rand()*stars + 1;
621 num -= game.state.galaxy[nqx][nqy].stars;
628 proutn("Super nova here?");
637 if (nqx != quady || nqy != quady || justin != 0) {
638 /* it isn't here, or we just entered (treat as inroute) */
639 if (game.damage[DRADIO] == 0.0 || condit == IHDOCKED) {
641 prout("Message from Starfleet Command Stardate %.2f", game.state.date);
642 prout(" Supernova in %s; caution advised.",
643 cramlc(quadrant, nqx, nqy));
647 /* we are in the quadrant! */
649 num = Rand()* game.state.galaxy[nqx][nqy].stars + 1;
652 if (game.quad[nsx][nsy]==IHSTAR) {
667 prouts("***RED ALERT! RED ALERT!");
669 prout("***Incipient supernova detected at ", cramlc(sector, nsx, nsy));
672 if (square(nsx-sectx) + square(nsy-secty) <= 2.1) {
673 proutn("Emergency override attempts t");
674 prouts("***************");
680 /* destroy any Klingons in supernovaed quadrant */
681 kldead = game.state.galaxy[nqx][nqy].klingons;
682 game.state.galaxy[nqx][nqy].klingons = 0;
683 comdead = iscdead = 0;
684 if (nqx==game.state.isx && nqy == game.state.isy) {
685 /* did in the Supercommander! */
686 game.state.nscrem = game.state.isx = game.state.isy = isatb = iscate = 0;
688 game.future[FSCMOVE] = game.future[FSCDBAS] = FOREVER;
690 if (game.state.remcom) {
691 int maxloop = game.state.remcom, l;
692 for (l = 1; l <= maxloop; l++) {
693 if (game.state.cx[l] == nqx && game.state.cy[l] == nqy) {
694 game.state.cx[l] = game.state.cx[game.state.remcom];
695 game.state.cy[l] = game.state.cy[game.state.remcom];
696 game.state.cx[game.state.remcom] = game.state.cy[game.state.remcom] = 0;
700 if (game.state.remcom==0) game.future[FTBEAM] = FOREVER;
705 game.state.remkl -= kldead;
706 /* destroy Romulans and planets in supernovaed quadrant */
707 nrmdead = game.state.galaxy[nqx][nqy].romulans;
708 game.state.galaxy[nqx][nqy].romulans = 0;
709 game.state.nromrem -= nrmdead;
710 npdead = num - nrmdead*10;
713 for (l = 0; l < inplan; l++)
714 if (game.state.plnets[l].x == nqx && game.state.plnets[l].y == nqy) {
715 DESTROY(&game.state.plnets[l]);
718 /* Destroy any base in supernovaed quadrant */
719 if (game.state.rembase) {
720 int maxloop = game.state.rembase, l;
721 for (l = 1; l <= maxloop; l++)
722 if (game.state.baseqx[l]==nqx && game.state.baseqy[l]==nqy) {
723 game.state.baseqx[l] = game.state.baseqx[game.state.rembase];
724 game.state.baseqy[l] = game.state.baseqy[game.state.rembase];
725 game.state.baseqx[game.state.rembase] = game.state.baseqy[game.state.rembase] = 0;
726 game.state.rembase--;
730 /* If starship caused supernova, tally up destruction */
732 game.state.starkl += game.state.galaxy[nqx][nqy].stars;
733 game.state.basekl += game.state.galaxy[nqx][nqy].starbase;
734 game.state.nplankl += npdead;
736 /* mark supernova in galaxy and in star chart */
737 if ((quadx == nqx && quady == nqy) ||
738 game.damage[DRADIO] == 0 ||
740 game.state.galaxy[nqx][nqy].supernova = TRUE;
741 /* If supernova destroys last klingons give special message */
742 if (KLINGREM==0 && (nqx != quadx || nqy != quady)) {
744 if (insx == 0) prout("Lucky you!");
745 proutn("A supernova in %s has just destroyed the last Klingons.",
746 cramlc(quadrant, nqx, nqy));
750 /* if some Klingons remain, continue or die in supernova */
751 if (alldone) finish(FSNOVAED);