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) {
54 prout("Lt. Uhura- \"Captain, the sub-space radio is working and");
55 prout(" surveillance reports are coming in.");
62 prout(" The star chart is now up to date.\"");
65 /* Cause extraneous event LINE to occur */
68 case FSNOVA: /* Supernova */
69 if (ipage==0) pause_game(1);
72 game.future[FSNOVA] = game.state.date + expran(0.5*intime);
73 if (game.state.galaxy[quadx][quady].supernova) return;
75 case FSPY: /* Check with spy to see if S.C. should tractor beam */
76 if (game.state.nscrem == 0 ||
77 ictbeam+istract > 0 ||
78 condit==IHDOCKED || isatb==1 || iscate==1) return;
80 (energy < 2000 && torps < 4 && shield < 1250) ||
81 (game.damage[DPHASER]>0 && (game.damage[DPHOTON]>0 || torps < 4)) ||
82 (game.damage[DSHIELD] > 0 &&
83 (energy < 2500 || game.damage[DPHASER] > 0) &&
84 (torps < 5 || game.damage[DPHOTON] > 0))) {
85 /* Tractor-beam her! */
87 yank = square(game.state.isx-quadx) + square(game.state.isy-quady);
88 /********* fall through to FTBEAM code ***********/
91 case FTBEAM: /* Tractor beam */
93 if (game.state.remcom == 0) {
94 game.future[FTBEAM] = 1e30;
97 i = Rand()*game.state.remcom+1.0;
98 yank = square(game.state.cx[i]-quadx) + square(game.state.cy[i]-quady);
99 if (istract || condit == IHDOCKED || yank == 0) {
100 /* Drats! Have to reschedule */
101 game.future[FTBEAM] = game.state.date + Time +
102 expran(1.5*intime/game.state.remcom);
106 /* tractor beaming cases merge here */
108 if (ipage==0) pause_game(1);
110 Time = (10.0/(7.5*7.5))*yank; /* 7.5 is yank rate (warp 7.5) */
115 prout(" caught in long range tractor beam--");
116 /* If Kirk & Co. screwing around on planet, handle */
117 atover(1); /* atover(1) is Grab */
119 if (icraft == 1) { /* Caught in Galileo? */
123 /* Check to see if shuttle is aboard */
127 prout("Galileo, left on the planet surface, is captured");
128 prout("by aliens and made into a flying McDonald's.");
129 game.damage[DSHUTTL] = -10;
133 prout("Galileo, left on the planet surface, is well hidden.");
137 quadx = game.state.isx;
138 quady = game.state.isy;
141 quadx = game.state.cx[i];
142 quady = game.state.cy[i];
144 iran(QUADSIZE, §x, §y);
146 proutn(" is pulled to ");
147 proutn(cramlc(quadrant, quadx, quady));
149 prout(cramlc(sector, sectx, secty));
151 prout("(Remainder of rest/repair period cancelled.)");
155 if (game.damage[DSHIELD]==0 && shield > 0) {
156 doshield(2); /* Shldsup */
159 else prout("(Shields not currently useable.)");
162 /* Adjust finish time to time of tractor beaming */
163 fintim = game.state.date+Time;
165 if (game.state.remcom <= 0) game.future[FTBEAM] = 1e30;
166 else game.future[FTBEAM] = game.state.date+Time+expran(1.5*intime/game.state.remcom);
168 case FSNAP: /* Snapshot of the universe (for time warp) */
169 game.snapsht = game.state;
171 game.future[FSNAP] = game.state.date + expran(0.5 * intime);
173 case FBATTAK: /* Commander attacks starbase */
174 if (game.state.remcom==0 || game.state.rembase==0) {
176 game.future[FBATTAK] = game.future[FCDBAS] = 1e30;
182 if (game.state.baseqx[j]==game.state.cx[k] && game.state.baseqy[j]==game.state.cy[k] &&
183 (game.state.baseqx[j]!=quadx || game.state.baseqy[j]!=quady) &&
184 (game.state.baseqx[j]!=game.state.isx || game.state.baseqy[j]!=game.state.isy)) {
190 if (j>game.state.rembase) {
191 /* no match found -- try later */
192 game.future[FBATTAK] = game.state.date + expran(0.3*intime);
193 game.future[FCDBAS] = 1e30;
196 /* commander + starbase combination found -- launch attack */
197 batx = game.state.baseqx[j];
198 baty = game.state.baseqy[j];
199 game.future[FCDBAS] = game.state.date+1.0+3.0*Rand();
200 if (isatb) /* extra time if SC already attacking */
201 game.future[FCDBAS] += game.future[FSCDBAS]-game.state.date;
202 game.future[FBATTAK] = game.future[FCDBAS] +expran(0.3*intime);
204 if (game.damage[DRADIO] != 0.0 &&
205 condit != IHDOCKED) break; /* No warning :-( */
207 if (ipage==0) pause_game(1);
210 proutn("Lt. Uhura- \"Captain, the starbase in ");
211 prout(cramlc(quadrant, batx, baty));
212 prout(" reports that it is under attack and that it can");
213 proutn(" hold out only until stardate %d",
214 (int)game.future[FCDBAS]);
218 proutn("Mr. Spock- \"Captain, shall we cancel the rest period?\" ");
226 case FSCDBAS: /* Supercommander destroys base */
227 game.future[FSCDBAS] = 1e30;
229 if (!game.state.galaxy[game.state.isx][game.state.isy].starbase)
230 break; /* WAS RETURN! */
233 batx = game.state.isx;
234 baty = game.state.isy;
235 case FCDBAS: /* Commander succeeds in destroying base */
237 game.future[FCDBAS] = 1e30;
238 /* find the lucky pair */
240 if (game.state.cx[i]==batx && game.state.cy[i]==baty)
242 if (i > game.state.remcom || game.state.rembase == 0 ||
243 !game.state.galaxy[batx][baty].starbase) {
244 /* No action to take after all */
249 /* Code merges here for any commander destroying base */
250 /* Not perfect, but will have to do */
251 /* Handle case where base is in same quadrant as starship */
252 if (batx==quadx && baty==quady) {
253 game.state.chart[batx][baty].starbase = FALSE;
254 game.quad[basex][basey]= IHDOT;
258 prout("Spock- \"Captain, I believe the starbase has been destroyegame.state.\"");
260 else if (game.state.rembase != 1 &&
261 (game.damage[DRADIO] <= 0.0 || condit == IHDOCKED)) {
262 /* Get word via subspace radio */
263 if (ipage==0) pause_game(1);
266 prout("Lt. Uhura- \"Captain, Starfleet Command reports that");
267 proutn(" the starbase in ");
268 proutn(cramlc(quadrant, batx, baty));
269 prout(" has been destroyed by");
270 if (isatb==2) prout("the Klingon Super-Commander");
271 else prout("a Klingon Commander");
272 game.state.chart[batx][baty].starbase = FALSE;
274 /* Remove Starbase from galaxy */
275 game.state.galaxy[batx][baty].starbase = FALSE;
277 if (game.state.baseqx[i]==batx && game.state.baseqy[i]==baty) {
278 game.state.baseqx[i]=game.state.baseqx[game.state.rembase];
279 game.state.baseqy[i]=game.state.baseqy[game.state.rembase];
281 game.state.rembase--;
283 /* reinstate a commander's base attack */
292 case FSCMOVE: /* Supercommander moves */
293 game.future[FSCMOVE] = game.state.date+0.2777;
294 if (ientesc+istract==0 &&
296 (iscate!=1 || justin==1)) scom(&ipage);
298 case FDSPROB: /* Move deep space probe */
299 game.future[FDSPROB] = game.state.date + 0.01;
302 i = (int)(probex/QUADSIZE +0.05);
303 j = (int)(probey/QUADSIZE + 0.05);
304 if (probecx != i || probecy != j) {
307 if (!VALID_QUADRANT(i, j) ||
308 game.state.galaxy[probecx][probecy].supernova) {
309 // Left galaxy or ran into supernova
310 if (game.damage[DRADIO]==0.0 || condit == IHDOCKED) {
311 if (ipage==0) pause_game(1);
314 proutn("Lt. Uhura- \"The deep space probe ");
315 if (!VALID_QUADRANT(j, i))
316 proutn("has left the galaxy");
318 proutn("is no longer transmitting");
321 game.future[FDSPROB] = 1e30;
324 if (game.damage[DRADIO]==0.0 || condit == IHDOCKED) {
325 if (ipage==0) pause_game(1);
328 proutn("Lt. Uhura- \"The deep space probe is now in ");
329 proutn(cramlc(quadrant, probecx, probecy));
333 /* Update star chart if Radio is working or have access to
335 if (game.damage[DRADIO] == 0.0 || condit == IHDOCKED) {
336 game.state.chart[probecx][probecy].klingons = game.state.galaxy[probecx][probecy].klingons;
337 game.state.chart[probecx][probecy].starbase = game.state.galaxy[probecx][probecy].starbase;
338 game.state.chart[probecx][probecy].stars = game.state.galaxy[probecx][probecy].stars;
339 game.state.galaxy[probecx][probecy].charted = TRUE;
341 proben--; // One less to travel
342 if (proben == 0 && isarmed &&
343 game.state.galaxy[probecx][probecy].stars) {
344 /* lets blow the sucker! */
346 game.future[FDSPROB] = 1e30;
347 if (game.state.galaxy[quadx][quady].supernova)
359 double temp, delay, origTime;
364 if (key != IHEOL) break;
365 proutn("How long? ");
372 origTime = delay = aaitem;
373 if (delay <= 0.0) return;
374 if (delay >= game.state.remtime || nenhere != 0) {
375 proutn("Are you sure? ");
376 if (ja() == 0) return;
379 /* Alternate resting periods (events) with attacks */
383 if (delay <= 0) resting = 0;
385 prout("%d stardates left.", (int)game.state.remtime);
391 double rtime = 1.0 + Rand();
392 if (rtime < temp) temp = rtime;
395 if (Time < delay) attack(0);
401 /* Repair Deathray if long rest at starbase */
402 if (origTime-delay >= 9.99 && condit == IHDOCKED)
403 game.damage[DDRAY] = 0.0;
405 // leave if quadrant supernovas
406 (!game.state.galaxy[quadx][quady].supernova);
412 void nova(int ix, int iy)
414 static double course[] =
415 {0.0, 10.5, 12.0, 1.5, 9.0, 0.0, 3.0, 7.5, 6.0, 4.5};
416 int bot, top, top2, hits[QUADSIZE+1][3], kount, icx, icy, mm, nn, j;
417 int iquad, iquad1, i, ll, newcx, newcy, ii, jj;
419 /* Wow! We've supernova'ed */
424 /* handle initial nova */
425 game.quad[ix][iy] = IHDOT;
426 crmena(1, IHSTAR, 2, ix, iy);
428 game.state.galaxy[quadx][quady].stars--;
431 /* Set up stack to recursively trigger adjacent stars */
432 bot = top = top2 = 1;
438 for (mm = bot; mm <= top; mm++)
439 for (nn = 1; nn <= 3; nn++) /* nn,j represents coordinates around current */
440 for (j = 1; j <= 3; j++) {
441 if (j==2 && nn== 2) continue;
442 ii = hits[mm][1]+nn-2;
443 jj = hits[mm][2]+j-2;
444 if (!VALID_SECTOR(jj, ii)) continue;
445 iquad = game.quad[ii][jj];
447 // case IHDOT: /* Empty space ends reaction
454 case IHSTAR: /* Affect another star */
456 /* This star supernovas */
463 game.state.galaxy[quadx][quady].stars -= 1;
465 crmena(1, IHSTAR, 2, ii, jj);
467 game.quad[ii][jj] = IHDOT;
469 case IHP: /* Destroy planet */
470 game.state.galaxy[quadx][quady].planets -= 1;
471 game.state.nplankl++;
472 crmena(1, IHP, 2, ii, jj);
473 prout(" destroyed.");
474 DESTROY(&game.state.plnets[iplnet]);
475 iplnet = plnetx = plnety = 0;
480 game.quad[ii][jj] = IHDOT;
482 case IHB: /* Destroy base */
483 game.state.galaxy[quadx][quady].starbase = FALSE;
485 if (game.state.baseqx[i]==quadx && game.state.baseqy[i]==quady)
487 game.state.baseqx[i] = game.state.baseqx[game.state.rembase];
488 game.state.baseqy[i] = game.state.baseqy[game.state.rembase];
489 game.state.rembase--;
493 crmena(1, IHB, 2, ii, jj);
494 prout(" destroyed.");
495 game.quad[ii][jj] = IHDOT;
497 case IHE: /* Buffet ship */
499 prout("***Starship buffeted by nova.");
501 if (shield >= 2000.0) shield -= 2000.0;
503 double diff = 2000.0 - shield;
507 prout("***Shields knocked out.");
508 game.damage[DSHIELD] += 0.005*damfac*Rand()*diff;
511 else energy -= 2000.0;
516 /* add in course nova contributes to kicking starship*/
517 icx += sectx-hits[mm][1];
518 icy += secty-hits[mm][2];
521 case IHK: /* kill klingon */
522 deadkl(ii,jj,iquad, ii, jj);
524 case IHC: /* Damage/destroy big enemies */
527 for_local_enemies(ll)
528 if (game.kx[ll]==ii && game.ky[ll]==jj) break;
529 game.kpower[ll] -= 800.0; /* If firepower is lost, die */
530 if (game.kpower[ll] <= 0.0) {
531 deadkl(ii, jj, iquad, ii, jj);
534 newcx = ii + ii - hits[mm][1];
535 newcy = jj + jj - hits[mm][2];
536 crmena(1, iquad, 2, ii, jj);
538 if (!VALID_SECTOR(newcx, newcy)) {
539 /* can't leave quadrant */
543 iquad1 = game.quad[newcx][newcy];
544 if (iquad1 == IHBLANK) {
545 proutn(", blasted into ");
546 crmena(0, IHBLANK, 2, newcx, newcy);
548 deadkl(ii, jj, iquad, newcx, newcy);
551 if (iquad1 != IHDOT) {
552 /* can't move into something else */
556 proutn(", buffeted to ");
557 proutn(cramlc(sector, newcx, newcy));
558 game.quad[ii][jj] = IHDOT;
559 game.quad[newcx][newcy] = iquad;
562 game.kavgd[ll] = sqrt(square(sectx-newcx)+square(secty-newcy));
563 game.kdist[ll] = game.kavgd[ll];
576 /* Starship affected by nova -- kick it away. */
578 if (icx) icx = (icx < 0 ? -1 : 1);
579 if (icy) icy = (icy < 0 ? -1 : 1);
580 direc = course[3*(icx+1)+icy+2];
581 if (direc == 0.0) dist = 0.0;
582 if (dist == 0.0) return;
583 Time = 10.0*dist/16.0;
585 prout("Force of nova displaces starship.");
586 iattak=2; /* Eliminates recursion problem */
588 Time = 10.0*dist/16.0;
593 void snova(int insx, int insy)
595 int comdead, nqx=0, nqy=0, nsx, nsy, num=0, kldead, iscdead;
604 /* NOVAMAX being used */
610 /* Scheduled supernova -- select star */
611 /* logic changed here so that we won't favor quadrants in top
615 stars += game.state.galaxy[nqx][nqy].stars;
618 if (stars == 0) return; /* nothing to supernova exists */
619 num = Rand()*stars + 1;
622 num -= game.state.galaxy[nqx][nqy].stars;
629 proutn("Super nova here?");
638 if (nqx != quady || nqy != quady || justin != 0) {
639 /* it isn't here, or we just entered (treat as inroute) */
640 if (game.damage[DRADIO] == 0.0 || condit == IHDOCKED) {
642 prout("Message from Starfleet Command Stardate %.2f", game.state.date);
643 prout(" Supernova in %s; caution advised.",
644 cramlc(quadrant, nqx, nqy));
648 /* we are in the quadrant! */
650 num = Rand()* game.state.galaxy[nqx][nqy].stars + 1;
653 if (game.quad[nsx][nsy]==IHSTAR) {
668 prouts("***RED ALERT! RED ALERT!");
670 prout("***Incipient supernova detected at ", cramlc(sector, nsx, nsy));
673 if (square(nsx-sectx) + square(nsy-secty) <= 2.1) {
674 proutn("Emergency override attempts t");
675 prouts("***************");
681 /* destroy any Klingons in supernovaed quadrant */
682 kldead = game.state.galaxy[nqx][nqy].klingons;
683 game.state.galaxy[nqx][nqy].klingons = 0;
684 comdead = iscdead = 0;
685 if (nqx==game.state.isx && nqy == game.state.isy) {
686 /* did in the Supercommander! */
687 game.state.nscrem = game.state.isx = game.state.isy = isatb = iscate = 0;
689 game.future[FSCMOVE] = game.future[FSCDBAS] = 1e30;
691 game.state.remkl -= kldead;
692 if (game.state.remcom) {
693 int maxloop = game.state.remcom, l;
694 for (l = 1; l <= maxloop; l++) {
695 if (game.state.cx[l] == nqx && game.state.cy[l] == nqy) {
696 game.state.cx[l] = game.state.cx[game.state.remcom];
697 game.state.cy[l] = game.state.cy[game.state.remcom];
698 game.state.cx[game.state.remcom] = game.state.cy[game.state.remcom] = 0;
702 if (game.state.remcom==0) game.future[FTBEAM] = 1e30;
707 /* destroy Romulans and planets in supernovaed quadrant */
708 nrmdead = game.state.galaxy[nqx][nqy].romulans;
709 game.state.galaxy[nqx][nqy].romulans = 0;
710 game.state.nromrem -= nrmdead;
711 npdead = num - nrmdead*10;
714 for (l = 0; l < inplan; l++)
715 if (game.state.plnets[l].x == nqx && game.state.plnets[l].y == nqy) {
716 DESTROY(&game.state.plnets[l]);
719 /* Destroy any base in supernovaed quadrant */
720 if (game.state.rembase) {
721 int maxloop = game.state.rembase, l;
722 for (l = 1; l <= maxloop; l++)
723 if (game.state.baseqx[l]==nqx && game.state.baseqy[l]==nqy) {
724 game.state.baseqx[l] = game.state.baseqx[game.state.rembase];
725 game.state.baseqy[l] = game.state.baseqy[game.state.rembase];
726 game.state.baseqx[game.state.rembase] = game.state.baseqy[game.state.rembase] = 0;
727 game.state.rembase--;
731 /* If starship caused supernova, tally up destruction */
733 game.state.starkl += game.state.galaxy[nqx][nqy].stars;
734 game.state.basekl += game.state.galaxy[nqx][nqy].starbase;
735 game.state.killk += kldead;
736 game.state.killc += comdead;
737 game.state.nromkl += nrmdead;
738 game.state.nplankl += npdead;
739 game.state.nsckill += iscdead;
741 /* mark supernova in galaxy and in star chart */
742 if ((quadx == nqx && quady == nqy) ||
743 game.damage[DRADIO] == 0 ||
745 game.state.galaxy[nqx][nqy].supernova = TRUE;
746 /* If supernova destroys last klingons give special message */
747 if (game.state.remkl==0 && (nqx != quadx || nqy != quady)) {
749 if (insx == 0) prout("Lucky you!");
750 proutn("A supernova in %s has just destroyed the last Klingons.",
751 cramlc(quadrant, nqx, nqy));
755 /* if some Klingons remain, continue or die in supernova */
756 if (alldone) finish(FSNOVAED);