From: Eric S. Raymond Date: Mon, 7 Feb 2005 13:10:54 +0000 (+0000) Subject: Rewrite to get ride of FORTRANish galaxy and newstuff arrays. It's X-Git-Tag: 2.0~341 X-Git-Url: https://jxself.org/git/?p=super-star-trek.git;a=commitdiff_plain;h=e536fe754b3a9be00dcaee8f6ec50ea2d8c7a184 Rewrite to get ride of FORTRANish galaxy and newstuff arrays. It's all one C structure array now. Also back out "Bases left" report. --- diff --git a/TODO b/TODO index dc76924..d546f6a 100644 --- a/TODO +++ b/TODO @@ -7,4 +7,6 @@ * Code to hurl you out of quadrant if a supernova occurs as you warp in seems to hang. -* Regenerate Thingy at random location when unfreezing a game. +* "Bases left" report doesn't look right in the -t version. + +* Orbit height is negative. diff --git a/ai.c b/ai.c index e766e98..c6a862e 100644 --- a/ai.c +++ b/ai.c @@ -7,7 +7,8 @@ static int tryexit(int lookx, int looky, int ienm, int loccom, int irun) iqx = quadx+(lookx+(QUADSIZE-1))/QUADSIZE - 1; iqy = quady+(looky+(QUADSIZE-1))/QUADSIZE - 1; if (iqx < 1 || iqx > GALSIZE || iqy < 1 || iqy > GALSIZE || - NOEXIT(game.state.galaxy[iqx][iqy])) + game.state.galaxy[iqx][iqy].supernova || + game.state.galaxy[iqx][iqy].klingons > 8) return 0; /* no can do -- neg energy, supernovae, or >8 Klingons */ if (ienm == IHR) return 0; /* Romulans cannot escape! */ if (irun == 0) { @@ -40,8 +41,8 @@ static int tryexit(int lookx, int looky, int ienm, int loccom, int irun) nenhere--; if (condit != IHDOCKED) newcnd(); /* Handle global matters related to escape */ - game.state.galaxy[quadx][quady] -= KLINGON_PLACE; - game.state.galaxy[iqx][iqy] += KLINGON_PLACE; + game.state.galaxy[quadx][quady].klingons--; + game.state.galaxy[iqx][iqy].klingons++; if (ienm==IHS) { ishere=0; iscate=0; @@ -307,7 +308,9 @@ static int movescom(int iqx, int iqy, int flag, int *ipage) if ((iqx==quadx && iqy==quady) || iqx < 1 || iqx > GALSIZE || iqy < 1 || iqy > GALSIZE || - NOEXIT(game.state.galaxy[iqx][iqy])) return 1; + game.state.galaxy[iqx][iqy].supernova || + game.state.galaxy[iqx][iqy].klingons > 8) + return 1; if (flag) { /* Avoid quadrants with bases if we want to avoid Enterprise */ for (i = 1; i <= game.state.rembase; i++) @@ -315,10 +318,10 @@ static int movescom(int iqx, int iqy, int flag, int *ipage) } if (justin && !iscate) return 1; /* do the move */ - game.state.galaxy[game.state.isx][game.state.isy] -= KLINGON_PLACE; + game.state.galaxy[game.state.isx][game.state.isy].klingons--; game.state.isx = iqx; game.state.isy = iqy; - game.state.galaxy[game.state.isx][game.state.isy] += KLINGON_PLACE; + game.state.galaxy[game.state.isx][game.state.isy].klingons++; if (ishere) { /* SC has scooted, Remove him from current quadrant */ iscate=0; @@ -345,7 +348,7 @@ static int movescom(int iqx, int iqy, int flag, int *ipage) game.state.plnets[i].crystals == 1) { /* destroy the planet */ DESTROY(&game.state.plnets[i]); - game.state.newstuf[game.state.isx][game.state.isy] -= 1; + game.state.galaxy[game.state.isx][game.state.isy].planets -= 1; if (game.damage[DRADIO] == 0.0 || condit == IHDOCKED) { if (*ipage==0) pause_game(1); *ipage = 1; @@ -428,7 +431,9 @@ void scom(int *ipage) ibqy = game.state.baseqy[i]; if ((ibqx == quadx && ibqy == quady) || (ibqx == batx && ibqy == baty) || - NOEXIT(game.state.galaxy[ibqx][ibqy])) continue; + game.state.galaxy[ibqx][ibqy].supernova || + game.state.galaxy[ibqx][ibqy].klingons > 8) + continue; /* if there is a commander, an no other base is appropriate, we will take the one with the commander */ for (j = 1; j <= game.state.remcom; j++) { @@ -530,7 +535,7 @@ void scom(int *ipage) #endif (Rand() > 0.2 || (game.damage[DRADIO] > 0.0 && condit != IHDOCKED) || - game.starch[game.state.isx][game.state.isy] > 0)) + !game.state.galaxy[game.state.isx][game.state.isy].charted)) return; if (*ipage==0) pause_game(1); *ipage = 1; diff --git a/battle.c b/battle.c index 75ac190..5356e3d 100644 --- a/battle.c +++ b/battle.c @@ -300,7 +300,6 @@ void torpedo(double course, double r, int inx, int iny, double *hit, int wait, i case IHB: /* Hit a base */ skip(1); prout("***STARBASE DESTROYED.."); - if (game.starch[quadx][quady] < 0) game.starch[quadx][quady] = 0; for (ll=1; ll<=game.state.rembase; ll++) { if (game.state.baseqx[ll]==quadx && game.state.baseqy[ll]==quady) { game.state.baseqx[ll]=game.state.baseqx[game.state.rembase]; @@ -311,7 +310,8 @@ void torpedo(double course, double r, int inx, int iny, double *hit, int wait, i game.quad[ix][iy]=IHDOT; game.state.rembase--; basex=basey=0; - game.state.galaxy[quadx][quady] -= BASE_PLACE; + game.state.galaxy[quadx][quady].starbase--; + game.state.chart[quadx][quady].starbase--; game.state.basekl++; newcnd(); return; @@ -319,7 +319,7 @@ void torpedo(double course, double r, int inx, int iny, double *hit, int wait, i crmena(1, iquad, 2, ix, iy); prout(" destroyed."); game.state.nplankl++; - game.state.newstuf[quadx][quady] -= 1; + game.state.galaxy[quadx][quady].planets--; DESTROY(&game.state.plnets[iplnet]); iplnet = 0; plnetx = plnety = 0; @@ -520,9 +520,10 @@ void attack(int torps_ok) r = (Rand()+Rand())*0.5 -0.5; r += 0.002*game.kpower[l]*r; torpedo(course, r, jx, jy, &hit, 0, 1, 1); - if (game.state.remkl==0) finish(FWON); /* Klingons did themselves in! */ - if (game.state.galaxy[quadx][quady] == SUPERNOVA_PLACE || - alldone) return; /* Supernova or finished */ + if (game.state.remkl==0) + finish(FWON); /* Klingons did themselves in! */ + if (game.state.galaxy[quadx][quady].supernova || alldone) + return; /* Supernova or finished */ if (hit == 0) continue; } if (shldup != 0 || shldchg != 0 || condit==IHDOCKED) { @@ -612,7 +613,7 @@ void deadkl(int ix, int iy, int type, int ixx, int iyy) /* Decide what kind of enemy it is and update approriately */ if (type == IHR) { /* chalk up a Romulan */ - game.state.newstuf[quadx][quady] -= ROMULAN_PLACE; + game.state.galaxy[quadx][quady].romulans--; irhere--; game.state.nromkl++; game.state.nromrem--; @@ -627,7 +628,7 @@ void deadkl(int ix, int iy, int type, int ixx, int iyy) } else { /* Some type of a Klingon */ - game.state.galaxy[quadx][quady] -= KLINGON_PLACE; + game.state.galaxy[quadx][quady].klingons--; klhere--; game.state.remkl--; switch (type) { @@ -828,7 +829,7 @@ void photon(void) if (shldup || condit == IHDOCKED) r *= 1.0 + 0.0001*shield; torpedo(course[i], r, sectx, secty, &dummy, 0, i, n); - if (alldone||game.state.galaxy[quadx][quady]==SUPERNOVA_PLACE) + if (alldone || game.state.galaxy[quadx][quady].supernova) return; } if (game.state.remkl==0) finish(FWON); diff --git a/events.c b/events.c index 5b75fae..55cc816 100644 --- a/events.c +++ b/events.c @@ -5,19 +5,13 @@ void events(void) { int ictbeam=0, ipage=0, istract=0, line, i=0, j, k, l, ixhold=0, iyhold=0; double fintim = game.state.date + Time, datemin, xtime, repair, yank=0; + int radio_was_broken; #ifdef DEBUG if (idebug) prout("EVENTS"); #endif - if (stdamtim == 1e30 && game.damage[DRADIO] != 0.0) { - /* chart will no longer be updated because radio is dead */ - stdamtim = game.state.date; - for (i=1; i <= GALSIZE ; i++) - for (j=1; j <= GALSIZE; j++) - if (game.starch[i][j] == 1) - game.starch[i][j] = game.state.galaxy[i][j]+SUPERNOVA_PLACE; - } + radio_was_broken = (game.damage[DRADIO] != 0.0); for (;;) { /* Select earliest extraneous event, line==0 if no events */ @@ -55,19 +49,16 @@ void events(void) if (game.damage[l] > 0.0 && l != DDRAY) game.damage[l] -= (game.damage[l]-repair > 0.0 ? repair : game.damage[l]); /* If radio repaired, update star chart and attack reports */ - if (stdamtim != 1e30 && game.damage[DRADIO] == 0.0) { + if (radio_was_broken && game.damage[DRADIO] == 0.0) { stdamtim = 1e30; prout("Lt. Uhura- \"Captain, the sub-space radio is working and"); prout(" surveillance reports are coming in."); skip(1); - for (i=1; i <= GALSIZE ; i++) - for (j=1; j <= GALSIZE; j++) - if (game.starch[i][j] >= SUPERNOVA_PLACE) game.starch[i][j] = 1; if (iseenit==0) { attakreport(0); iseenit = 1; } - skip(1); + rechart(); prout(" The star chart is now up to date.\""); skip(1); } @@ -79,7 +70,7 @@ void events(void) ipage=1; snova(0,0); game.future[FSNOVA] = game.state.date + expran(0.5*intime); - if (game.state.galaxy[quadx][quady] == SUPERNOVA_PLACE) return; + if (game.state.galaxy[quadx][quady].supernova) return; break; case FSPY: /* Check with spy to see if S.C. should tractor beam */ if (game.state.nscrem == 0 || @@ -235,7 +226,7 @@ void events(void) case FSCDBAS: /* Supercommander destroys base */ game.future[FSCDBAS] = 1e30; isatb = 2; - if (!BASES(game.state.galaxy[game.state.isx][game.state.isy])) + if (!game.state.galaxy[game.state.isx][game.state.isy].starbase) break; /* WAS RETURN! */ ixhold = batx; iyhold = baty; @@ -246,9 +237,10 @@ void events(void) game.future[FCDBAS] = 1e30; /* find the lucky pair */ for (i = 1; i <= game.state.remcom; i++) - if (game.state.cx[i]==batx && game.state.cy[i]==baty) break; + if (game.state.cx[i]==batx && game.state.cy[i]==baty) + break; if (i > game.state.remcom || game.state.rembase == 0 || - !BASES(game.state.galaxy[batx][baty])) { + !game.state.galaxy[batx][baty].starbase) { /* No action to take after all */ batx = baty = 0; break; @@ -256,10 +248,9 @@ void events(void) } /* Code merges here for any commander destroying base */ /* Not perfect, but will have to do */ - if (game.starch[batx][baty] == -1) game.starch[batx][baty] = 0; /* Handle case where base is in same quadrant as starship */ if (batx==quadx && baty==quady) { - if (game.starch[batx][baty] >= SUPERNOVA_PLACE) game.starch[batx][baty] -= BASE_PLACE; + game.state.chart[batx][baty].starbase = FALSE; game.quad[basex][basey]= IHDOT; basex=basey=0; newcnd(); @@ -278,9 +269,10 @@ void events(void) prout(" has been destroyed by"); if (isatb==2) prout("the Klingon Super-Commander"); else prout("a Klingon Commander"); + game.state.chart[batx][baty].starbase = FALSE; } /* Remove Starbase from galaxy */ - game.state.galaxy[batx][baty] -= BASE_PLACE; + game.state.galaxy[batx][baty].starbase = FALSE; for (i=1; i <= game.state.rembase; i++) if (game.state.baseqx[i]==batx && game.state.baseqy[i]==baty) { game.state.baseqx[i]=game.state.baseqx[game.state.rembase]; @@ -313,7 +305,7 @@ void events(void) probecx = i; probecy = j; if (i < 1 || i > GALSIZE || j < 1 || j > GALSIZE || - game.state.galaxy[probecx][probecy] == SUPERNOVA_PLACE) { + game.state.galaxy[probecx][probecy].supernova) { // Left galaxy or ran into supernova if (game.damage[DRADIO]==0.0 || condit == IHDOCKED) { if (ipage==0) pause_game(1); @@ -340,16 +332,20 @@ void events(void) } /* Update star chart if Radio is working or have access to radio. */ - if (game.damage[DRADIO] == 0.0 || condit == IHDOCKED) - game.starch[probecx][probecy] = game.damage[DRADIO] > 0.0 ? - game.state.galaxy[probecx][probecy]+SUPERNOVA_PLACE : 1; + if (game.damage[DRADIO] == 0.0 || condit == IHDOCKED) { + game.state.chart[probecx][probecy].klingons = game.state.galaxy[probecx][probecy].klingons; + game.state.chart[probecx][probecy].starbase = game.state.galaxy[probecx][probecy].starbase; + game.state.chart[probecx][probecy].stars = game.state.galaxy[probecx][probecy].stars; + game.state.galaxy[probecx][probecy].charted = TRUE; + } proben--; // One less to travel if (proben == 0 && isarmed && - STARS(game.state.galaxy[probecx][probecy])) { + game.state.galaxy[probecx][probecy].stars) { /* lets blow the sucker! */ snova(1,0); game.future[FDSPROB] = 1e30; - if (game.state.galaxy[quadx][quady] == SUPERNOVA_PLACE) return; + if (game.state.galaxy[quadx][quady].supernova) + return; } break; } @@ -406,7 +402,8 @@ void wait(void) if (origTime-delay >= 9.99 && condit == IHDOCKED) game.damage[DDRAY] = 0.0; } while - (game.state.galaxy[quadx][quady] != SUPERNOVA_PLACE); // leave if quadrant supernovas + // leave if quadrant supernovas + (!game.state.galaxy[quadx][quady].supernova); resting = 0; Time = 0; @@ -428,7 +425,7 @@ void nova(int ix, int iy) game.quad[ix][iy] = IHDOT; crmena(1, IHSTAR, 2, ix, iy); prout(" novas."); - game.state.galaxy[quadx][quady] -= 1; + game.state.galaxy[quadx][quady].stars--; game.state.starkl++; /* Set up stack to recursively trigger adjacent stars */ @@ -463,14 +460,14 @@ void nova(int ix, int iy) top2++; hits[top2][1]=ii; hits[top2][2]=jj; - game.state.galaxy[quadx][quady] -= 1; + game.state.galaxy[quadx][quady].stars -= 1; game.state.starkl++; crmena(1, IHSTAR, 2, ii, jj); prout(" novas."); game.quad[ii][jj] = IHDOT; break; case IHP: /* Destroy planet */ - game.state.newstuf[quadx][quady] -= 1; + game.state.galaxy[quadx][quady].planets -= 1; game.state.nplankl++; crmena(1, IHP, 2, ii, jj); prout(" destroyed."); @@ -483,9 +480,10 @@ void nova(int ix, int iy) game.quad[ii][jj] = IHDOT; break; case IHB: /* Destroy base */ - game.state.galaxy[quadx][quady] -= BASE_PLACE; + game.state.galaxy[quadx][quady].starbase = FALSE; for (i = 1; i <= game.state.rembase; i++) - if (game.state.baseqx[i]==quadx && game.state.baseqy[i]==quady) break; + if (game.state.baseqx[i]==quadx && game.state.baseqy[i]==quady) + break; game.state.baseqx[i] = game.state.baseqx[game.state.rembase]; game.state.baseqy[i] = game.state.baseqy[game.state.rembase]; game.state.rembase--; @@ -594,7 +592,7 @@ void nova(int ix, int iy) void snova(int insx, int insy) { - int comdead, nqx=0, nqy=0, nsx, nsy, num, kldead, iscdead; + int comdead, nqx=0, nqy=0, nsx, nsy, num=0, kldead, iscdead; int nrmdead, npdead; int incipient=0; @@ -614,14 +612,14 @@ void snova(int insx, int insy) left of universe */ for (nqx = 1; nqx<=GALSIZE; nqx++) { for (nqy = 1; nqy<=GALSIZE; nqy++) { - stars += STARS(game.state.galaxy[nqx][nqy]); + stars += game.state.galaxy[nqx][nqy].stars; } } if (stars == 0) return; /* nothing to supernova exists */ num = Rand()*stars + 1; for (nqx = 1; nqx<=GALSIZE; nqx++) { for (nqy = 1; nqy<=GALSIZE; nqy++) { - num -= STARS(game.state.galaxy[nqx][nqy]); + num -= game.state.galaxy[nqx][nqy].stars; if (num <= 0) break; } if (num <=0) break; @@ -649,7 +647,7 @@ void snova(int insx, int insy) else { /* we are in the quadrant! */ incipient = 1; - num = Rand()* STARS(game.state.galaxy[nqx][nqy]) + 1; + num = Rand()* game.state.galaxy[nqx][nqy].stars + 1; for (nsx=1; nsx < QUADSIZE; nsx++) { for (nsy=1; nsy < QUADSIZE; nsy++) { if (game.quad[nsx][nsy]==IHSTAR) { @@ -681,8 +679,8 @@ void snova(int insx, int insy) } } /* destroy any Klingons in supernovaed quadrant */ - num=game.state.galaxy[nqx][nqy]; - kldead = num/100; + kldead = game.state.galaxy[nqx][nqy].klingons; + game.state.galaxy[nqx][nqy].klingons = 0; comdead = iscdead = 0; if (nqx==game.state.isx && nqy == game.state.isy) { /* did in the Supercommander! */ @@ -707,9 +705,8 @@ void snova(int insx, int insy) } } /* destroy Romulans and planets in supernovaed quadrant */ - num = game.state.newstuf[nqx][nqy]; - game.state.newstuf[nqx][nqy] = 0; - nrmdead = num/10; + nrmdead = game.state.galaxy[nqx][nqy].romulans; + game.state.galaxy[nqx][nqy].romulans = 0; game.state.nromrem -= nrmdead; npdead = num - nrmdead*10; if (npdead) { @@ -733,9 +730,8 @@ void snova(int insx, int insy) } /* If starship caused supernova, tally up destruction */ if (insx) { - num = game.state.galaxy[nqx][nqy] % 100; - game.state.starkl += num % 10; - game.state.basekl += num/10; + game.state.starkl += game.state.galaxy[nqx][nqy].stars; + game.state.basekl += game.state.galaxy[nqx][nqy].starbase; game.state.killk += kldead; game.state.killc += comdead; game.state.nromkl += nrmdead; @@ -746,8 +742,7 @@ void snova(int insx, int insy) if ((quadx == nqx && quady == nqy) || game.damage[DRADIO] == 0 || condit == IHDOCKED) - game.starch[nqx][nqy] = 1; - game.state.galaxy[nqx][nqy] = SUPERNOVA_PLACE; + game.state.galaxy[nqx][nqy].supernova = TRUE; /* If supernova destroys last klingons give special message */ if (game.state.remkl==0 && (nqx != quadx || nqy != quady)) { skip(2); diff --git a/io.c b/io.c index 5de0819..b3d2438 100644 --- a/io.c +++ b/io.c @@ -408,7 +408,7 @@ void makechart(void) void setpassword(void) { - if (!game.options & OPTION_CURSES) { + if (!(game.options & OPTION_CURSES)) { while (TRUE) { scan(); strcpy(game.passwd, citem); diff --git a/moving.c b/moving.c index f9b352b..2ba016a 100644 --- a/moving.c +++ b/moving.c @@ -58,7 +58,7 @@ void imove(void) * that attacks only happen if Klingons * are present and your skill is good. */ - if (skill > SKILL_GOOD && klhere > 0 && game.state.galaxy[quadx][quady] != SUPERNOVA_PLACE) + if (skill > SKILL_GOOD && klhere > 0 && !game.state.galaxy[quadx][quady].supernova) attack(0); if (alldone) return; } @@ -200,7 +200,7 @@ no_quad_change: game.kdist[l] = finald; } sortkl(); - if (game.state.galaxy[quadx][quady] != SUPERNOVA_PLACE && iattak == 0) + if (!game.state.galaxy[quadx][quady].supernova && iattak == 0) attack(0); for (l = 1 ; l <= nenhere; l++) game.kavgd[l] = game.kdist[l]; } @@ -264,7 +264,7 @@ static void getcd(int isprobe, int akey) { if (landed == 1 && !isprobe) { prout("Dummy! You can't leave standard orbit until you"); - proutn("are back abourt the "); + proutn("are back aboard the "); crmshp(); prout("."); chew(); @@ -730,8 +730,8 @@ void atover(int igrab) crmshp(); skip(1); prout("safely out of quadrant."); - game.starch[quadx][quady] = game.damage[DRADIO] > 0.0 ? game.state.galaxy[quadx][quady]+SUPERNOVA_PLACE:1; - + if (game.damage[DRADIO] == 0.0) + game.state.galaxy[quadx][quady].charted = TRUE; /* Try to use warp engines */ if (game.damage[DWARPEN]) { skip(1); @@ -759,14 +759,16 @@ void atover(int igrab) finish(FSNOVAED); return; } + } while /* Repeat if another snova */ - } while (game.state.galaxy[quadx][quady] == SUPERNOVA_PLACE); - if (game.state.remkl==0) finish(FWON); /* Snova killed remaining enemy. */ + (game.state.galaxy[quadx][quady].supernova); + if (game.state.remkl==0) + finish(FWON); /* Snova killed remaining enemy. */ } void timwrp() { - int l, ll, gotit; + int l, gotit; prout("***TIME WARP ENTERED."); if (game.state.snap && Rand() < 0.5) { /* Go back in time */ @@ -804,16 +806,11 @@ void timwrp() prout("Checkov- \"Security reports the Galileo has reappeared in the dock!\""); iscraft = 1; } - - /* Revert star chart to earlier era, if it was known then*/ - if (game.damage[DRADIO]==0.0 || stdamtim > game.state.date) { - for (l = 1; l <= GALSIZE; l++) - for (ll = 1; ll <= GALSIZE; ll++) - if (game.starch[l][ll] > 1) - game.starch[l][ll]=game.damage[DRADIO]>0.0 ? game.state.galaxy[l][ll]+SUPERNOVA_PLACE :1; - prout("Spock has reconstructed a correct star chart from memory"); - if (game.damage[DRADIO] > 0.0) stdamtim = game.state.date; - } + /* + * There used to be code to do the actual reconstrction here, + * but the starchart is now part of the snapshotted galaxy state. + */ + prout("Spock has reconstructed a correct star chart from memory"); } else { /* Go forward in time */ diff --git a/planets.c b/planets.c index 69ca327..057fb84 100644 --- a/planets.c +++ b/planets.c @@ -23,7 +23,7 @@ static int consumeTime(void) events(); /* Used to avoid if future[FSCMOVE] within time */ // future[FSNOVA] = asave; /*fails if game over, quadrant super-novas or we've moved to new quadrant*/ - if (alldone || game.state.galaxy[quadx][quady] == SUPERNOVA_PLACE || justin != 0) return 1; + if (alldone || game.state.galaxy[quadx][quady].supernova || justin != 0) return 1; return 0; } diff --git a/reports.c b/reports.c index de2ba1b..3f654cf 100644 --- a/reports.c +++ b/reports.c @@ -135,9 +135,15 @@ void lrscan(void) if (x == 0 || x > GALSIZE || y == 0 || y > GALSIZE) proutn(" -1"); else { - if (game.state.galaxy[x][y] 0 ? game.state.galaxy[x][y]+SUPERNOVA_PLACE : 1; + if (!game.damage[DRADIO]) + game.state.galaxy[x][y].charted = TRUE; + game.state.chart[x][y].klingons = game.state.galaxy[x][y].klingons; + game.state.chart[x][y].starbase = game.state.galaxy[x][y].starbase; + game.state.chart[x][y].stars = game.state.galaxy[x][y].stars; + if (game.state.galaxy[x][y].supernova) + proutn("***"); + else + proutn(" %-3d", game.state.chart[x][y].klingons*100 + game.state.chart[x][y].starbase * 10 + game.state.chart[x][y].stars); } } prout(" "); @@ -165,6 +171,20 @@ void dreprt(void) if (!jdam) prout("All devices functional."); } +void rechart(void) +/* update the chart in the Enterprise's computer from galaxy data */ +{ + int i, j; + stdamtim = game.state.date; + for (i=1; i <= GALSIZE ; i++) + for (j=1; j <= GALSIZE; j++) + if (game.state.galaxy[i][j].charted) { + game.state.chart[i][j].klingons = game.state.galaxy[i][j].klingons; + game.state.chart[i][j].starbase = game.state.galaxy[i][j].starbase; + game.state.chart[i][j].stars = game.state.galaxy[i][j].stars; + } +} + void chart(int nn) { int i,j; @@ -177,16 +197,15 @@ void chart(int nn) if (stdamtim != 1e30) { if (condit == IHDOCKED) { /* We are docked, so restore chart from base information */ - stdamtim = game.state.date; - for (i=1; i <= GALSIZE ; i++) - for (j=1; j <= GALSIZE; j++) - if (game.starch[i][j] == 1) game.starch[i][j] = game.state.galaxy[i][j]+SUPERNOVA_PLACE; + rechart(); } - else { - proutn("(Last surveillance update %d stardates ago.", + else if (game.state.date-stdamtim) { + prout("(Last surveillance update %d stardates ago).", (int)(game.state.date-stdamtim)); } } + else if (game.damage[DRADIO] == 0.0) + rechart(); prout(" 1 2 3 4 5 6 7 8"); for (i = 1; i <= GALSIZE; i++) { @@ -194,14 +213,14 @@ void chart(int nn) for (j = 1; j <= GALSIZE; j++) { char buf[4]; proutn(" "); - if (game.starch[i][j] == CHART_UNKNOWN) - strcpy(buf, ".1."); - else if (game.starch[i][j] == 0) - strcpy(buf, "..."); - else if (game.state.galaxy[i][j]>=SUPERNOVA_PLACE) + if (game.state.galaxy[i][j].supernova) strcpy(buf, "***"); + else if (!game.state.galaxy[i][j].charted && game.state.galaxy[i][j].starbase) + strcpy(buf, ".1."); + else if (game.state.galaxy[i][j].charted) + sprintf(buf, "%d%d%d", game.state.chart[i][j].klingons, game.state.chart[i][j].starbase, game.state.chart[i][j].stars); else - sprintf(buf, "%03d", game.state.galaxy[i][j]); + strcpy(buf, "..."); for (cp = buf; cp < buf + sizeof(buf); cp++) if (*cp == '0') *cp = '.'; @@ -301,23 +320,13 @@ static void status(int req) case 10: attakreport(1); break; - /* - * Note: attakreport() can in some cases produce two lines of - * output. If that happens, and QUADSIZE is the normal 10, items - * 11 and up will be printed past the bottom of the quadrant display. - * Under the curses display logic they will get lost because they're - * written outside the report window. - */ - case 11: /* ESR */ - proutn("Bases Left %d", game.state.rembase); - break; } } int srscan(int l) { static char requests[][3] = - {"","da","co","po","ls","wa","en","to","sh","kl","ti", "ba"}; + {"","da","co","po","ls","wa","en","to","sh","kl","ti"}; int leftside=TRUE, rightside=TRUE, i, j, jj, req=0, nn=FALSE; int goodScan=TRUE; switch (l) { @@ -332,7 +341,12 @@ int srscan(int l) prout(" [Using Base's sensors]"); } else proutn(" Short-range scan\n\r"); - if (goodScan) game.starch[quadx][quady] = game.damage[DRADIO]>0.0 ? game.state.galaxy[quadx][quady]+SUPERNOVA_PLACE:1; + if (goodScan && !game.damage[DRADIO]) { + game.state.chart[quadx][quady].klingons = game.state.galaxy[quadx][quady].klingons; + game.state.chart[quadx][quady].starbase = game.state.galaxy[quadx][quady].starbase; + game.state.chart[quadx][quady].stars = game.state.galaxy[quadx][quady].stars; + game.state.galaxy[quadx][quady].charted = TRUE; + } scan(); if (isit("chart")) nn = TRUE; if (isit("no")) rightside = FALSE; diff --git a/setup.c b/setup.c index b9c4842..f4a0373 100644 --- a/setup.c +++ b/setup.c @@ -228,7 +228,11 @@ void setup(int needprompt) alive = 1; docfac = 0.25; for (i = 1; i <= GALSIZE; i++) - for (j = 1; j <= GALSIZE; j++) game.state.newstuf[i][j] = game.starch[i][j] = 0; + for (j = 1; j <= GALSIZE; j++) { + game.state.galaxy[i][j].charted = 0; + game.state.galaxy[i][j].planets = 0; + game.state.galaxy[i][j].romulans = 0; + } // Initialize times for extraneous events game.future[FSNOVA] = game.state.date + expran(0.5 * intime); game.future[FTBEAM] = game.state.date + expran(1.5 * (intime / game.state.remcom)); @@ -246,14 +250,14 @@ void setup(int needprompt) for (j=1; j<=GALSIZE; j++) { int k = Rand()*9.0 + 1.0; instar += k; - game.state.galaxy[i][j] = k * STAR_PLACE; + game.state.galaxy[i][j].stars = k; } // Locate star bases in galaxy for (i = 1; i <= inbase; i++) { int contflag; do { do iran(GALSIZE, &ix, &iy); - while (BASES(game.state.galaxy[ix][iy])); + while (game.state.galaxy[ix][iy].starbase); contflag = FALSE; for (j = i-1; j > 0; j--) { /* Improved placement algorithm to spread out bases */ @@ -275,8 +279,8 @@ void setup(int needprompt) game.state.baseqx[i] = ix; game.state.baseqy[i] = iy; - game.starch[ix][iy] = CHART_UNKNOWN; - game.state.galaxy[ix][iy] += BASE_PLACE; + game.state.galaxy[ix][iy].starbase = 1; + game.state.chart[ix][iy].starbase = 1; } // Position ordinary Klingon Battle Cruisers krem = inkling - incom - game.state.nscrem; @@ -287,10 +291,8 @@ void setup(int needprompt) int klump = (1.0 - r*r)*klumper; if (klump > krem) klump = krem; krem -= klump; - klump *= KLINGON_PLACE; - do iran(GALSIZE, &ix, &iy); - while (game.state.galaxy[ix][iy] + klump >= SUPERNOVA_PLACE); - game.state.galaxy[ix][iy] += klump; + do iran(GALSIZE,&ix,&iy); while (game.state.galaxy[ix][iy].supernova); + game.state.galaxy[ix][iy].klingons += klump; } while (krem > 0); // Position Klingon Commander Ships #ifdef DEBUG @@ -309,21 +311,21 @@ void setup(int needprompt) #endif iran(GALSIZE, &ix, &iy); } - while ((game.state.galaxy[ix][iy] <= KLINGON_PLACE && Rand() < 0.75)|| - NOEXIT(game.state.galaxy[ix][iy])); + while ((!game.state.galaxy[ix][iy].klingons && Rand() < 0.75)|| + game.state.galaxy[ix][iy].supernova|| + game.state.galaxy[ix][iy].klingons > 8); // check for duplicate for (j = 1; j < i; j++) if (game.state.cx[j]==ix && game.state.cy[j]==iy) break; } while (j < i); - game.state.galaxy[ix][iy] += KLINGON_PLACE; + game.state.galaxy[ix][iy].klingons++; game.state.cx[i] = ix; game.state.cy[i] = iy; } // Locate planets in galaxy for (i = 0; i < inplan; i++) { - do iran(GALSIZE, &ix, &iy); - while (game.state.newstuf[ix][iy] > 0); - game.state.newstuf[ix][iy] = 1; + do iran(GALSIZE, &ix, &iy); while (game.state.galaxy[ix][iy].planets); + game.state.galaxy[ix][iy].planets = 1; game.state.plnets[i].x = ix; game.state.plnets[i].y = iy; game.state.plnets[i].pclass = Rand()*3.0; // Planet class M N or O @@ -333,15 +335,15 @@ void setup(int needprompt) // Locate Romulans for (i = 1; i <= game.state.nromrem; i++) { iran(GALSIZE, &ix, &iy); - game.state.newstuf[ix][iy] += ROMULAN_PLACE; + game.state.galaxy[ix][iy].romulans = 1; } // Locate the Super Commander if (game.state.nscrem > 0) { do iran(GALSIZE, &ix, &iy); - while (game.state.galaxy[ix][iy] >= 900); + while (game.state.galaxy[ix][iy].supernova || game.state.galaxy[ix][iy].klingons > 8); game.state.isx = ix; game.state.isy = iy; - game.state.galaxy[ix][iy] += KLINGON_PLACE; + game.state.galaxy[ix][iy].klingons++; } // Place thing (in tournament game, thingx == -1, don't want one!) if (thingx != -1) { @@ -500,7 +502,7 @@ void newcnd(void) { condit = IHGREEN; if (energy < 1000.0) condit = IHYELLOW; - if (game.state.galaxy[quadx][quady] >= KLINGON_PLACE || game.state.newstuf[quadx][quady] >= ROMULAN_PLACE) + if (game.state.galaxy[quadx][quady].klingons || game.state.galaxy[quadx][quady].romulans) condit = IHRED; if (!alive) condit=IHDEAD; } @@ -508,8 +510,6 @@ void newcnd(void) void newqad(int shutup) { - int quadnum = game.state.galaxy[quadx][quady]; - int newnum = game.state.newstuf[quadx][quady]; int i, j, ix, iy, nplan; iattak = 1; @@ -537,22 +537,21 @@ void newqad(int shutup) } // Clear quadrant for (i=1; i <= QUADSIZE; i++) - for (j=1; j <= QUADSIZE; j++) game.quad[i][j] = IHDOT; + for (j=1; j <= QUADSIZE; j++) + game.quad[i][j] = IHDOT; // cope with supernova - if (quadnum >= SUPERNOVA_PLACE) { + if (game.state.galaxy[quadx][quady].supernova) return; - } - klhere = KLINGONS(quadnum); - irhere = ROMULANS(newnum); - nplan = newnum%10; + klhere = game.state.galaxy[quadx][quady].klingons; + irhere = game.state.galaxy[quadx][quady].romulans; + nplan = game.state.galaxy[quadx][quady].planets; nenhere = klhere + irhere; // Position Starship game.quad[sectx][secty] = ship; - if (quadnum >= KLINGON_PLACE) { + if (game.state.galaxy[quadx][quady].klingons) { // Position ordinary Klingons - quadnum -= KLINGON_PLACE*klhere; for (i = 1; i <= klhere; i++) { dropin(IHK, &ix, &iy); game.kx[i] = ix; @@ -587,10 +586,8 @@ void newqad(int shutup) game.kpower[i] = Rand()*400.0 + 450.0 + 50.0*skill; } // If quadrant needs a starbase, put it in - if (quadnum >= BASE_PLACE) { - quadnum -= BASE_PLACE; + if (game.state.galaxy[quadx][quady].starbase) dropin(IHB, &basex, &basey); - } if (nplan) { // If quadrant needs a planet, put it in @@ -604,7 +601,8 @@ void newqad(int shutup) // Check for condition newcnd(); // And finally the stars - for (i = 1; i <= quadnum; i++) dropin(IHSTAR, &ix, &iy); + for (i = 1; i <= game.state.galaxy[quadx][quady].stars; i++) + dropin(IHSTAR, &ix, &iy); // Check for RNZ if (irhere > 0 && klhere == 0) { @@ -672,7 +670,8 @@ void newqad(int shutup) // Put in a few black holes for (i = 1; i <= 3; i++) - if (Rand() > 0.5) dropin(IHBLANK, &ix, &iy); + if (Rand() > 0.5) + dropin(IHBLANK, &ix, &iy); // Take out X's in corners if Tholian present if (ithere) { diff --git a/sst-doc.xml b/sst-doc.xml index 06c38a2..3a56ba6 100644 --- a/sst-doc.xml +++ b/sst-doc.xml @@ -1771,6 +1771,9 @@ The HELP/CALL/SOS command is now MAYDAY. SOS and CALL are still accepted. Status report now indicates if dilithium crystals are on board. + +At Dave's prompting, restored the Space Thingy's original elusive behavior. + Here are some good pages on the history of Star Trek games: diff --git a/sst.c b/sst.c index 65c79ac..2dca29e 100644 --- a/sst.c +++ b/sst.c @@ -114,9 +114,7 @@ Eric Raymond's changes: 2. Status report now indicates when dilithium crystals are on board. - 3. Can now report starbases left in scrscan. - - 4. Per Dave Matuszek's remarks, Thingy state is not saved across games. + 3. Per Dave Matuszek's remarks, Thingy state is not saved across games. */ /* the input queue */ @@ -485,14 +483,14 @@ static void makemoves(void) events(); if (alldone) break; // Events did us in } - if (game.state.galaxy[quadx][quady] == SUPERNOVA_PLACE) { // Galaxy went Nova! + if (game.state.galaxy[quadx][quady].supernova) { // Galaxy went Nova! atover(0); continue; } if (hitme && justin==0) { attack(2); if (alldone) break; - if (game.state.galaxy[quadx][quady] == SUPERNOVA_PLACE) { // went NOVA! + if (game.state.galaxy[quadx][quady].supernova) { // went NOVA! atover(0); hitme = TRUE; continue; diff --git a/sst.h b/sst.h index 5b6fb04..9a67c1d 100644 --- a/sst.h +++ b/sst.h @@ -40,11 +40,9 @@ typedef struct { basekl, // destroyed bases killk, // Klingons killed killc, // commanders killed - galaxy[GALSIZE+1][GALSIZE+1], // The Galaxy (subscript 0 not used) cx[QUADSIZE+1],cy[QUADSIZE+1], // Commander quadrant coordinates baseqx[BASEMAX], // Base quadrant X baseqy[BASEMAX], // Base quadrant Y - newstuf[GALSIZE+1][GALSIZE+1], // Extended galaxy goodies isx, isy, // Coordinate of Super Commander nscrem, // remaining super commanders nromkl, // Romulans killed @@ -55,28 +53,22 @@ typedef struct { double date, // stardate remres, // remaining resources remtime; // remaining time + struct { + int stars; + int planets; + int starbase; + int klingons; + int romulans; + int supernova; + int charted; + } galaxy[GALSIZE+1][GALSIZE+1]; // The Galaxy (subscript 0 not used) + struct { + int stars; + int starbase; + int klingons; + } chart[GALSIZE+1][GALSIZE+1]; // the starchart (subscript 0 not used) } snapshot; // Data that is snapshot -/* - * This is how the integers in the galaxy array are encoded. - * Someday these should turn into structure fields. - */ -#define SUPERNOVA_PLACE 1000 -#define KLINGON_PLACE 100 -#define BASE_PLACE 10 -#define STAR_PLACE 1 -#define KLINGONS(n) ((n)/KLINGON_PLACE) -#define BASES(n) (((n)%KLINGON_PLACE)/BASE_PLACE) -#define STARS(n) ((n)%BASE_PLACE) -#define NOEXIT(s) ((s) > 899) /* supernova or >8 Klingons */ - -/* for newstuff */ -#define ROMULAN_PLACE 10 -#define ROMULANS(n) ((n)/ROMULAN_PLACE) - -/* for starch */ -#define CHART_UNKNOWN -1 - #define SKILL_NONE 0 #define SKILL_NOVICE 1 #define SKILL_FAIR 2 @@ -135,7 +127,6 @@ EXTERN struct { char passwd[10]; // Self Destruct password int kx[(QUADSIZE+1)*(QUADSIZE+1)]; // enemy sector locations int ky[(QUADSIZE+1)*(QUADSIZE+1)]; - int starch[GALSIZE+1][GALSIZE+1]; // star chart /* members with macro definitions start here */ int inkling, inbase, @@ -403,6 +394,7 @@ void doshield(int); void dock(int); void dreprt(void); void chart(int); +void rechart(void); void impuls(void); void wait(void); void setwrp(void);