X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;f=sst;h=cee6f46c4114fc4b53ca333abf80668e8ec9bf5a;hb=fd980fc79a74f392c867f4f3d82bf470cb32a739;hp=3b23fac6a16b76b3cb50a080d31aa8398522c0a1;hpb=bd1b01477a638819082f75d990f279883a8871aa;p=super-star-trek.git diff --git a/sst b/sst index 3b23fac..cee6f46 100755 --- a/sst +++ b/sst @@ -88,6 +88,14 @@ class randomizer: # logfp.write("#seed(%d)\n" % n) game.lcg_x = n % randomizer.LCG_M + @staticmethod + def getrngstate(): + return game.lcg_x + + @staticmethod + def setrngstate(n): + game.lcg_x = n + GALSIZE = 8 # Galaxy size in quadrants NINHAB = (GALSIZE * GALSIZE // 2) # Number of inhabited worlds MAXUNINHAB = 10 # Maximum uninhabited worlds @@ -203,15 +211,12 @@ class Coord: return "%s - %s" % (self.i+1, self.j+1) __repr__ = __str__ -class Thingy(Coord): +class Thingy(): "Do not anger the Space Thingy!" def __init__(self): - Coord.__init__(self) - self.angered = False - def angry(self): - self.angered = True + self.location = Coord() def at(self, q): - return (q.i, q.j) == (self.i, self.j) + return (q.i, q.j) == (self.location.i, self.location.j) class Planet: def __init__(self): @@ -291,47 +296,46 @@ OPTION_ALL = 0xffffffff OPTION_TTY = 0x00000001 # old interface OPTION_CURSES = 0x00000002 # new interface OPTION_IOMODES = 0x00000003 # cover both interfaces -OPTION_PLANETS = 0x00000004 # planets and mining +OPTION_PLANETS = 0x00000004 # planets and mining (> 1974) OPTION_THOLIAN = 0x00000008 # Tholians and their webs (UT 1979 version) -OPTION_THINGY = 0x00000010 # Space Thingy can shoot back (Stas, 2005) OPTION_PROBE = 0x00000020 # deep-space probes (DECUS version, 1980) -OPTION_SHOWME = 0x00000040 # bracket Enterprise in chart -OPTION_RAMMING = 0x00000080 # enemies may ram Enterprise (Almy) -OPTION_MVBADDY = 0x00000100 # more enemies can move (Almy) -OPTION_BLKHOLE = 0x00000200 # black hole may timewarp you (Stas, 2005) -OPTION_BASE = 0x00000400 # bases have good shields (Stas, 2005) -OPTION_WORLDS = 0x00000800 # logic for inhabited worlds (ESR, 2006) -OPTION_AUTOSCAN = 0x00001000 # automatic LRSCAN before CHART (ESR, 2006) -OPTION_CAPTURE = 0x00002000 # Enable BSD-Trek capture (Almy, 2013). -OPTION_CLOAK = 0x80004000 # Enable BSD-Trek capture (Almy, 2013). -OPTION_PLAIN = 0x01000000 # user chose plain game -OPTION_ALMY = 0x02000000 # user chose Almy variant +OPTION_SHOWME = 0x00000040 # bracket Enterprise in chart (ESR, 2005) +OPTION_RAMMING = 0x00000080 # enemies may ram Enterprise (Almy, 1979) +OPTION_MVBADDY = 0x00000100 # more enemies can move (Almy, 1979?) +OPTION_AUTOPASS = 0x00000200 # Autogenerate password (Almy, 1997?) +OPTION_BLKHOLE = 0x00000400 # black hole may timewarp you (Stas, 2005) +OPTION_BASE = 0x00000800 # bases have good shields (Stas, 2005) +OPTION_WORLDS = 0x00001000 # logic for inhabited worlds (ESR, 2006) +OPTION_AUTOSCAN = 0x00002000 # automatic LRSCAN before CHART (ESR, 2006) +OPTION_CAPTURE = 0x00004000 # Enable BSD-Trek capture (Almy, 2013). +OPTION_CLOAK = 0x80008000 # Enable BSD-Trek capture (Almy, 2013). +OPTION_ALMY = 0x01000000 # Almy's death ray upgrade (1997?) OPTION_COLOR = 0x04000000 # enable color display (ESR, 2010) OPTION_DOTFILL = 0x08000000 # fix dotfill glitch in chart (ESR, 2019) OPTION_ALPHAMERIC = 0x10000000 # Alpha Y coordinates (ESR, 2023) option_names = { - "ALL": OPTION_ALL, - "TTY": OPTION_TTY, - "IOMODES": OPTION_IOMODES, - "PLANETS": OPTION_PLANETS, - "THOLIAN": OPTION_THOLIAN, - "THINGY": OPTION_THINGY, - "PROBE": OPTION_PROBE, - "SHOWME": OPTION_SHOWME, - "RAMMING": OPTION_RAMMING, - "MVBADDY": OPTION_MVBADDY, - "BLKHOLE": OPTION_BLKHOLE, - "BASE": OPTION_BASE, - "WORLDS": OPTION_WORLDS, - "AUTOSCAN": OPTION_AUTOSCAN, - "CAPTURE": OPTION_CAPTURE, - "CLOAK": OPTION_CLOAK, - "PLAIN": OPTION_PLAIN, - "ALMY": OPTION_ALMY, - "COLOR": OPTION_COLOR, - "DOTFILL": OPTION_DOTFILL, - } + "ALL": (OPTION_ALL, 0), + "TTY": (OPTION_TTY, 0), + "IOMODES": (OPTION_IOMODES, 0), + "PLANETS": (OPTION_PLANETS, 1974), + "THOLIAN": (OPTION_THOLIAN, 1979), + "PROBE": (OPTION_PROBE, 1980), + "SHOWME": (OPTION_SHOWME, 2006), + "RAMMING": (OPTION_RAMMING, 1979), + "MVBADDY": (OPTION_MVBADDY, 1979), + "AUTOPASS": (OPTION_AUTOPASS, 1997), + "BLKHOLE": (OPTION_BLKHOLE, 2006), + "BASE": (OPTION_BASE, 2005), + "WORLDS": (OPTION_WORLDS, 2006), + "AUTOSCAN": (OPTION_AUTOSCAN, 2000), + "CAPTURE": (OPTION_CAPTURE, 2013), + "CLOAK": (OPTION_CLOAK, 2013), + "ALMY": (OPTION_ALMY, 1997), + "COLOR": (OPTION_COLOR, 2010), + "DOTFILL": (OPTION_DOTFILL, 2019), + "ALPHAMERIC": (OPTION_ALPHAMERIC, 2023) +} # Define devices DSRSENS = 0 @@ -680,7 +684,7 @@ def movebaddy(enemy): if game.condition == "docked" and (game.options & OPTION_BASE): # protected by base -- back off ! motion -= game.skill*(2.0-rnd.real()**2) if game.idebug: - proutn("=== MOTION = %d, FORCES = %1.2f, " % (motion, forces)) + proutn("=== MOTION = %d, FORCES = %1.2f, " % (motion, forces)) # pragma: no cover # don't move if no motion if motion == 0: return [] @@ -697,7 +701,7 @@ def movebaddy(enemy): nsteps = min(nsteps, QUADSIZE) # This shouldn't be necessary nsteps = max(nsteps, 1) # This shouldn't be necessary if game.idebug: - proutn("NSTEPS = %d:" % nsteps) + proutn("NSTEPS = %d:" % nsteps) # pragma: no cover # Compute preferred values of delta X and Y m = game.sector - enemy.location if 2.0 * abs(m.i) < abs(m.j): @@ -709,7 +713,7 @@ def movebaddy(enemy): # main move loop for ll in range(nsteps): if game.idebug: - proutn(" %d" % (ll+1)) + proutn(" %d" % (ll+1)) # pragma: no cover # Check if preferred position available look = goto + m if m.i < 0: @@ -757,11 +761,11 @@ def movebaddy(enemy): if success: goto = look if game.idebug: - proutn(repr(goto)) + proutn(repr(goto)) # pragma: no cover else: break # done early if game.idebug: - skip(1) + skip(1) # pragma: no cover # Enemy moved, but is still in sector return [(False, enemy, old_dist, goto)] @@ -837,7 +841,7 @@ def supercommander(): idelta = Coord() basetbl = [] if game.idebug: - prout("== SUPERCOMMANDER") + prout("== SUPERCOMMANDER") # pragma: no cover # Decide on being active or passive avoid = ((game.incom - len(game.state.kcmdr) + game.inkling - game.remkl())/(game.state.date+0.01-game.indate) < 0.1*game.skill*(game.skill+1.0) or \ (game.state.date-game.indate) < 3.0) @@ -1279,7 +1283,7 @@ def torpedo(origin, bearing, dispersion, number, nburst): # Loop to move a single torpedo setwnd(message_window) for step in range(1, QUADSIZE*2): - if not track.nexttok(): + if not track.nextstep(): break w = track.sector() if not w.valid_sector(): @@ -1303,7 +1307,7 @@ def torpedo(origin, bearing, dispersion, number, nburst): # In the C/FORTRAN version, dispersion was 2.5 radians, which # is 143 degrees, which is almost exactly 4.8 clockface units displacement = course(track.bearing+rnd.real(-2.4, 2.4), distance=2**0.5) - displacement.nexttok() + displacement.nextstep() bumpto = displacement.sector() if not bumpto.valid_sector(): return hit @@ -1345,7 +1349,7 @@ def torpedo(origin, bearing, dispersion, number, nburst): return None proutn(crmena(True, iquad, "sector", w)) displacement = course(track.bearing+rnd.real(-2.4, 2.4), distance=2**0.5, origin=w) - displacement.nexttok() + displacement.nextstep() bumpto = displacement.sector() if game.quad[bumpto.i][bumpto.j] == ' ': prout(_(" buffeted into black hole.")) @@ -1412,21 +1416,15 @@ def torpedo(origin, bearing, dispersion, number, nburst): prout(crmena(True, '*', "sector", w) + _(" unaffected by photon blast.")) return None elif iquad == '?': # Hit a thingy - if not (game.options & OPTION_THINGY) or rnd.withprob(0.3): - skip(1) - prouts(_("AAAAIIIIEEEEEEEEAAAAAAAAUUUUUGGGGGHHHHHHHHHHHH!!!")) - skip(1) - prouts(_(" HACK! HACK! HACK! *CHOKE!* ")) - skip(1) - proutn(_("Mr. Spock-")) - prouts(_(" \"Fascinating!\"")) - skip(1) - deadkl(w, iquad, w) - else: - # Stas Sergeev added the possibility that - # you can shove the Thingy and piss it off. - # It then becomes an enemy and may fire at you. - thing.angry() + skip(1) + prouts(_("AAAAIIIIEEEEEEEEAAAAAAAAUUUUUGGGGGHHHHHHHHHHHH!!!")) + skip(1) + prouts(_(" HACK! HACK! HACK! *CHOKE!* ")) + skip(1) + proutn(_("Mr. Spock-")) + prouts(_(" \"Fascinating!\"")) + skip(1) + deadkl(w, iquad, w) return None elif iquad == ' ': # Black hole skip(1) @@ -1545,7 +1543,7 @@ def attack(torps_ok): prout("Sector %s." % goto) sortenemies() # if no enemies remain after movement, we're done - if len(game.enemies) == 0 or (len(game.enemies) == 1 and thing.at(game.quadrant) and not thing.angered): + if len(game.enemies) == 0 or (len(game.enemies) == 1 and thing.at(game.quadrant)): return # set up partial hits if attack happens during shield status change pfac = 1.0/game.inshld @@ -1565,7 +1563,7 @@ def attack(torps_ok): r *= 0.25 if enemy.power < 500: r *= 0.25 - if enemy.type == 'T' or (enemy.type == '?' and not thing.angered): + if enemy.type in ('T', '?'): continue # different enemies have different probabilities of throwing a torp usephasers = not torps_ok or \ @@ -1908,8 +1906,6 @@ def hittem(hits): else: proutn(_("Very small hit on ")) ienm = game.quad[w.i][w.j] - if ienm == '?': - thing.angry() proutn(crmena(False, ienm, "sector", w)) skip(1) if kpow == 0: @@ -2555,7 +2551,7 @@ def events(): supercommander() elif evcode == FDSPROB: # Move deep space probe schedule(FDSPROB, 0.01) - if not game.probe.nexttok(): + if not game.probe.nextstep(): if not game.probe.quadrant().valid_quadrant() or \ game.state.galaxy[game.probe.quadrant().i][game.probe.quadrant().j].supernova: # Left galaxy or ran into supernova @@ -2602,8 +2598,8 @@ def events(): break else: # can't seem to find one; ignore this call - if game.idebug: # pragma: no cover - prout("=== Couldn't find location for distress event.") + if game.idebug: + prout("=== Couldn't find location for distress event.") # pragma: no cover continue # got one!! Schedule its enslavement ev = schedule(FENSLV, expran(game.intime)) @@ -3838,7 +3834,7 @@ def imove(icourse=None, noattack=False): return True # This should not happen prout(_("Which way did he go?")) # pragma: no cover - return False + return False # pragma: no cover elif iquad == ' ': skip(1) prouts(_("***RED ALERT! RED ALERT!")) @@ -3892,7 +3888,7 @@ def imove(icourse=None, noattack=False): # Move out game.quad[game.sector.i][game.sector.j] = '.' for _m in range(icourse.moves): - icourse.nexttok() + icourse.nextstep() w = icourse.sector() if icourse.origin.quadrant() != icourse.location.quadrant(): newquadrant(noattack) @@ -4123,7 +4119,7 @@ class course: self.step = 0 def arrived(self): return self.location.roundtogrid() == self.final - def nexttok(self): + def nextstep(self): "Next step on course." self.step += 1 self.nextlocation = self.location + self.increment @@ -4189,7 +4185,7 @@ def impulse(): return def warp(wcourse, involuntary): - "ove under warp drive." + "Move under warp drive." blooey = False; twarp = False if not involuntary: # Not WARPX entry game.ididit = False @@ -4261,7 +4257,7 @@ def warp(wcourse, involuntary): # Decide if time warp will occur if 0.5*wcourse.distance*math.pow(7.0,game.warpfac-10.0) > rnd.real(): twarp = True - if game.idebug and game.warpfac==10 and not twarp: + if game.idebug and game.warpfac==10 and not twarp: # pragma: no cover blooey = False proutn("=== Force time warp? ") if ja(): @@ -4272,7 +4268,7 @@ def warp(wcourse, involuntary): look = wcourse.moves while look > 0: look -= 1 - wcourse.nexttok() + wcourse.nextstep() w = wcourse.sector() if not w.valid_sector(): break @@ -4818,7 +4814,7 @@ def beam(): if not ja(): scanner.chew() return - if not (game.options & OPTION_PLAIN): + if (game.options & OPTION_ALMY): nrgneed = 50 * game.skill + game.height / 100.0 if nrgneed > game.energy: prout(_("Engineering to bridge--")) @@ -5085,7 +5081,10 @@ def deathray(): prouts(_("WHIRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR")) skip(1) dprob = 0.30 - if game.options & OPTION_PLAIN: + # Ugh. This test (For Tom Almy's death-ray upgrade) was inverted for a long time. + # Furthermore, somebody (ESR or Stas?) changed Tom Almy's 0.7 upgraded chance of + # working to 0.5. + if game.options & OPTION_ALMY: dprob = 0.5 r = rnd.real() if r > dprob: @@ -5096,7 +5095,7 @@ def deathray(): prout(_("Ensign Chekov- \"Congratulations, Captain!\"")) if game.unwon() == 0: finish(FWON) - if (game.options & OPTION_PLAIN) == 0: + if (game.options & OPTION_ALMY): prout(_("Spock- \"Captain, I believe the `Experimental Death Ray'")) if rnd.withprob(0.05): prout(_(" is still operational.\"")) @@ -5608,7 +5607,7 @@ def goptions(): if mode == "IHEOL": active = [] for k, v in option_names.items(): - if (v & game.options) and k != "ALL": + if (v[0] & game.options) and k != "ALL": active.append(k) active.sort() prout(str(" ".join(active))) @@ -5620,7 +5619,7 @@ def goptions(): if scanner.type == "IHEOL": break if scanner.token.upper() in option_names: - changemask |= option_names[scanner.token.upper()] + changemask |= option_names[scanner.token.upper()][0] else: prout(_("No such option as ") + scanner.token) if mode == "set": @@ -5820,7 +5819,7 @@ def setup(): game.state.galaxy[i][j].stars = k # Locate star bases in galaxy if game.idebug: - prout("=== Allocating %d bases" % game.inbase) + prout("=== Allocating %d bases" % game.inbase) # pragma: no cover for i in range(game.inbase): while True: while True: @@ -5836,15 +5835,15 @@ def setup(): if distq < 6.0*(BASEMAX+1-game.inbase) and rnd.withprob(0.75): contflag = True if game.idebug: - prout("=== Abandoning base #%d at %s" % (i, w)) + prout("=== Abandoning base #%d at %s" % (i, w)) # pragma: no cover break elif distq < 6.0 * (BASEMAX+1-game.inbase): if game.idebug: - prout("=== Saving base #%d, close to #%d" % (i, j)) + prout("=== Saving base #%d, close to #%d" % (i, j)) # pragma: no cover if not contflag: break if game.idebug: - prout("=== Placing base #%d in quadrant %s" % (i, w)) + prout("=== Placing base #%d in quadrant %s" % (i, w)) # pragma: no cover game.state.baseq.append(w) game.state.galaxy[w.i][w.j].starbase = game.state.chart[w.i][w.j].starbase = True # Position ordinary Klingon Battle Cruisers @@ -5930,12 +5929,17 @@ def setup(): # Place thing (in tournament game, we don't want one!) # New in SST2K: never place the Thing near a starbase. # This makes sense and avoids a special case in the old code. - global thing if game.tourn is None: + # Avoid distrubing the RNG chain. This code + # was a late fix and we don't want to mess up + # all the regression tests. + state = randomizer.getrngstate() while True: - thing = randplace(GALSIZE) - if thing not in game.state.baseq: + thing.location = randplace(GALSIZE) + # Put it somewhere a starbase is not + if thing.location not in game.state.baseq: break + randomizer.setrngstate(state) skip(2) game.state.snap = False if game.skill == SKILL_NOVICE: @@ -5971,33 +5975,52 @@ def setup(): clrscr() setwnd(message_window) newqad() - if len(game.enemies) - (thing == game.quadrant) - (game.tholian is not None): + if len(game.enemies) - (thing.location == game.quadrant) - (game.tholian is not None): game.shldup = True if game.neutz: # bad luck to start in a Romulan Neutral Zone attack(torps_ok=False) def choose(): "Choose your game type." - while True: - game.tourn = game.length = 0 - game.thawed = False - game.skill = SKILL_NONE - # Do not chew here, we want to use command-line tokens - if not scanner.inqueue: # Can start with command line options - proutn(_("Would you like a regular, tournament, or saved game? ")) + game.tourn = None + game.length = 0 + game.thawed = False + game.skill = SKILL_NONE + gametype = None + wayback = 0 + while gametype is None or game.length == 0 or game.skill == SKILL_NONE or wayback == 0: + eol_is_fancy = False + if not scanner.inqueue or scanner.token == "IHEOL": # Can start with command line options + if gametype is None: + proutn(_("Would you like a regular, tournament, or saved game? ")) + elif game.length==0: + proutn(_("Would you like a Short, Medium, or Long game? ")) + elif game.skill == SKILL_NONE: + proutn(_("Are you a Novice, Fair, Good, Expert, or Emeritus player? ")) + elif wayback == 0: + proutn(_("Wayback setting (press enter for current year): ")) + eol_is_fancy = True scanner.nexttok() - if scanner.sees("tournament"): + if game.idebug: + prout("-- Token: %s=%s" % (scanner.type, repr(scanner.token))) + if scanner.token == "": + raise SystemExit(0) # Early end of replay + if scanner.token.startswith("r"): # regular + gametype = "regular" + elif scanner.token.startswith("t"): + gametype = "tournament" + proutn(_("Type in tournament number-")) + game.tourn = 0 while scanner.nexttok() == "IHEOL": - proutn(_("Type in tournament number-")) - if scanner.real == 0: - scanner.chew() - continue # We don't want a blank entry + if scanner.real == 0: + scanner.chew() + continue # We don't want a blank entry game.tourn = int(round(scanner.real)) rnd.seed(scanner.real) if logfp: logfp.write("# rnd.seed(%d)\n" % scanner.real) - break - if scanner.sees("saved") or scanner.sees("frozen"): + elif scanner.token.startswith("sa") or scanner.token.startswith("fr"): # saved or frozen + gametype = "saved" if thaw(): continue scanner.chew() @@ -6008,59 +6031,42 @@ def choose(): report() waitfor() return True - if scanner.sees("regular"): - break - proutn(_("What is \"%s\"? ") % scanner.token) - scanner.chew() - while game.length==0 or game.skill==SKILL_NONE: - if scanner.nexttok() == "IHALPHA": - if scanner.sees("short"): - game.length = 1 - elif scanner.sees("medium"): - game.length = 2 - elif scanner.sees("long"): - game.length = 4 - elif scanner.sees("novice"): - game.skill = SKILL_NOVICE - elif scanner.sees("fair"): - game.skill = SKILL_FAIR - elif scanner.sees("good"): - game.skill = SKILL_GOOD - elif scanner.sees("expert"): - game.skill = SKILL_EXPERT - elif scanner.sees("emeritus"): - game.skill = SKILL_EMERITUS - else: - proutn(_("What is \"")) - proutn(scanner.token) - prout("\"?") + elif scanner.token.startswith("s"): # short + game.length = 1 + elif scanner.token.startswith("m"): # medium + game.length = 2 + elif scanner.token.startswith("l"): # long + game.length = 4 + elif scanner.token.startswith("n"): # novice + game.skill = SKILL_NOVICE + elif (game.skill is None) and scanner.token.startswith("f"): # fair + game.skill = SKILL_FAIR + elif scanner.token.startswith("g"): # good + game.skill = SKILL_GOOD + elif scanner.token.startswith("e"): # expert + game.skill = SKILL_EXPERT + elif scanner.token.startswith("em"): # emeritus + game.skill = SKILL_EMERITUS + elif scanner.type == "IHREAL": + wayback = scanner.int() + elif (eol_is_fancy and scanner.token.startswith("\n")): + wayback = time.localtime().tm_year + elif scanner.token.startswith("\n"): + continue + elif scanner.token.startswith("idebug"): + game.idebug = True else: - scanner.chew() - if game.length==0: - proutn(_("Would you like a Short, Medium, or Long game? ")) - elif game.skill == SKILL_NONE: - proutn(_("Are you a Novice, Fair, Good, Expert, or Emeritus player? ")) - # Choose game options -- added by ESR for SST2K - if scanner.nexttok() != "IHALPHA": - scanner.chew() - proutn(_("Choose your game style (plain, almy, fancy or just press enter): ")) - scanner.nexttok() - if scanner.sees("plain"): - # Approximates the UT FORTRAN version. - game.options &=~ (OPTION_THOLIAN | OPTION_PLANETS | OPTION_THINGY | OPTION_PROBE | OPTION_RAMMING | OPTION_MVBADDY | OPTION_BLKHOLE | OPTION_BASE | OPTION_WORLDS | OPTION_COLOR | OPTION_CAPTURE | OPTION_CLOAK | OPTION_DOTFILL | OPTION_ALPHAMERIC) - game.options |= OPTION_PLAIN - elif scanner.sees("almy"): - # Approximates Tom Almy's version. - game.options &=~ (OPTION_THINGY | OPTION_BLKHOLE | OPTION_BASE | OPTION_WORLDS | OPTION_COLOR | OPTION_DOTFILL | OPTION_ALPHAMERIC) - game.options |= OPTION_ALMY - elif scanner.sees("fancy") or scanner.sees("\n"): - pass - elif len(scanner.token): - proutn(_("What is \"%s\"?") % scanner.token) + # Unrecognized token + prout(_("Can't interpret %s") % repr(scanner.token)) + for (name, (option, year)) in option_names.items(): + if wayback < year: + game.options &=~ option setpassword() if game.passwd == "debug": # pragma: no cover game.idebug = True prout("=== Debug mode enabled.") + if game.idebug: + prout("--- Setup: type=%s length=%s skill=%s wayback=%s" % (gametype, game.length, game.skill, wayback)) # Use parameters to generate initial values of things game.damfac = 0.5 * game.skill game.inbase = rnd.integer(BASEMIN, BASEMAX+1) @@ -6174,7 +6180,7 @@ def newqad(): prout(_("INTRUDER! YOU HAVE VIOLATED THE ROMULAN NEUTRAL ZONE.")) prout(_("LEAVE AT ONCE, OR YOU WILL BE DESTROYED!")) # Put in THING if needed - if thing == game.quadrant: + if thing.location == game.quadrant: Enemy(etype='?', loc=dropin(), power=rnd.real(6000,6500.0)+250.0*game.skill) if not damaged(DSRSENS): @@ -6227,7 +6233,12 @@ def newqad(): def setpassword(): "Set the self-destruct password." - if game.options & OPTION_PLAIN: + if game.options & OPTION_AUTOPASS: + game.passwd = "" + game.passwd += chr(ord('a')+rnd.integer(26)) + game.passwd += chr(ord('a')+rnd.integer(26)) + game.passwd += chr(ord('a')+rnd.integer(26)) + else: while True: scanner.chew() proutn(_("Please type in a secret password- ")) @@ -6236,11 +6247,6 @@ def setpassword(): #game.passwd = getpass.getpass("Please type in a secret password- ") if game.passwd is not None: break - else: - game.passwd = "" - game.passwd += chr(ord('a')+rnd.integer(26)) - game.passwd += chr(ord('a')+rnd.integer(26)) - game.passwd += chr(ord('a')+rnd.integer(26)) # Code from sst.c begins here @@ -6538,7 +6544,7 @@ def makemoves(): if game.alldone: break if game.idebug: - prout("=== Ending") + prout("=== Ending") # pragma: no cover def cramen(ch): "Emit the name of an enemy or feature." @@ -6703,7 +6709,7 @@ def debugme(): # pragma: no cover proutn("Toggle debug flag? ") if ja(): game.idebug = not game.idebug - if game.idebug: + if game.idebug: # pragma: no cover prout("Debug output ON") else: prout("Debug output OFF") @@ -6781,49 +6787,58 @@ if __name__ == '__main__': game = Gamestate() rnd = randomizer() logfp = None - game.options = OPTION_ALL &~ (OPTION_IOMODES | OPTION_PLAIN | OPTION_ALMY) + game.options = OPTION_ALL &~ OPTION_IOMODES if os.getenv("TERM"): game.options |= OPTION_CURSES # pragma: no cover else: game.options |= OPTION_TTY seed = int(time.time()) - (options, arguments) = getopt.getopt(sys.argv[1:], "cr:s:txV") - for (switch, val) in options: - if switch == '-r': - # pylint: disable=raise-missing-from - try: - replayfp = open(val, "r") - except IOError: - sys.stderr.write("sst: can't open replay file %s\n" % val) - raise SystemExit(1) - # pylint: disable=raise-missing-from - try: - line = replayfp.readline().strip() - (leader, __, seed) = line.split() - # pylint: disable=eval-used - seed = eval(seed) - line = replayfp.readline().strip() - arguments += line.split()[2:] - except ValueError: # pragma: no cover - sys.stderr.write("sst: replay file %s is ill-formed\n"% val) + try: + (options, arguments) = getopt.getopt(sys.argv[1:], "cr:s:txV") + for (switch, val) in options: + if switch == '-r': + # pylint: disable=raise-missing-from + try: + replayfp = open(val, "r") + except IOError: + sys.stderr.write("sst: can't open replay file %s\n" % val) + raise SystemExit(1) + # pylint: disable=raise-missing-from + try: + while True: + line = replayfp.readline().strip() + print(line) + if line == "#": + break + if line.startswith("# seed"): + (__, __, seed) = line.split() + # pylint: disable=eval-used + seed = eval(seed) + elif line.startswith("# arguments"): + arguments += line.split()[2:] + except ValueError: # pragma: no cover + sys.stderr.write("sst: replay file %s is ill-formed\n"% val) + raise SystemExit(1) + game.options |= OPTION_TTY + game.options &=~ OPTION_CURSES + elif switch == '-s': # pragma: no cover + seed = int(val) + elif switch == '-t': # pragma: no cover + game.options |= OPTION_TTY + game.options &=~ OPTION_CURSES + elif switch == '-x': # pragma: no cover + game.idebug = True + elif switch == '-c': # Enable curses debugging - undocumented + game.cdebug = True + elif switch == '-V': # pragma: no cover + print("SST2K", version) + raise SystemExit(0) + else: # pragma: no cover + sys.stderr.write("usage: sst [-t] [-x] [startcommand...].\n") raise SystemExit(1) - game.options |= OPTION_TTY - game.options &=~ OPTION_CURSES - elif switch == '-s': # pragma: no cover - seed = int(val) - elif switch == '-t': # pragma: no cover - game.options |= OPTION_TTY - game.options &=~ OPTION_CURSES - elif switch == '-x': # pragma: no cover - game.idebug = True - elif switch == '-c': # Enable curses debugging - undocumented - game.cdebug = True - elif switch == '-V': # pragma: no cover - print("SST2K", version) - raise SystemExit(0) - else: # pragma: no cover - sys.stderr.write("usage: sst [-t] [-x] [startcommand...].\n") - raise SystemExit(1) + except getopt.GetoptError as err: + print(err) + raise SystemExit(1) from err # where to save the input in case of bugs if "TMPDIR" in os.environ: # pragma: no cover tmpdir = os.environ['TMPDIR'] @@ -6840,6 +6855,7 @@ if __name__ == '__main__': logfp.write("# SST2K version %s\n" % version) logfp.write("# recorded by %s@%s on %s\n" % \ (getpass.getuser(),socket.getfqdn(),time.ctime())) + logfp.write("#\n") rnd.seed(seed) scanner = sstscanner() for arg in arguments: