5 int ictbeam=0, ipage=0, istract=0, line, i=0, j, k, l, ixhold=0, iyhold=0;
6 double fintim = game.state.date + Time, datemin, xtime, repair, yank=0;
9 if (idebug) prout("EVENTS");
12 if (stdamtim == 1e30 && game.damage[DRADIO] != 0.0) {
13 /* chart will no longer be updated because radio is dead */
14 stdamtim = game.state.date;
15 for (i=1; i <= 8 ; i++)
16 for (j=1; j <= 8; j++)
17 if (game.starch[i][j] == 1) game.starch[i][j] = game.state.galaxy[i][j]+1000;
21 /* Select earliest extraneous event, line==0 if no events */
25 for (l=1; l<=NEVENTS; l++)
26 if (game.future[l] < datemin) {
28 datemin = game.future[l];
30 xtime = datemin-game.state.date;
31 game.state.date = datemin;
32 /* Decrement Federation resources and recompute remaining time */
33 game.state.remres -= (game.state.remkl+4*game.state.remcom)*xtime;
34 game.state.remtime = game.state.remres/(game.state.remkl+4*game.state.remcom);
35 if (game.state.remtime <=0) {
39 /* Is life support adequate? */
40 if (game.damage[DLIFSUP] && condit != IHDOCKED) {
41 if (lsupres < xtime && game.damage[DLIFSUP] > lsupres) {
46 if (game.damage[DLIFSUP] <= xtime) lsupres = inlsr;
50 if (condit == IHDOCKED) repair /= docfac;
51 /* Don't fix Deathray here */
52 for (l=1; l<=NDEVICES; l++)
53 if (game.damage[l] > 0.0 && l != DDRAY)
54 game.damage[l] -= (game.damage[l]-repair > 0.0 ? repair : game.damage[l]);
55 /* If radio repaired, update star chart and attack reports */
56 if (stdamtim != 1e30 && game.damage[DRADIO] == 0.0) {
58 prout("Lt. Uhura- \"Captain, the sub-space radio is working and");
59 prout(" surveillance reports are coming in.");
61 for (i=1; i <= 8 ; i++)
62 for (j=1; j <= 8; j++)
63 if (game.starch[i][j] > 999) game.starch[i][j] = 1;
69 prout(" The star chart is now up to date.\"");
72 /* Cause extraneous event LINE to occur */
75 case FSNOVA: /* Supernova */
76 if (ipage==0) pause_game(1);
79 game.future[FSNOVA] = game.state.date + expran(0.5*intime);
80 if (game.state.galaxy[quadx][quady] == 1000) return;
82 case FSPY: /* Check with spy to see if S.C. should tractor beam */
83 if (game.state.nscrem == 0 ||
84 ictbeam+istract > 0 ||
85 condit==IHDOCKED || isatb==1 || iscate==1) return;
87 (energy < 2000 && torps < 4 && shield < 1250) ||
88 (game.damage[DPHASER]>0 && (game.damage[DPHOTON]>0 || torps < 4)) ||
89 (game.damage[DSHIELD] > 0 &&
90 (energy < 2500 || game.damage[DPHASER] > 0) &&
91 (torps < 5 || game.damage[DPHOTON] > 0))) {
92 /* Tractor-beam her! */
94 yank = square(game.state.isx-quadx) + square(game.state.isy-quady);
95 /*********TBEAM CODE***********/
98 case FTBEAM: /* Tractor beam */
100 if (game.state.remcom == 0) {
101 game.future[FTBEAM] = 1e30;
104 i = Rand()*game.state.remcom+1.0;
105 yank = square(game.state.cx[i]-quadx) + square(game.state.cy[i]-quady);
106 if (istract || condit == IHDOCKED || yank == 0) {
107 /* Drats! Have to reschedule */
108 game.future[FTBEAM] = game.state.date + Time +
109 expran(1.5*intime/game.state.remcom);
113 /* tractor beaming cases merge here */
115 if (ipage==0) pause_game(1);
117 Time = (10.0/(7.5*7.5))*yank; /* 7.5 is yank rate (warp 7.5) */
122 prout(" caught in long range tractor beam--");
123 /* If Kirk & Co. screwing around on planet, handle */
124 atover(1); /* atover(1) is Grab */
126 if (icraft == 1) { /* Caught in Galileo? */
130 /* Check to see if shuttle is aboard */
134 prout("Galileo, left on the planet surface, is captured");
135 prout("by aliens and made into a flying McDonald's.");
136 game.damage[DSHUTTL] = -10;
140 prout("Galileo, left on the planet surface, is well hidden.");
144 quadx = game.state.isx;
145 quady = game.state.isy;
148 quadx = game.state.cx[i];
149 quady = game.state.cy[i];
151 iran10(§x, §y);
153 proutn(" is pulled to ");
154 proutn(cramlc(quadrant, quadx, quady));
156 prout(cramlc(sector, sectx, secty));
158 prout("(Remainder of rest/repair period cancellegame.state.)");
162 if (game.damage[DSHIELD]==0 && shield > 0) {
163 doshield(2); /* Shldsup */
166 else prout("(Shields not currently useable.)");
169 /* Adjust finish time to time of tractor beaming */
170 fintim = game.state.date+Time;
172 if (game.state.remcom <= 0) game.future[FTBEAM] = 1e30;
173 else game.future[FTBEAM] = game.state.date+Time+expran(1.5*intime/game.state.remcom);
175 case FSNAP: /* Snapshot of the universe (for time warp) */
176 game.snapsht = game.state;
178 game.future[FSNAP] = game.state.date + expran(0.5 * intime);
180 case FBATTAK: /* Commander attacks starbase */
181 if (game.state.remcom==0 || game.state.rembase==0) {
183 game.future[FBATTAK] = game.future[FCDBAS] = 1e30;
187 for (j=1; j<=game.state.rembase; j++) {
188 for (k=1; k<=game.state.remcom; k++)
189 if (game.state.baseqx[j]==game.state.cx[k] && game.state.baseqy[j]==game.state.cy[k] &&
190 (game.state.baseqx[j]!=quadx || game.state.baseqy[j]!=quady) &&
191 (game.state.baseqx[j]!=game.state.isx || game.state.baseqy[j]!=game.state.isy)) {
197 if (j>game.state.rembase) {
198 /* no match found -- try later */
199 game.future[FBATTAK] = game.state.date + expran(0.3*intime);
200 game.future[FCDBAS] = 1e30;
203 /* commander + starbase combination found -- launch attack */
204 batx = game.state.baseqx[j];
205 baty = game.state.baseqy[j];
206 game.future[FCDBAS] = game.state.date+1.0+3.0*Rand();
207 if (isatb) /* extra time if SC already attacking */
208 game.future[FCDBAS] += game.future[FSCDBAS]-game.state.date;
209 game.future[FBATTAK] = game.future[FCDBAS] +expran(0.3*intime);
211 if (game.damage[DRADIO] != 0.0 &&
212 condit != IHDOCKED) break; /* No warning :-( */
214 if (ipage==0) pause_game(1);
217 proutn("Lt. Uhura- \"Captain, the starbase in ");
218 prout(cramlc(quadrant, batx, baty));
219 prout(" reports that it is under attack and that it can");
220 proutn(" hold out only until stardate %d",
221 (int)game.future[FCDBAS]);
225 proutn("Mr. Spock- \"Captain, shall we cancel the rest period?\" ");
233 case FSCDBAS: /* Supercommander destroys base */
234 game.future[FSCDBAS] = 1e30;
236 if (game.state.galaxy[game.state.isx][game.state.isy]%100 < 10) break; /* WAS RETURN! */
239 batx = game.state.isx;
240 baty = game.state.isy;
241 case FCDBAS: /* Commander succeeds in destroying base */
243 game.future[FCDBAS] = 1e30;
244 /* find the lucky pair */
245 for (i = 1; i <= game.state.remcom; i++)
246 if (game.state.cx[i]==batx && game.state.cy[i]==baty) break;
247 if (i > game.state.remcom || game.state.rembase == 0 ||
248 game.state.galaxy[batx][baty] % 100 < 10) {
249 /* No action to take after all */
254 /* Code merges here for any commander destroying base */
255 /* Not perfect, but will have to do */
256 if (game.starch[batx][baty] == -1) game.starch[batx][baty] = 0;
257 /* Handle case where base is in same quadrant as starship */
258 if (batx==quadx && baty==quady) {
259 if (game.starch[batx][baty] > 999) game.starch[batx][baty] -= 10;
260 game.quad[basex][basey]= IHDOT;
264 prout("Spock- \"Captain, I believe the starbase has been destroyegame.state.\"");
266 else if (game.state.rembase != 1 &&
267 (game.damage[DRADIO] <= 0.0 || condit == IHDOCKED)) {
268 /* Get word via subspace radio */
269 if (ipage==0) pause_game(1);
272 prout("Lt. Uhura- \"Captain, Starfleet Command reports that");
273 proutn(" the starbase in ");
274 proutn(cramlc(quadrant, batx, baty));
275 prout(" has been destroyed by");
276 if (isatb==2) prout("the Klingon Super-Commander");
277 else prout("a Klingon Commander");
279 /* Remove Starbase from galaxy */
280 game.state.galaxy[batx][baty] -= 10;
281 for (i=1; i <= game.state.rembase; i++)
282 if (game.state.baseqx[i]==batx && game.state.baseqy[i]==baty) {
283 game.state.baseqx[i]=game.state.baseqx[game.state.rembase];
284 game.state.baseqy[i]=game.state.baseqy[game.state.rembase];
286 game.state.rembase--;
288 /* reinstate a commander's base attack */
297 case FSCMOVE: /* Supercommander moves */
298 game.future[FSCMOVE] = game.state.date+0.2777;
299 if (ientesc+istract==0 &&
301 (iscate!=1 || justin==1)) scom(&ipage);
303 case FDSPROB: /* Move deep space probe */
304 game.future[FDSPROB] = game.state.date + 0.01;
307 i = (int)(probex/10 +0.05);
308 j = (int)(probey/10 + 0.05);
309 if (probecx != i || probecy != j) {
312 if (i < 1 || i > 8 || j < 1 || j > 8 ||
313 game.state.galaxy[probecx][probecy] == 1000) {
314 // Left galaxy or ran into supernova
315 if (game.damage[DRADIO]==0.0 || condit == IHDOCKED) {
316 if (ipage==0) pause_game(1);
319 proutn("Lt. Uhura- \"The deep space probe ");
320 if (i < 1 ||i > 8 || j < 1 || j > 8)
321 proutn("has left the galaxy");
323 proutn("is no longer transmitting");
326 game.future[FDSPROB] = 1e30;
329 if (game.damage[DRADIO]==0.0 || condit == IHDOCKED) {
330 if (ipage==0) pause_game(1);
333 proutn("Lt. Uhura- \"The deep space probe is now in ");
334 proutn(cramlc(quadrant, probecx, probecy));
338 /* Update star chart if Radio is working or have access to
340 if (game.damage[DRADIO] == 0.0 || condit == IHDOCKED)
341 game.starch[probecx][probecy] = game.damage[DRADIO] > 0.0 ?
342 game.state.galaxy[probecx][probecy]+1000 : 1;
343 proben--; // One less to travel
344 if (proben == 0 && isarmed &&
345 game.state.galaxy[probecx][probecy] % 10 > 0) {
346 /* lets blow the sucker! */
348 game.future[FDSPROB] = 1e30;
349 if (game.state.galaxy[quadx][quady] == 1000) return;
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;
404 } while (game.state.galaxy[quadx][quady] != 1000); // leave if quadrant supernovas
410 void nova(int ix, int iy) {
411 static double course[] =
412 {0.0, 10.5, 12.0, 1.5, 9.0, 0.0, 3.0, 7.5, 6.0, 4.5};
413 int bot, top, top2, hits[11][3], kount, icx, icy, mm, nn, j;
414 int iquad, iquad1, i, ll, newcx, newcy, ii, jj;
416 /* Wow! We've supernova'ed */
421 /* handle initial nova */
422 game.quad[ix][iy] = IHDOT;
423 crmena(1, IHSTAR, 2, ix, iy);
425 game.state.galaxy[quadx][quady] -= 1;
428 /* Set up stack to recursively trigger adjacent stars */
429 bot = top = top2 = 1;
435 for (mm = bot; mm <= top; mm++)
436 for (nn = 1; nn <= 3; nn++) /* nn,j represents coordinates around current */
437 for (j = 1; j <= 3; j++) {
438 if (j==2 && nn== 2) continue;
439 ii = hits[mm][1]+nn-2;
440 jj = hits[mm][2]+j-2;
441 if (ii < 1 || ii > 10 || jj < 1 || jj > 10) continue;
442 iquad = game.quad[ii][jj];
444 // case IHDOT: /* Empty space ends reaction
451 case IHSTAR: /* Affect another star */
453 /* This star supernovas */
460 game.state.galaxy[quadx][quady] -= 1;
462 crmena(1, IHSTAR, 2, ii, jj);
464 game.quad[ii][jj] = IHDOT;
466 case IHP: /* Destroy planet */
467 game.state.newstuf[quadx][quady] -= 1;
468 game.state.nplankl++;
469 crmena(1, IHP, 2, ii, jj);
470 prout(" destroyed.");
471 DESTROY(&game.state.plnets[iplnet]);
472 iplnet = plnetx = plnety = 0;
477 game.quad[ii][jj] = IHDOT;
479 case IHB: /* Destroy base */
480 game.state.galaxy[quadx][quady] -= 10;
481 for (i = 1; i <= game.state.rembase; i++)
482 if (game.state.baseqx[i]==quadx && game.state.baseqy[i]==quady) break;
483 game.state.baseqx[i] = game.state.baseqx[game.state.rembase];
484 game.state.baseqy[i] = game.state.baseqy[game.state.rembase];
485 game.state.rembase--;
489 crmena(1, IHB, 2, ii, jj);
490 prout(" destroyed.");
491 game.quad[ii][jj] = IHDOT;
493 case IHE: /* Buffet ship */
495 prout("***Starship buffeted by nova.");
497 if (shield >= 2000.0) shield -= 2000.0;
499 double diff = 2000.0 - shield;
503 prout("***Shields knocked out.");
504 game.damage[DSHIELD] += 0.005*damfac*Rand()*diff;
507 else energy -= 2000.0;
512 /* add in course nova contributes to kicking starship*/
513 icx += sectx-hits[mm][1];
514 icy += secty-hits[mm][2];
517 case IHK: /* kill klingon */
518 deadkl(ii,jj,iquad, ii, jj);
520 case IHC: /* Damage/destroy big enemies */
523 for (ll = 1; ll <= nenhere; ll++)
524 if (game.kx[ll]==ii && game.ky[ll]==jj) break;
525 game.kpower[ll] -= 800.0; /* If firepower is lost, die */
526 if (game.kpower[ll] <= 0.0) {
527 deadkl(ii, jj, iquad, ii, jj);
530 newcx = ii + ii - hits[mm][1];
531 newcy = jj + jj - hits[mm][2];
532 crmena(1, iquad, 2, ii, jj);
534 if (newcx<1 || newcx>10 || newcy<1 || newcy>10) {
535 /* can't leave quadrant */
539 iquad1 = game.quad[newcx][newcy];
540 if (iquad1 == IHBLANK) {
541 proutn(", blasted into ");
542 crmena(0, IHBLANK, 2, newcx, newcy);
544 deadkl(ii, jj, iquad, newcx, newcy);
547 if (iquad1 != IHDOT) {
548 /* can't move into something else */
552 proutn(", buffeted to ");
553 proutn(cramlc(sector, newcx, newcy));
554 game.quad[ii][jj] = IHDOT;
555 game.quad[newcx][newcy] = iquad;
558 game.kavgd[ll] = sqrt(square(sectx-newcx)+square(secty-newcy));
559 game.kdist[ll] = game.kavgd[ll];
564 if (top == top2) break;
568 if (kount==0) return;
570 /* Starship affected by nova -- kick it away. */
572 if (icx) icx = (icx < 0 ? -1 : 1);
573 if (icy) icy = (icy < 0 ? -1 : 1);
574 direc = course[3*(icx+1)+icy+2];
575 if (direc == 0.0) dist = 0.0;
576 if (dist == 0.0) return;
577 Time = 10.0*dist/16.0;
579 prout("Force of nova displaces starship.");
580 iattak=2; /* Eliminates recursion problem */
582 Time = 10.0*dist/16.0;
587 void snova(int insx, int insy) {
588 int comdead, nqx=0, nqy=0, nsx, nsy, num, kldead, iscdead;
597 /* NOVAMAX being used */
603 /* Scheduled supernova -- select star */
604 /* logic changed here so that we won't favor quadrants in top
606 for (nqx = 1; nqx<=8; nqx++) {
607 for (nqy = 1; nqy<=8; nqy++) {
608 stars += game.state.galaxy[nqx][nqy] % 10;
611 if (stars == 0) return; /* nothing to supernova exists */
612 num = Rand()*stars + 1;
613 for (nqx = 1; nqx<=8; nqx++) {
614 for (nqy = 1; nqy<=8; nqy++) {
615 num -= game.state.galaxy[nqx][nqy] % 10;
622 proutn("Super nova here?");
631 if (nqx != quady || nqy != quady || justin != 0) {
632 /* it isn't here, or we just entered (treat as inroute) */
633 if (game.damage[DRADIO] == 0.0 || condit == IHDOCKED) {
635 prout("Message from Starfleet Command Stardate %.2f", game.state.date);
636 prout(" Supernova in %s; caution advised.",
637 cramlc(quadrant, nqx, nqy));
641 /* we are in the quadrant! */
643 num = Rand()* (game.state.galaxy[nqx][nqy]%10) + 1;
644 for (nsx=1; nsx < 10; nsx++) {
645 for (nsy=1; nsy < 10; nsy++) {
646 if (game.quad[nsx][nsy]==IHSTAR) {
661 prouts("***RED ALERT! RED ALERT!");
663 prout("***Incipient supernova detected at ", cramlc(sector, nsx, nsy));
666 if (square(nsx-sectx) + square(nsy-secty) <= 2.1) {
667 proutn("Emergency override attempts t");
668 prouts("***************");
674 /* destroy any Klingons in supernovaed quadrant */
675 num=game.state.galaxy[nqx][nqy];
677 comdead = iscdead = 0;
678 if (nqx==game.state.isx && nqy == game.state.isy) {
679 /* did in the Supercommander! */
680 game.state.nscrem = game.state.isx = game.state.isy = isatb = iscate = 0;
682 game.future[FSCMOVE] = game.future[FSCDBAS] = 1e30;
684 game.state.remkl -= kldead;
685 if (game.state.remcom) {
686 int maxloop = game.state.remcom, l;
687 for (l = 1; l <= maxloop; l++) {
688 if (game.state.cx[l] == nqx && game.state.cy[l] == nqy) {
689 game.state.cx[l] = game.state.cx[game.state.remcom];
690 game.state.cy[l] = game.state.cy[game.state.remcom];
691 game.state.cx[game.state.remcom] = game.state.cy[game.state.remcom] = 0;
695 if (game.state.remcom==0) game.future[FTBEAM] = 1e30;
700 /* destroy Romulans and planets in supernovaed quadrant */
701 num = game.state.newstuf[nqx][nqy];
702 game.state.newstuf[nqx][nqy] = 0;
704 game.state.nromrem -= nrmdead;
705 npdead = num - nrmdead*10;
708 for (l = 0; l < inplan; l++)
709 if (game.state.plnets[l].x == nqx && game.state.plnets[l].y == nqy) {
710 DESTROY(&game.state.plnets[l]);
713 /* Destroy any base in supernovaed quadrant */
714 if (game.state.rembase) {
715 int maxloop = game.state.rembase, l;
716 for (l = 1; l <= maxloop; l++)
717 if (game.state.baseqx[l]==nqx && game.state.baseqy[l]==nqy) {
718 game.state.baseqx[l] = game.state.baseqx[game.state.rembase];
719 game.state.baseqy[l] = game.state.baseqy[game.state.rembase];
720 game.state.baseqx[game.state.rembase] = game.state.baseqy[game.state.rembase] = 0;
721 game.state.rembase--;
725 /* If starship caused supernova, tally up destruction */
727 num = game.state.galaxy[nqx][nqy] % 100;
728 game.state.starkl += num % 10;
729 game.state.basekl += num/10;
730 game.state.killk += kldead;
731 game.state.killc += comdead;
732 game.state.nromkl += nrmdead;
733 game.state.nplankl += npdead;
734 game.state.nsckill += iscdead;
736 /* mark supernova in galaxy and in star chart */
737 if ((quadx == nqx && quady == nqy) ||
738 game.damage[DRADIO] == 0 ||
740 game.starch[nqx][nqy] = 1;
741 game.state.galaxy[nqx][nqy] = 1000;
742 /* If supernova destroys last klingons give special message */
743 if (game.state.remkl==0 && (nqx != quadx || nqy != quady)) {
745 if (insx == 0) prout("Lucky you!");
746 proutn("A supernova in %s has just destroyed the last Klingons.",
747 cramlc(quadrant, nqx, nqy));
751 /* if some Klingons remain, continue or die in supernova */
752 if (alldone) finish(FSNOVAED);