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;
10 if (idebug) prout("EVENTS");
13 if (stdamtim == 1e30 && game.damage[DRADIO] != 0.0) {
14 /* chart will no longer be updated because radio is dead */
15 stdamtim = game.state.date;
16 for (i=1; i <= GALSIZE ; i++)
17 for (j=1; j <= GALSIZE; j++)
18 if (game.starch[i][j] == 1)
19 game.starch[i][j] = game.state.galaxy[i][j]+SUPERNOVA_PLACE;
23 /* Select earliest extraneous event, line==0 if no events */
27 for (l=1; l<=NEVENTS; l++)
28 if (game.future[l] < datemin) {
30 datemin = game.future[l];
32 xtime = datemin-game.state.date;
33 game.state.date = datemin;
34 /* Decrement Federation resources and recompute remaining time */
35 game.state.remres -= (game.state.remkl+4*game.state.remcom)*xtime;
36 game.state.remtime = game.state.remres/(game.state.remkl+4*game.state.remcom);
37 if (game.state.remtime <=0) {
41 /* Is life support adequate? */
42 if (game.damage[DLIFSUP] && condit != IHDOCKED) {
43 if (lsupres < xtime && game.damage[DLIFSUP] > lsupres) {
48 if (game.damage[DLIFSUP] <= xtime) lsupres = inlsr;
52 if (condit == IHDOCKED) repair /= docfac;
53 /* Don't fix Deathray here */
54 for (l=1; l<=NDEVICES; l++)
55 if (game.damage[l] > 0.0 && l != DDRAY)
56 game.damage[l] -= (game.damage[l]-repair > 0.0 ? repair : game.damage[l]);
57 /* If radio repaired, update star chart and attack reports */
58 if (stdamtim != 1e30 && game.damage[DRADIO] == 0.0) {
60 prout("Lt. Uhura- \"Captain, the sub-space radio is working and");
61 prout(" surveillance reports are coming in.");
63 for (i=1; i <= GALSIZE ; i++)
64 for (j=1; j <= GALSIZE; j++)
65 if (game.starch[i][j] >= SUPERNOVA_PLACE) game.starch[i][j] = 1;
71 prout(" The star chart is now up to date.\"");
74 /* Cause extraneous event LINE to occur */
77 case FSNOVA: /* Supernova */
78 if (ipage==0) pause_game(1);
81 game.future[FSNOVA] = game.state.date + expran(0.5*intime);
82 if (game.state.galaxy[quadx][quady] == SUPERNOVA_PLACE) return;
84 case FSPY: /* Check with spy to see if S.C. should tractor beam */
85 if (game.state.nscrem == 0 ||
86 ictbeam+istract > 0 ||
87 condit==IHDOCKED || isatb==1 || iscate==1) return;
89 (energy < 2000 && torps < 4 && shield < 1250) ||
90 (game.damage[DPHASER]>0 && (game.damage[DPHOTON]>0 || torps < 4)) ||
91 (game.damage[DSHIELD] > 0 &&
92 (energy < 2500 || game.damage[DPHASER] > 0) &&
93 (torps < 5 || game.damage[DPHOTON] > 0))) {
94 /* Tractor-beam her! */
96 yank = square(game.state.isx-quadx) + square(game.state.isy-quady);
97 /********* fall through to FTBEAM code ***********/
100 case FTBEAM: /* Tractor beam */
102 if (game.state.remcom == 0) {
103 game.future[FTBEAM] = 1e30;
106 i = Rand()*game.state.remcom+1.0;
107 yank = square(game.state.cx[i]-quadx) + square(game.state.cy[i]-quady);
108 if (istract || condit == IHDOCKED || yank == 0) {
109 /* Drats! Have to reschedule */
110 game.future[FTBEAM] = game.state.date + Time +
111 expran(1.5*intime/game.state.remcom);
115 /* tractor beaming cases merge here */
117 if (ipage==0) pause_game(1);
119 Time = (10.0/(7.5*7.5))*yank; /* 7.5 is yank rate (warp 7.5) */
124 prout(" caught in long range tractor beam--");
125 /* If Kirk & Co. screwing around on planet, handle */
126 atover(1); /* atover(1) is Grab */
128 if (icraft == 1) { /* Caught in Galileo? */
132 /* Check to see if shuttle is aboard */
136 prout("Galileo, left on the planet surface, is captured");
137 prout("by aliens and made into a flying McDonald's.");
138 game.damage[DSHUTTL] = -10;
142 prout("Galileo, left on the planet surface, is well hidden.");
146 quadx = game.state.isx;
147 quady = game.state.isy;
150 quadx = game.state.cx[i];
151 quady = game.state.cy[i];
153 iran(QUADSIZE, §x, §y);
155 proutn(" is pulled to ");
156 proutn(cramlc(quadrant, quadx, quady));
158 prout(cramlc(sector, sectx, secty));
160 prout("(Remainder of rest/repair period cancelled.)");
164 if (game.damage[DSHIELD]==0 && shield > 0) {
165 doshield(2); /* Shldsup */
168 else prout("(Shields not currently useable.)");
171 /* Adjust finish time to time of tractor beaming */
172 fintim = game.state.date+Time;
174 if (game.state.remcom <= 0) game.future[FTBEAM] = 1e30;
175 else game.future[FTBEAM] = game.state.date+Time+expran(1.5*intime/game.state.remcom);
177 case FSNAP: /* Snapshot of the universe (for time warp) */
178 game.snapsht = game.state;
180 game.future[FSNAP] = game.state.date + expran(0.5 * intime);
182 case FBATTAK: /* Commander attacks starbase */
183 if (game.state.remcom==0 || game.state.rembase==0) {
185 game.future[FBATTAK] = game.future[FCDBAS] = 1e30;
189 for (j=1; j<=game.state.rembase; j++) {
190 for (k=1; k<=game.state.remcom; k++)
191 if (game.state.baseqx[j]==game.state.cx[k] && game.state.baseqy[j]==game.state.cy[k] &&
192 (game.state.baseqx[j]!=quadx || game.state.baseqy[j]!=quady) &&
193 (game.state.baseqx[j]!=game.state.isx || game.state.baseqy[j]!=game.state.isy)) {
199 if (j>game.state.rembase) {
200 /* no match found -- try later */
201 game.future[FBATTAK] = game.state.date + expran(0.3*intime);
202 game.future[FCDBAS] = 1e30;
205 /* commander + starbase combination found -- launch attack */
206 batx = game.state.baseqx[j];
207 baty = game.state.baseqy[j];
208 game.future[FCDBAS] = game.state.date+1.0+3.0*Rand();
209 if (isatb) /* extra time if SC already attacking */
210 game.future[FCDBAS] += game.future[FSCDBAS]-game.state.date;
211 game.future[FBATTAK] = game.future[FCDBAS] +expran(0.3*intime);
213 if (game.damage[DRADIO] != 0.0 &&
214 condit != IHDOCKED) break; /* No warning :-( */
216 if (ipage==0) pause_game(1);
219 proutn("Lt. Uhura- \"Captain, the starbase in ");
220 prout(cramlc(quadrant, batx, baty));
221 prout(" reports that it is under attack and that it can");
222 proutn(" hold out only until stardate %d",
223 (int)game.future[FCDBAS]);
227 proutn("Mr. Spock- \"Captain, shall we cancel the rest period?\" ");
235 case FSCDBAS: /* Supercommander destroys base */
236 game.future[FSCDBAS] = 1e30;
238 if (!BASES(game.state.galaxy[game.state.isx][game.state.isy]))
239 break; /* WAS RETURN! */
242 batx = game.state.isx;
243 baty = game.state.isy;
244 case FCDBAS: /* Commander succeeds in destroying base */
246 game.future[FCDBAS] = 1e30;
247 /* find the lucky pair */
248 for (i = 1; i <= game.state.remcom; i++)
249 if (game.state.cx[i]==batx && game.state.cy[i]==baty) break;
250 if (i > game.state.remcom || game.state.rembase == 0 ||
251 !BASES(game.state.galaxy[batx][baty])) {
252 /* No action to take after all */
257 /* Code merges here for any commander destroying base */
258 /* Not perfect, but will have to do */
259 if (game.starch[batx][baty] == -1) game.starch[batx][baty] = 0;
260 /* Handle case where base is in same quadrant as starship */
261 if (batx==quadx && baty==quady) {
262 if (game.starch[batx][baty] >= SUPERNOVA_PLACE) game.starch[batx][baty] -= BASE_PLACE;
263 game.quad[basex][basey]= IHDOT;
267 prout("Spock- \"Captain, I believe the starbase has been destroyegame.state.\"");
269 else if (game.state.rembase != 1 &&
270 (game.damage[DRADIO] <= 0.0 || condit == IHDOCKED)) {
271 /* Get word via subspace radio */
272 if (ipage==0) pause_game(1);
275 prout("Lt. Uhura- \"Captain, Starfleet Command reports that");
276 proutn(" the starbase in ");
277 proutn(cramlc(quadrant, batx, baty));
278 prout(" has been destroyed by");
279 if (isatb==2) prout("the Klingon Super-Commander");
280 else prout("a Klingon Commander");
282 /* Remove Starbase from galaxy */
283 game.state.galaxy[batx][baty] -= BASE_PLACE;
284 for (i=1; i <= game.state.rembase; i++)
285 if (game.state.baseqx[i]==batx && game.state.baseqy[i]==baty) {
286 game.state.baseqx[i]=game.state.baseqx[game.state.rembase];
287 game.state.baseqy[i]=game.state.baseqy[game.state.rembase];
289 game.state.rembase--;
291 /* reinstate a commander's base attack */
300 case FSCMOVE: /* Supercommander moves */
301 game.future[FSCMOVE] = game.state.date+0.2777;
302 if (ientesc+istract==0 &&
304 (iscate!=1 || justin==1)) scom(&ipage);
306 case FDSPROB: /* Move deep space probe */
307 game.future[FDSPROB] = game.state.date + 0.01;
310 i = (int)(probex/QUADSIZE +0.05);
311 j = (int)(probey/QUADSIZE + 0.05);
312 if (probecx != i || probecy != j) {
315 if (i < 1 || i > GALSIZE || j < 1 || j > GALSIZE ||
316 game.state.galaxy[probecx][probecy] == SUPERNOVA_PLACE) {
317 // Left galaxy or ran into supernova
318 if (game.damage[DRADIO]==0.0 || condit == IHDOCKED) {
319 if (ipage==0) pause_game(1);
322 proutn("Lt. Uhura- \"The deep space probe ");
323 if (i < 1 ||i > GALSIZE || j < 1 || j > GALSIZE)
324 proutn("has left the galaxy");
326 proutn("is no longer transmitting");
329 game.future[FDSPROB] = 1e30;
332 if (game.damage[DRADIO]==0.0 || condit == IHDOCKED) {
333 if (ipage==0) pause_game(1);
336 proutn("Lt. Uhura- \"The deep space probe is now in ");
337 proutn(cramlc(quadrant, probecx, probecy));
341 /* Update star chart if Radio is working or have access to
343 if (game.damage[DRADIO] == 0.0 || condit == IHDOCKED)
344 game.starch[probecx][probecy] = game.damage[DRADIO] > 0.0 ?
345 game.state.galaxy[probecx][probecy]+SUPERNOVA_PLACE : 1;
346 proben--; // One less to travel
347 if (proben == 0 && isarmed &&
348 STARS(game.state.galaxy[probecx][probecy])) {
349 /* lets blow the sucker! */
351 game.future[FDSPROB] = 1e30;
352 if (game.state.galaxy[quadx][quady] == SUPERNOVA_PLACE) return;
363 double temp, delay, origTime;
368 if (key != IHEOL) break;
369 proutn("How long? ");
376 origTime = delay = aaitem;
377 if (delay <= 0.0) return;
378 if (delay >= game.state.remtime || nenhere != 0) {
379 proutn("Are you sure? ");
380 if (ja() == 0) return;
383 /* Alternate resting periods (events) with attacks */
387 if (delay <= 0) resting = 0;
389 prout("%d stardates left.", (int)game.state.remtime);
395 double rtime = 1.0 + Rand();
396 if (rtime < temp) temp = rtime;
399 if (Time < delay) attack(0);
405 /* Repair Deathray if long rest at starbase */
406 if (origTime-delay >= 9.99 && condit == IHDOCKED)
407 game.damage[DDRAY] = 0.0;
409 (game.state.galaxy[quadx][quady] != SUPERNOVA_PLACE); // leave if quadrant supernovas
415 void nova(int ix, int iy)
417 static double course[] =
418 {0.0, 10.5, 12.0, 1.5, 9.0, 0.0, 3.0, 7.5, 6.0, 4.5};
419 int bot, top, top2, hits[QUADSIZE+1][3], kount, icx, icy, mm, nn, j;
420 int iquad, iquad1, i, ll, newcx, newcy, ii, jj;
422 /* Wow! We've supernova'ed */
427 /* handle initial nova */
428 game.quad[ix][iy] = IHDOT;
429 crmena(1, IHSTAR, 2, ix, iy);
431 game.state.galaxy[quadx][quady] -= 1;
434 /* Set up stack to recursively trigger adjacent stars */
435 bot = top = top2 = 1;
441 for (mm = bot; mm <= top; mm++)
442 for (nn = 1; nn <= 3; nn++) /* nn,j represents coordinates around current */
443 for (j = 1; j <= 3; j++) {
444 if (j==2 && nn== 2) continue;
445 ii = hits[mm][1]+nn-2;
446 jj = hits[mm][2]+j-2;
447 if (ii < 1 || ii > QUADSIZE || jj < 1 || jj > QUADSIZE) continue;
448 iquad = game.quad[ii][jj];
450 // case IHDOT: /* Empty space ends reaction
457 case IHSTAR: /* Affect another star */
459 /* This star supernovas */
466 game.state.galaxy[quadx][quady] -= 1;
468 crmena(1, IHSTAR, 2, ii, jj);
470 game.quad[ii][jj] = IHDOT;
472 case IHP: /* Destroy planet */
473 game.state.newstuf[quadx][quady] -= 1;
474 game.state.nplankl++;
475 crmena(1, IHP, 2, ii, jj);
476 prout(" destroyed.");
477 DESTROY(&game.state.plnets[iplnet]);
478 iplnet = plnetx = plnety = 0;
483 game.quad[ii][jj] = IHDOT;
485 case IHB: /* Destroy base */
486 game.state.galaxy[quadx][quady] -= BASE_PLACE;
487 for (i = 1; i <= game.state.rembase; i++)
488 if (game.state.baseqx[i]==quadx && game.state.baseqy[i]==quady) break;
489 game.state.baseqx[i] = game.state.baseqx[game.state.rembase];
490 game.state.baseqy[i] = game.state.baseqy[game.state.rembase];
491 game.state.rembase--;
495 crmena(1, IHB, 2, ii, jj);
496 prout(" destroyed.");
497 game.quad[ii][jj] = IHDOT;
499 case IHE: /* Buffet ship */
501 prout("***Starship buffeted by nova.");
503 if (shield >= 2000.0) shield -= 2000.0;
505 double diff = 2000.0 - shield;
509 prout("***Shields knocked out.");
510 game.damage[DSHIELD] += 0.005*damfac*Rand()*diff;
513 else energy -= 2000.0;
518 /* add in course nova contributes to kicking starship*/
519 icx += sectx-hits[mm][1];
520 icy += secty-hits[mm][2];
523 case IHK: /* kill klingon */
524 deadkl(ii,jj,iquad, ii, jj);
526 case IHC: /* Damage/destroy big enemies */
529 for (ll = 1; ll <= nenhere; ll++)
530 if (game.kx[ll]==ii && game.ky[ll]==jj) break;
531 game.kpower[ll] -= 800.0; /* If firepower is lost, die */
532 if (game.kpower[ll] <= 0.0) {
533 deadkl(ii, jj, iquad, ii, jj);
536 newcx = ii + ii - hits[mm][1];
537 newcy = jj + jj - hits[mm][2];
538 crmena(1, iquad, 2, ii, jj);
540 if (newcx<1 || newcx>QUADSIZE || newcy<1 || newcy>QUADSIZE) {
541 /* can't leave quadrant */
545 iquad1 = game.quad[newcx][newcy];
546 if (iquad1 == IHBLANK) {
547 proutn(", blasted into ");
548 crmena(0, IHBLANK, 2, newcx, newcy);
550 deadkl(ii, jj, iquad, newcx, newcy);
553 if (iquad1 != IHDOT) {
554 /* can't move into something else */
558 proutn(", buffeted to ");
559 proutn(cramlc(sector, newcx, newcy));
560 game.quad[ii][jj] = IHDOT;
561 game.quad[newcx][newcy] = iquad;
564 game.kavgd[ll] = sqrt(square(sectx-newcx)+square(secty-newcy));
565 game.kdist[ll] = game.kavgd[ll];
578 /* Starship affected by nova -- kick it away. */
580 if (icx) icx = (icx < 0 ? -1 : 1);
581 if (icy) icy = (icy < 0 ? -1 : 1);
582 direc = course[3*(icx+1)+icy+2];
583 if (direc == 0.0) dist = 0.0;
584 if (dist == 0.0) return;
585 Time = 10.0*dist/16.0;
587 prout("Force of nova displaces starship.");
588 iattak=2; /* Eliminates recursion problem */
590 Time = 10.0*dist/16.0;
595 void snova(int insx, int insy)
597 int comdead, nqx=0, nqy=0, nsx, nsy, num, kldead, iscdead;
606 /* NOVAMAX being used */
612 /* Scheduled supernova -- select star */
613 /* logic changed here so that we won't favor quadrants in top
615 for (nqx = 1; nqx<=GALSIZE; nqx++) {
616 for (nqy = 1; nqy<=GALSIZE; nqy++) {
617 stars += STARS(game.state.galaxy[nqx][nqy]);
620 if (stars == 0) return; /* nothing to supernova exists */
621 num = Rand()*stars + 1;
622 for (nqx = 1; nqx<=GALSIZE; nqx++) {
623 for (nqy = 1; nqy<=GALSIZE; nqy++) {
624 num -= STARS(game.state.galaxy[nqx][nqy]);
631 proutn("Super nova here?");
640 if (nqx != quady || nqy != quady || justin != 0) {
641 /* it isn't here, or we just entered (treat as inroute) */
642 if (game.damage[DRADIO] == 0.0 || condit == IHDOCKED) {
644 prout("Message from Starfleet Command Stardate %.2f", game.state.date);
645 prout(" Supernova in %s; caution advised.",
646 cramlc(quadrant, nqx, nqy));
650 /* we are in the quadrant! */
652 num = Rand()* STARS(game.state.galaxy[nqx][nqy]) + 1;
653 for (nsx=1; nsx < QUADSIZE; nsx++) {
654 for (nsy=1; nsy < QUADSIZE; nsy++) {
655 if (game.quad[nsx][nsy]==IHSTAR) {
670 prouts("***RED ALERT! RED ALERT!");
672 prout("***Incipient supernova detected at ", cramlc(sector, nsx, nsy));
675 if (square(nsx-sectx) + square(nsy-secty) <= 2.1) {
676 proutn("Emergency override attempts t");
677 prouts("***************");
683 /* destroy any Klingons in supernovaed quadrant */
684 num=game.state.galaxy[nqx][nqy];
686 comdead = iscdead = 0;
687 if (nqx==game.state.isx && nqy == game.state.isy) {
688 /* did in the Supercommander! */
689 game.state.nscrem = game.state.isx = game.state.isy = isatb = iscate = 0;
691 game.future[FSCMOVE] = game.future[FSCDBAS] = 1e30;
693 game.state.remkl -= kldead;
694 if (game.state.remcom) {
695 int maxloop = game.state.remcom, l;
696 for (l = 1; l <= maxloop; l++) {
697 if (game.state.cx[l] == nqx && game.state.cy[l] == nqy) {
698 game.state.cx[l] = game.state.cx[game.state.remcom];
699 game.state.cy[l] = game.state.cy[game.state.remcom];
700 game.state.cx[game.state.remcom] = game.state.cy[game.state.remcom] = 0;
704 if (game.state.remcom==0) game.future[FTBEAM] = 1e30;
709 /* destroy Romulans and planets in supernovaed quadrant */
710 num = game.state.newstuf[nqx][nqy];
711 game.state.newstuf[nqx][nqy] = 0;
713 game.state.nromrem -= nrmdead;
714 npdead = num - nrmdead*10;
717 for (l = 0; l < inplan; l++)
718 if (game.state.plnets[l].x == nqx && game.state.plnets[l].y == nqy) {
719 DESTROY(&game.state.plnets[l]);
722 /* Destroy any base in supernovaed quadrant */
723 if (game.state.rembase) {
724 int maxloop = game.state.rembase, l;
725 for (l = 1; l <= maxloop; l++)
726 if (game.state.baseqx[l]==nqx && game.state.baseqy[l]==nqy) {
727 game.state.baseqx[l] = game.state.baseqx[game.state.rembase];
728 game.state.baseqy[l] = game.state.baseqy[game.state.rembase];
729 game.state.baseqx[game.state.rembase] = game.state.baseqy[game.state.rembase] = 0;
730 game.state.rembase--;
734 /* If starship caused supernova, tally up destruction */
736 num = game.state.galaxy[nqx][nqy] % 100;
737 game.state.starkl += num % 10;
738 game.state.basekl += num/10;
739 game.state.killk += kldead;
740 game.state.killc += comdead;
741 game.state.nromkl += nrmdead;
742 game.state.nplankl += npdead;
743 game.state.nsckill += iscdead;
745 /* mark supernova in galaxy and in star chart */
746 if ((quadx == nqx && quady == nqy) ||
747 game.damage[DRADIO] == 0 ||
749 game.starch[nqx][nqy] = 1;
750 game.state.galaxy[nqx][nqy] = SUPERNOVA_PLACE;
751 /* If supernova destroys last klingons give special message */
752 if (game.state.remkl==0 && (nqx != quadx || nqy != quady)) {
754 if (insx == 0) prout("Lucky you!");
755 proutn("A supernova in %s has just destroyed the last Klingons.",
756 cramlc(quadrant, nqx, nqy));
760 /* if some Klingons remain, continue or die in supernova */
761 if (alldone) finish(FSNOVAED);