X-Git-Url: https://jxself.org/git/?p=super-star-trek.git;a=blobdiff_plain;f=src%2Fsst.py;h=e7a54919341fe3d348ff7492a97a2015380e2e94;hp=0c47c96064bc3f6f0a8fe2195fe0a6160f679e9f;hb=5582ed2207d6a03b841afc376af746813881bebd;hpb=12e8e2c7e247de376ae698f617c23a7ad29444ea diff --git a/src/sst.py b/src/sst.py index 0c47c96..e7a5491 100644 --- a/src/sst.py +++ b/src/sst.py @@ -173,7 +173,7 @@ Also, the nav subsystem (enabling automatic course setting) can be damaged separately from the main computer (which handles weapons targeting, ETA calculation, and self-destruct). """ -import os, sys, math, curses, time, atexit, readline, cPickle, random, getopt +import os,sys,math,curses,time,atexit,readline,cPickle,random,getopt,copy SSTDOC = "/usr/share/doc/sst/sst.doc" DOC_NAME = "sst.doc" @@ -244,7 +244,16 @@ class coord: def distance(self, other): return math.sqrt((self.x - other.x)**2 + (self.y - other.y)**2) def sgn(self): - return coord(self.x / abs(x), self.y / abs(y)); + s = coord() + if self.x == 0: + s.x = 0 + else: + s.x = self.x / abs(self.x) + if self.y == 0: + s.y = 0 + else: + s.y = self.y / abs(self.y) + return s def __hash__(self): return hash((x, y)) def __str__(self): @@ -423,7 +432,6 @@ class gamestate: self.ishere = False # super-commander in quadrant self.iscate = False # super commander is here self.ientesc = False # attempted escape from supercommander - self.ithere = False # Tholian is here self.resting = False # rest time self.icraft = False # Kirk in Galileo self.landed = False # party on planet (true), on ship (false) @@ -1021,9 +1029,8 @@ def supercommander(): def movetholian(): # move the Tholian - if not game.ithere or game.justin: + if not game.tholian or game.justin: return - if game.tholian.x == 0 and game.tholian.y == 0: idx = 0; idy = QUADSIZE-1 elif game.tholian.x == 0 and game.tholian.y == QUADSIZE-1: @@ -1036,12 +1043,10 @@ def movetholian(): # something is wrong! game.ithere = False return - # do nothing if we are blocked if game.quad[idx][idy]!= IHDOT and game.quad[idx][idy]!= IHWEB: return game.quad[game.tholian.x][game.tholian.y] = IHWEB - if game.tholian.x != idx: # move in x axis im = math.fabs(idx - game.tholian.x)*1.0/(idx - game.tholian.x) @@ -1074,7 +1079,7 @@ def movetholian(): dropin(IHBLANK) crmena(True, IHT, "sector", game.tholian) prout(_(" completes web.")) - game.ithere = False + game.tholian = None game.nenhere -= 1 return @@ -1260,7 +1265,7 @@ def ram(ibumpd, ienm, w): proutn("***") crmshp() prout(_(" heavily damaged.")) - icas = 10.0+20.0*random.random() + icas = 10 + random.randrange(20) prout(_("***Sickbay reports %d casualties"), icas) game.casual += icas game.state.crew -= icas @@ -1486,7 +1491,7 @@ def torpedo(course, r, incoming, i, n): h1 = math.fabs(h1) if h1 >= 600: game.quad[w.x][w.y] = IHDOT - game.ithere = False + game.tholian = None deadkl(w, iquad, w) return None skip(1) @@ -1496,7 +1501,7 @@ def torpedo(course, r, incoming, i, n): return None prout(_(" disappears.")) game.quad[w.x][w.y] = IHWEB - game.ithere = False + game.tholian = None game.nenhere -= 1 dropin(IHBLANK) return None @@ -1527,7 +1532,6 @@ def fry(hit): # a critical hit occured if hit < (275.0-25.0*game.skill)*(1.0+0.5*random.random()): return - ncrit = 1.0 + hit/(500.0+100.0*random.random()) proutn(_("***CRITICAL HIT--")) # Select devices and cause damage @@ -1564,42 +1568,32 @@ def attack(torps_ok): hitmax=0.0; hittot=0.0; chgfac=1.0 jay = coord() where = "neither" - # game could be over at this point, check if game.alldone: return - if idebug: prout("=== ATTACK!") - - # Tholian gewts to move before attacking - if game.ithere: + # Tholian gets to move before attacking + if game.tholian: movetholian() - # if you have just entered the RNZ, you'll get a warning if game.neutz: # The one chance not to be attacked game.neutz = False return - # commanders get a chance to tac-move towards you if (((game.comhere or game.ishere) and not game.justin) or game.skill == SKILL_EMERITUS) and torps_ok: moveklings() - # if no enemies remain after movement, we're done if game.nenhere==0 or (game.nenhere==1 and thing == game.quadrant and not iqengry): return - # set up partial hits if attack happens during shield status change pfac = 1.0/game.inshld if game.shldchg: chgfac = 0.25+0.5*random.random() - skip(1) - # message verbosity control if game.skill <= SKILL_FAIR: where = "sector" - for loop in range(game.nenhere): if game.kpower[loop] < 0: continue; # too weak to attack @@ -1723,7 +1717,6 @@ def attack(torps_ok): def deadkl(w, type, mv): # kill a Klingon, Tholian, Romulan, or Thingy # Added mv to allow enemy to "move" before dying - crmena(True, type, sector, mv) # Decide what kind of enemy it is and update appropriately if type == IHR: @@ -1733,7 +1726,7 @@ def deadkl(w, type, mv): game.state.nromrem -= 1 elif type == IHT: # Killed a Tholian - game.ithere = False + game.tholian = None elif type == IHQUEST: # Killed a Thingy global iqengry @@ -1766,7 +1759,6 @@ def deadkl(w, type, mv): unschedule(FSCDBAS) else: prout("*** Internal error, deadkl() called on %s\n" % type) - # For each kind of enemy, finish message to player prout(_(" destroyed.")) game.quad[w.x][w.y] = IHDOT @@ -1923,7 +1915,6 @@ def overheat(rpow): def checkshctrl(rpow): # check shield control - skip(1) if random.random() < 0.998: prout(_("Shields lowered.")) @@ -1960,7 +1951,7 @@ def checkshctrl(rpow): def hittem(hits): # register a phaser hit on Klingons and Romulans - nenhr2=game.nenhere; kk=1 + nenhr2 = game.nenhere; kk=1 w = coord() skip(1) for k in range(nenhr2): @@ -2001,7 +1992,7 @@ def hittem(hits): else: # decide whether or not to emasculate klingon if kpow > 0 and random.random() >= 0.9 and \ kpow <= ((0.4 + 0.4*random.random())*kpini): - prout(_("***Mr. Spock- \"Captain, the vessel at Sector %s"), w) + prout(_("***Mr. Spock- \"Captain, the vessel at Sector %s") % w) prout(_(" has just lost its firepower.\"")) game.kpower[kk] = -kpow kk += 1 @@ -2009,12 +2000,11 @@ def hittem(hits): def phasers(): # fire phasers - hits = []; rpow=0 + hits = [] kz = 0; k = 1; irec=0 # Cheating inhibitor - ifast = False; no = False; itarg = True; msgflag = True + ifast = False; no = False; itarg = True; msgflag = True; rpow=0 automode = "NOTSET" key=0 - skip(1) # SR sensors and Computer are needed fopr automode if damaged(DSRSENS) or damaged(DCOMPTR): @@ -2038,8 +2028,8 @@ def phasers(): return prout(_("Weapons Officer Sulu- \"High-speed shield control enabled, sir.\"")) ifast = True - - # Original code so convoluted, I re-did it all + # Original code so convoluted, I re-did it all + # (That was Tom Almy talking about the C code, I think -- ESR) while automode=="NOTSET": key=scan() if key == IHALPHA: @@ -2081,7 +2071,8 @@ def phasers(): elif not itarg: automode = "FORCEMAN" else: - proutn(_("Manual or automatic? ")) + proutn(_("Manual or automatic? ")) + chew() avail = game.energy if ifast: avail -= 200.0 @@ -2129,7 +2120,7 @@ def phasers(): extra = 0.0 powrem = rpow for i in range(game.nenhere): - hits[i] = 0.0 + hits.append(0.0) if powrem <= 0: continue hits[i] = math.fabs(game.kpower[i])/(PHASEFAC*math.pow(0.90,game.kdist[i])) @@ -2146,7 +2137,7 @@ def phasers(): hittem(hits) game.ididit = True if extra > 0 and not game.alldone: - if game.ithere: + if game.tholian: proutn(_("*** Tholian web absorbs ")) if game.nenhere>0: proutn(_("excess ")) @@ -2262,8 +2253,6 @@ def phasers(): # only have one FDISTR/FENSLV/FREPRO sequence going at any given time # BSD Trek, from which we swiped the idea, can have up to 5. -import math - def unschedule(evtype): # remove an event from the schedule game.future[evtype].date = FOREVER @@ -2295,7 +2284,6 @@ def cancelrest(): game.resting = False game.optime = 0.0 return True - return False def events(): @@ -2306,9 +2294,8 @@ def events(): w = coord(); hold = coord() ev = event(); ev2 = event() - def tractorbeam(): + def tractorbeam(yank): # tractor beaming cases merge here - yank = math.sqrt(yank) announce() game.optime = (10.0/(7.5*7.5))*yank # 7.5 is yank rate (warp 7.5) skip(1) @@ -2332,7 +2319,7 @@ def events(): game.iscraft = "removed" else: prout(_("Galileo, left on the planet surface, is well hidden.")) - if evcode==0: + if evcode == FSPY: game.quadrant = game.state.kscmdr else: game.quadrant = game.state.kcmdr[i] @@ -2345,8 +2332,8 @@ def events(): game.resting = False if not game.shldup: if not damaged(DSHIELD) and game.shield > 0: - doshield(True) # raise shields - game.shldchg=False + doshield(shraise=True) # raise shields + game.shldchg = False else: prout(_("(Shields not currently useable.)")) newqad(False) @@ -2487,27 +2474,25 @@ def events(): (game.energy < 2500 or damaged(DPHASER)) and \ (game.torps < 5 or damaged(DPHOTON))): # Tractor-beam her! - istract = True - yank = distance(game.state.kscmdr, game.quadrant) - ictbeam = True - tractorbeam() + istract = ictbeam = True + tractorbeam(distance(game.state.kscmdr, game.quadrant)) else: return elif evcode == FTBEAM: # Tractor beam if game.state.remcom == 0: unschedule(FTBEAM) continue - i = random.random()*game.state.remcom+1.0 - yank = square(game.state.kcmdr[i].x-game.quadrant.x) + square(game.state.kcmdr[i].y-game.quadrant.y) + i = random.randrange(game.state.remcom) + yank = distance(game.state.kcmdr[i], game.quadrant) if istract or game.condition == "docked" or yank == 0: # Drats! Have to reschedule schedule(FTBEAM, game.optime + expran(1.5*game.intime/game.state.remcom)) continue ictbeam = True - tractorbeam() + tractorbeam(yank) elif evcode == FSNAP: # Snapshot of the universe (for time warp) - game.snapsht = game.state + game.snapsht = copy.deepcopy(game.state) game.state.snap = True schedule(FSNAP, expran(0.5 * game.intime)) elif evcode == FBATTAK: # Commander attacks starbase @@ -2628,7 +2613,7 @@ def events(): q = game.state.galaxy[w.x][w.y] if not (game.quadrant == w or q.planet == None or \ not q.planet.inhabited or \ - q.supernova or q.status!=secure or q.klingons<=0): + q.supernova or q.status!="secure" or q.klingons<=0): break else: # can't seem to find one; ignore this call @@ -2733,9 +2718,7 @@ def wait(): proutn(_("Are you sure? ")) if ja() == False: return - # Alternate resting periods (events) with attacks - game.resting = True while True: if delay <= 0: @@ -2778,12 +2761,10 @@ def nova(nov): # star goes nova course = (0.0, 10.5, 12.0, 1.5, 9.0, 0.0, 3.0, 7.5, 6.0, 4.5) newc = coord(); scratch = coord() - if random.random() < 0.05: # Wow! We've supernova'ed supernova(False, nov) return - # handle initial nova game.quad[nov.x][nov.y] = IHDOT crmena(False, IHSTAR, sector, nov) @@ -2924,7 +2905,7 @@ def nova(nov): game.optime = 10.0*game.dist/16.0 skip(1) prout(_("Force of nova displaces starship.")) - imove(True) + imove(novapush=True) game.optime = 10.0*game.dist/16.0 return @@ -2932,7 +2913,6 @@ def supernova(induced, w=None): # star goes supernova num = 0; npdead = 0 nq = coord() - if w != None: nq = w else: @@ -2945,7 +2925,7 @@ def supernova(induced, w=None): stars += game.state.galaxy[nq.x][nq.y].stars if stars == 0: return # nothing to supernova exists - num = random.random()*stars + 1 + num = random.randrange(stars) + 1 for nq.x in range(GALSIZE): for nq.y in range(GALSIZE): num -= game.state.galaxy[nq.x][nq.y].stars @@ -2957,7 +2937,6 @@ def supernova(induced, w=None): proutn("=== Super nova here?") if ja() == True: nq = game.quadrant - if not nq == game.quadrant or game.justin: # it isn't here, or we just entered (treat as enroute) if communicating(): @@ -2967,7 +2946,7 @@ def supernova(induced, w=None): else: ns = coord() # we are in the quadrant! - num = random.random()* game.state.galaxy[nq.x][nq.y].stars + 1 + num = random.randrange(game.state.galaxy[nq.x][nq.y].stars) + 1 for ns.x in range(QUADSIZE): for ns.y in range(QUADSIZE): if game.quad[ns.x][ns.y]==IHSTAR: @@ -2976,7 +2955,6 @@ def supernova(induced, w=None): break if num==0: break - skip(1) prouts(_("***RED ALERT! RED ALERT!")) skip(1) @@ -3111,7 +3089,13 @@ def kaboom(): def killrate(): "Compute our rate of kils over time." - return ((game.inkling + game.incom + game.inscom) - (game.state.remkl + game.state.remcom + game.state.nscrem))/(game.state.date-game.indate) + elapsed = game.state.date - game.indate + if elapsed == 0: # Avoid divide-by-zero error if calculated on turn 0 + return 0 + else: + starting = (game.inkling + game.incom + game.inscom) + remaining = (game.state.remkl + game.state.remcom + game.state.nscrem) + return (starting - remaining)/elapsed def badpoints(): "Compute demerits." @@ -3128,7 +3112,6 @@ def badpoints(): badpt += 200.0 return badpt - def finish(ifin): # end the game, with appropriate notfications igotit = False @@ -3339,7 +3322,6 @@ def finish(ifin): def score(): # compute player's score timused = game.state.date - game.indate - iskill = game.skill if (timused == 0 or (game.state.remkl + game.state.remcom + game.state.nscrem) != 0) and timused < 5.0: timused = 5.0 @@ -3438,7 +3420,6 @@ def plaque(): winner = cgetline() # The 38 below must be 64 for 132-column paper nskip = 38 - len(winner)/2 - fp.write("\n\n\n\n") # --------DRAW ENTERPRISE PICTURE. fp.write(" EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n" ) @@ -3515,7 +3496,7 @@ def iostart(): #textdomain(PACKAGE) if atexit.register(outro): sys.stderr.write("Unable to register outro(), exiting...\n") - os.exit(1) + raise SysExit,1 if not (game.options & OPTION_CURSES): ln_env = os.getenv("LINES") if ln_env: @@ -3551,7 +3532,6 @@ def iostart(): setwnd(fullscreen_window) textcolor(DEFAULT) - def waitfor(): "wait for user action -- OK to do nothing if on a TTY" if game.options & OPTION_CURSES: @@ -3624,13 +3604,13 @@ def prout(line): def prouts(line): "print slowly!" for c in line: - curses.delay_output(30) + time.sleep(0.03) proutn(c) if game.options & OPTION_CURSES: wrefresh(curwnd) else: sys.stdout.flush() - curses.delay_output(300) + time.sleep(0.03) def cgetline(): "Get a line of input." @@ -3640,10 +3620,13 @@ def cgetline(): else: if replayfp and not replayfp.closed: line = replayfp.readline() + if line == '': + prout("*** Replay finished") + replayfp.close() else: - line = raw_input() + line = raw_input("COMMAND> ") if logfp: - logfp.write(line) + logfp.write(line + "\n") return line def setwnd(wnd): @@ -3750,7 +3733,7 @@ def boom(w): srscan_window.attron(curses.A_REVERSE) put_srscan_sym(w, game.quad[w.x][w.y]) #sound(500) - #delay(1000) + #time.sleep(1.0) #nosound() srscan_window.attroff(curses.A_REVERSE) put_srscan_sym(w, game.quad[w.x][w.y]) @@ -3786,18 +3769,18 @@ def tracktorpedo(w, l, i, n, iquad): if not damaged(DSRSENS) or game.condition=="docked": if i != 1 and l == 1: drawmaps(2) - curses.delay_output(400) + time.sleep(0.4) if (iquad==IHDOT) or (iquad==IHBLANK): put_srscan_sym(w, '+') #sound(l*10) - #curses.delay_output(100) + #time.sleep(0.1) #nosound() put_srscan_sym(w, iquad) else: curwnd.attron(curses.A_REVERSE) put_srscan_sym(w, iquad) #sound(500) - #curses.delay_output(1000) + #time.sleep(1.0) #nosound() curwnd.attroff(curses.A_REVERSE) put_srscan_sym(w, iquad) @@ -3835,7 +3818,7 @@ def imove(novapush): trbeam = False def no_quad_change(): - # No quadrant change -- compute new avg enemy distances + # No quadrant change -- compute new average enemy distances game.quad[game.sector.x][game.sector.y] = game.ship if game.nenhere: for m in range(game.nenhere): @@ -3850,12 +3833,10 @@ def imove(novapush): newcnd() drawmaps(0) setwnd(message_window) - w.x = w.y = 0 if game.inorbit: prout(_("Helmsman Sulu- \"Leaving standard orbit.\"")) game.inorbit = False - angle = ((15.0 - game.direc) * 0.5235988) deltax = -math.sin(angle) deltay = math.cos(angle) @@ -3863,10 +3844,8 @@ def imove(novapush): bigger = math.fabs(deltax) else: bigger = math.fabs(deltay) - deltay /= bigger deltax /= bigger - # If tractor beam is to occur, don't move full distance if game.state.date+game.optime >= scheduled(FTBEAM): trbeam = True @@ -3877,14 +3856,13 @@ def imove(novapush): game.quad[game.sector.x][game.sector.y] = IHDOT x = game.sector.x y = game.sector.y - n = 10.0*game.dist*bigger+0.5 - + n = int(10.0*game.dist*bigger+0.5) if n > 0: for m in range(1, n+1): x += deltax y += deltay - w.x = x + 0.5 - w.y = y + 0.5 + w.x = int(round(x)) + w.y = int(round(y)) if not VALID_SECTOR(w.x, w.y): # Leaving quadrant -- allow final enemy attack # Don't do it if being pushed by Nova @@ -3903,31 +3881,30 @@ def imove(novapush): if game.alldone: return # compute final position -- new quadrant and sector - x = QUADSIZE*(game.quadrant.x-1)+game.sector.x - y = QUADSIZE*(game.quadrant.y-1)+game.sector.y - w.x = x+10.0*game.dist*bigger*deltax+0.5 - w.y = y+10.0*game.dist*bigger*deltay+0.5 + x = (QUADSIZE*game.quadrant.x)+game.sector.x + y = (QUADSIZE*game.quadrant.y)+game.sector.y + w.x = int(round(x+10.0*game.dist*bigger*deltax)) + w.y = int(round(y+10.0*game.dist*bigger*deltay)) # check for edge of galaxy kinks = 0 while True: - kink = 0 - if w.x <= 0: - w.x = -w.x + 1 - kink = 1 - if w.y <= 0: - w.y = -w.y + 1 - kink = 1 - if w.x > GALSIZE*QUADSIZE: - w.x = (GALSIZE*QUADSIZE*2)+1 - w.x - kink = 1 - if w.y > GALSIZE*QUADSIZE: - w.y = (GALSIZE*QUADSIZE*2)+1 - w.y - kink = 1 + kink = False + if w.x < 0: + w.x = -w.x + kink = True + if w.y < 0: + w.y = -w.y + kink = True + if w.x >= GALSIZE*QUADSIZE: + w.x = (GALSIZE*QUADSIZE*2) - w.x + kink = True + if w.y >= GALSIZE*QUADSIZE: + w.y = (GALSIZE*QUADSIZE*2) - w.y + kink = True if kink: - kinks = 1 - if not kink: - break - + kinks += 1 + else: + break if kinks: game.nkinks += 1 if game.nkinks == 3: @@ -3941,10 +3918,10 @@ def imove(novapush): # Compute final position in new quadrant if trbeam: # Don't bother if we are to be beamed return - game.quadrant.x = (w.x+(QUADSIZE-1))/QUADSIZE - game.quadrant.y = (w.y+(QUADSIZE-1))/QUADSIZE - game.sector.x = w.x - QUADSIZE*(game.quadrant.x-1) - game.sector.y = w.y - QUADSIZE*(game.quadrant.y-1) + game.quadrant.x = w.x/QUADSIZE + game.quadrant.y = w.y/QUADSIZE + game.sector.x = w.x - (QUADSIZE*game.quadrant.x) + game.sector.y = w.y - (QUADSIZE*game.quadrant.y) skip(1) prout(_("Entering Quadrant %s.") % game.quadrant) game.quad[game.sector.x][game.sector.y] = game.ship @@ -3957,7 +3934,7 @@ def imove(novapush): # object encountered in flight path stopegy = 50.0*game.dist/game.optime game.dist = distance(game.sector, w) / (QUADSIZE * 1.0) - if iquad in (IHT. IHK, OHC, IHS, IHR, IHQUEST): + if iquad in (IHT, IHK, IHC, IHS, IHR, IHQUEST): game.sector = w ram(False, iquad, game.sector) final = game.sector @@ -4038,8 +4015,7 @@ def dock(verbose): prout(_("Lt. Uhura- \"Captain, an important message from the starbase:\"")) attackreport(False) game.iseenit = True - -# + # This program originally required input in terms of a (clock) # direction and distance. Somewhere in history, it was changed to # cartesian coordinates. So we need to convert. Probably @@ -4047,25 +4023,20 @@ def dock(verbose): # pain if the computer isn't working! Manual mode is still confusing # because it involves giving x and y motions, yet the coordinates # are always displayed y - x, where +y is downward! -# -def getcd(isprobe, akey): - # get course and distance - irowq=game.quadrant.x; icolq=game.quadrant.y; key=0 +def getcourse(isprobe, akey): + # get course and distance + key = 0 + dquad = copy.copy(game.quadrant) navmode = "unspecified" itemp = "curt" - incr = coord() + dsect = coord() iprompt = False - - # Get course direction and distance. If user types bad values, return - # with DIREC = -1.0. - game.direc = -1.0 - if game.landed and not isprobe: prout(_("Dummy! You can't leave standard orbit until you")) proutn(_("are back aboard the ship.")) chew() - return + return False while navmode == "unspecified": if damaged(DNAVSYS): if isprobe: @@ -4082,7 +4053,6 @@ def getcd(isprobe, akey): akey = -1 else: key = scan() - if key == IHEOL: proutn(_("Manual or automatic- ")) iprompt = True @@ -4099,7 +4069,7 @@ def getcd(isprobe, akey): else: huh() chew() - return + return False else: # numeric if isprobe: prout(_("(Manual navigation assumed.)")) @@ -4107,7 +4077,6 @@ def getcd(isprobe, akey): prout(_("(Manual movement assumed.)")) navmode = "manual" break - if navmode == "automatic": while key == IHEOL: if isprobe: @@ -4117,52 +4086,53 @@ def getcd(isprobe, akey): chew() iprompt = True key = scan() - if key != IHREAL: huh() - return - xi = int(aaitem-0.05) + return False + xi = int(round(aaitem))-1 key = scan() if key != IHREAL: huh() - return - xj = int(aaitem-0.5) + return False + xj = int(round(aaitem))-1 key = scan() if key == IHREAL: # both quadrant and sector specified - xk = aaitem + xk = int(round(aaitem))-1 key = scan() if key != IHREAL: huh() - return - xl = aaitem - - irowq = xi + 0.5 - icolq = xj + 0.5 - incr.y = xk + 0.5 - incr.x = xl + 0.5 + return False + xl = int(round(aaitem))-1 + dquad.x = xi + dquad.y = xj + dsect.y = xk + dsect.x = xl else: + # only one pair of numbers was specified if isprobe: # only quadrant specified -- go to center of dest quad - irowq = xi + 0.5 - icolq = xj + 0.5 - incr.y = incr.x = 5 + dquad.x = xi + dquad.y = xj + dsect.y = dsect.x = 4 # preserves 1-origin behavior else: - incr.y = xi + 0.5 - incr.x = xj + 0.5 + # only sector specified + dsect.y = xi + dsect.x = xj itemp = "normal" - if not VALID_QUADRANT(icolq,irowq) or not VALID_SECTOR(incr.x,incr.y): + if not VALID_QUADRANT(dquad.y,dquad.x) or not VALID_SECTOR(dsect.x,dsect.y): huh() - return + return False skip(1) if not isprobe: if itemp > "curt": if iprompt: - prout(_("Helmsman Sulu- \"Course locked in for Sector %s.\"") % incr) + prout(_("Helmsman Sulu- \"Course locked in for Sector %s.\"") % dsect) else: prout(_("Ensign Chekov- \"Course laid in, Captain.\"")) - deltax = icolq - game.quadrant.y + 0.1*(incr.x-game.sector.y) - deltay = game.quadrant.x - irowq + 0.1*(game.sector.x-incr.y) + # the actual deltas get computed here + deltax = dquad.y-game.quadrant.y + 0.1*(dsect.x-game.sector.y) + deltay = game.quadrant.x-dquad.x + 0.1*(game.sector.x-dsect.y) else: # manual while key == IHEOL: proutn(_("X and Y displacements- ")) @@ -4172,26 +4142,27 @@ def getcd(isprobe, akey): itemp = "verbose" if key != IHREAL: huh() - return + return False deltax = aaitem key = scan() if key != IHREAL: huh() - return + return False deltay = aaitem # Check for zero movement if deltax == 0 and deltay == 0: chew() - return + return False if itemp == "verbose" and not isprobe: skip(1) prout(_("Helmsman Sulu- \"Aye, Sir.\"")) + # Course actually laid in. game.dist = math.sqrt(deltax*deltax + deltay*deltay) game.direc = math.atan2(deltax, deltay)*1.90985932 if game.direc < 0.0: game.direc += 12.0 chew() - return + return True def impulse(): # move under impulse power @@ -4202,13 +4173,11 @@ def impulse(): prout(_("Engineer Scott- \"The impulse engines are damaged, Sir.\"")) return if game.energy > 30.0: - getcd(False, 0) - if game.direc == -1.0: + if not getcourse(isprobe=False, akey=0): return power = 20.0 + 100.0*game.dist else: power = 30.0 - if power >= game.energy: # Insufficient power for trip skip(1) @@ -4231,7 +4200,7 @@ def impulse(): if ja() == False: return # Activate impulse engines and pay the cost - imove(False) + imove(novapush=False) game.ididit = True if game.alldone: return @@ -4258,12 +4227,9 @@ def warp(timewarp): prout(_("Engineer Scott- \"Sorry, Captain. Until this damage")) prout(_(" is repaired, I can only give you warp 4.\"")) return - - # Read in course and distance - getcd(False, 0) - if game.direc == -1.0: + # Read in course and distance + if not getcourse(isprobe=False, akey=0): return - # Make sure starship has enough energy for the trip power = (game.dist+0.05)*game.warpfac*game.warpfac*game.warpfac*(game.shldup+1) if power >= game.energy: @@ -4340,10 +4306,8 @@ def warp(timewarp): if game.quad[ix][iy] != IHDOT: blooey = False twarp = False - - # Activate Warp Engines and pay the cost - imove(False) + imove(novapush=False) if game.alldone: return game.energy -= game.dist*game.warpfac*game.warpfac*game.warpfac*(game.shldup+1) @@ -4404,7 +4368,6 @@ def setwarp(): def atover(igrab): # cope with being tossed out of quadrant by supernova or yanked by beam - chew() # is captain on planet? if game.landed: @@ -4431,13 +4394,11 @@ def atover(igrab): game.icrystl = True if igrab: return - # Check to see if captain in shuttle craft if game.icraft: finish(FSTRACTOR) if game.alldone: return - # Inform captain of attempt to reach safety skip(1) while True: @@ -4566,7 +4527,6 @@ def probe(): prout(_("Uhura- \"The previous probe is still reporting data, Sir.\"")) return key = scan() - if key == IHEOL: # slow mode, so let Kirk know how many probes there are left if game.nprobes == 1: @@ -4576,7 +4536,6 @@ def probe(): proutn(_("Are you sure you want to fire a probe? ")) if ja() == False: return - game.isarmed = False if key == IHALPHA and citem == "armed": game.isarmed = True @@ -4584,8 +4543,7 @@ def probe(): elif key == IHEOL: proutn(_("Arm NOVAMAX warhead? ")) game.isarmed = ja() - getcd(True, key) - if game.direc == -1.0: + if not getcourse(isprobe=True, akey=key): return game.nprobes -= 1 angle = ((15.0 - game.direc) * 0.5235988) @@ -4595,7 +4553,6 @@ def probe(): bigger = math.fabs(game.probeinx) else: bigger = math.fabs(game.probeiny) - game.probeiny /= bigger game.probeinx /= bigger game.proben = 10.0*game.dist*bigger +0.5 @@ -4628,7 +4585,6 @@ def mayday(): # yell for help from nearest starbase # There's more than one way to move in this game! line = 0 - chew() # Test for conditions which prevent calling for help if game.condition == "docked": @@ -4907,13 +4863,14 @@ def sensor(): if game.iplnet.known=="shuttle_down": prout(_(" Sensors show Galileo still on surface.")) proutn(_(" Readings indicate")) - if game.iplnet.crystals != present: + if game.iplnet.crystals != "present": proutn(_(" no")) prout(_(" dilithium crystals present.\"")) if game.iplnet.known == "unknown": game.iplnet.known = "known" elif game.iplnet.inhabited: - prout(_("Spock- \"The inhabited planet %s is located at Sector %s, Captain.\"") % (game.iplnet.name, game.plnet)) + prout(_("Spock- \"The inhabited planet %s ") % game.iplnet.name) + prout(_(" is located at Sector %s, Captain.\"") % game.plnet) def beam(): # use the transporter @@ -5029,7 +4986,7 @@ def mine(): skip(1) prout(_("there's no reason to mine more at this time.")) return - game.optime = (0.1+0.2*random.random())*game.iplnet.pclass + game.optime = (0.1+0.2*random.random())*(ord(game.iplnet.pclass)-ord("M")) if consumeTime(): return prout(_("Mining operation complete.")) @@ -5187,7 +5144,6 @@ def shuttle(): def deathray(): # use the big zapper r = random.random() - game.ididit = False skip(1) chew() @@ -5446,7 +5402,7 @@ def chart(): prout(_("(Last surveillance update %d stardates ago).") % ((int)(game.state.date-game.lastchart))) prout(" 1 2 3 4 5 6 7 8") for i in range(GALSIZE): - proutn("%d |" % (i)) + proutn("%d |" % (i+1)) for j in range(GALSIZE): if (game.options & OPTION_SHOWME) and i == game.quadrant.x and j == game.quadrant.y: proutn("<") @@ -5575,7 +5531,7 @@ def srscan(): if game.condition != "docked": newcnd() for i in range(QUADSIZE): - proutn("%2d " % (i)) + proutn("%2d " % (i+1)) for j in range(QUADSIZE): sectscan(goodScan, i, j) skip(1) @@ -5616,14 +5572,12 @@ def eta(): w2.y = 0 else: w2.y=QUADSIZE-1 - if not VALID_QUADRANT(w1.x, w1.y) or not VALID_SECTOR(w2.x, w2.y): huh() return game.dist = math.sqrt(square(w1.y-game.quadrant.y+0.1*(w2.y-game.sector.y))+ square(w1.x-game.quadrant.x+0.1*(w2.x-game.sector.x))) wfl = False - if prompt: prout(_("Answer \"no\" if you don't know the value:")) while True: @@ -5706,83 +5660,16 @@ def eta(): return -#ifdef BSD_BUG_FOR_BUG -# A visual scan is made in a particular direction of three sectors -# in the general direction specified. This takes time, and -# Klingons can attack you, so it should be done only when sensors -# are out. Code swiped from BSD-Trek. Not presently used, as we -# automatically display all adjacent sectors on the short-range -# scan even when short-range sensors are out. - -# This struct[] has the delta x, delta y for particular directions - -visdelta = ( - (-1,-1), - (-1, 0), - (-1, 1), - (0, 1), - (1, 1), - (1, 0), - (1, -1), - (0, -1), - (-1,-1), - (-1, 0), - (-1, 1), -) - -def visual(): - v = coord() - if scan() != IHREAL: - chew() - proutn(_("Direction? ")) - if scan()!=IHREAL: - huh() - return - if aaitem < 0.0 or aaitem > 360.0: - return - co = (aaitem + 22) / 45 - v = visdelta[co] - ix = game.sector.x + v.x - iy = game.sector.y + v.y - if ix < 0 or ix >= QUADSIZE or iy < 0 or iy >= QUADSIZE: - co = '?' - else: - co = game.quad[ix][iy] - printf("%d,%d %c " % (ix+1, iy+1, co)) - v += 1 - ix = game.sector.x + v.x - iy = game.sector.y + v.y - if ix < 0 or ix >= QUADSIZE or iy < 0 or iy >= QUADSIZE: - co = '?' - else: - co = game.quad[ix][iy] - printf("%c " % (co)) - v += 1 - ix = game.sector.x + v.x - iy = game.sector.y + v.y - if ix < 0 or ix >= QUADSIZE or iy < 0 or iy >= QUADSIZE: - co = '?' - else: - co = game.quad[ix][iy] - prout("%c %d,%d\n" % (co, ix+1, iy+1)) - game.optime = 0.5 - game.ididit = True -#endif - # Code from setup.c begins here -def filelength(fd): - return os.fstat(fd).st_size - def prelim(): # issue a historically correct banner skip(2) prout(_("-SUPER- STAR TREK")) skip(1) -#ifdef __HISTORICAL__ +# From the FORTRAN original # prout(_("Latest update-21 Sept 78")) # skip(1) -#endif __HISTORICAL__ def freeze(boss): # save game @@ -5903,7 +5790,6 @@ device = ( def setup(needprompt): # prepare to play, set up cosmos w = coord() - # Decide how many of everything if choose(needprompt): return # frozen game @@ -6101,7 +5987,7 @@ def setup(needprompt): prout(_(" YOU'LL NEED IT.")) waitfor() newqad(False) - if game.nenhere - (thing == game.quadrant) - game.ithere: + if game.nenhere - (thing == game.quadrant) - (game.tholian != None): game.shldup = True if game.neutz: # bad luck to start in a Romulan Neutral Zone attack(False) @@ -6125,7 +6011,7 @@ def choose(needprompt): if aaitem == 0: chew() continue # We don't want a blank entry - game.tourn = int(aaitem) + game.tourn = int(round(aaitem)) random.seed(aaitem) break if isit("saved") or isit("frozen"): @@ -6259,7 +6145,6 @@ def newqad(shutup): game.inorbit = False game.landed = False game.ientesc = False - game.ithere = False global iqengry iqengry = False game.iseenit = False @@ -6274,10 +6159,8 @@ def newqad(shutup): game.klhere = q.klingons game.irhere = q.romulans game.nenhere = game.klhere + game.irhere - # Position Starship game.quad[game.sector.x][game.sector.y] = game.ship - if q.klingons: w.x = w.y = 0 # quiet a gcc warning # Position ordinary Klingons @@ -6292,9 +6175,8 @@ def newqad(shutup): game.quad[w.x][w.y] = IHC game.kpower[game.klhere] = 950.0+400.0*random.random()+50.0*game.skill game.comhere = True - # If we need a super-commander, promote a Klingon - if same(game.quadrant, game.state.kscmdr): + if game.quadrant == game.state.kscmdr: game.quad[game.ks[0].x][game.ks[0].y] = IHS game.kpower[1] = 1175.0 + 400.0*random.random() + 125.0*game.skill game.iscate = (game.state.remkl > 1) @@ -6308,7 +6190,6 @@ def newqad(shutup): # If quadrant needs a starbase, put it in if q.starbase: game.base = dropin(IHB) - # If quadrant needs a planet, put it in if q.planet: game.iplnet = q.planet @@ -6332,7 +6213,6 @@ def newqad(shutup): skip(1) prout(_("INTRUDER! YOU HAVE VIOLATED THE ROMULAN NEUTRAL ZONE.")) prout(_("LEAVE AT ONCE, OR YOU WILL BE DESTROYED!")) - if shutup==0: # Put in THING if needed global thing @@ -6348,19 +6228,18 @@ def newqad(shutup): skip(1) prout(_("Mr. Spock- \"Captain, this is most unusual.")) prout(_(" Please examine your short-range scan.\"")) - # Decide if quadrant needs a Tholian; lighten up if skill is low if game.options & OPTION_THOLIAN: if (game.skill < SKILL_GOOD and random.random() <= 0.02) or \ (game.skill == SKILL_GOOD and random.random() <= 0.05) or \ (game.skill > SKILL_GOOD and random.random() <= 0.08): + game.tholian = coord() while True: game.tholian.x = random.choice((0, QUADSIZE-1)) game.tholian.y = random.choice((0, QUADSIZE-1)) if game.quad[game.tholian.x][game.tholian.y] == IHDOT: break game.quad[game.tholian.x][game.tholian.y] = IHT - game.ithere = True game.nenhere += 1 game.ks[game.nenhere] = game.tholian game.kdist[game.nenhere] = game.kavgd[game.nenhere] = \ @@ -6376,14 +6255,12 @@ def newqad(shutup): if game.quad[QUADSIZE-1][QUADSIZE-1]==IHDOT: game.quad[QUADSIZE-1][QUADSIZE-1] = 'X' sortklings() - # Put in a few black holes for i in range(1, 3+1): if random.random() > 0.5: dropin(IHBLANK) - # Take out X's in corners if Tholian present - if game.ithere: + if game.tholian: if game.quad[0][0]=='X': game.quad[0][0] = IHDOT if game.quad[0][QUADSIZE-1]=='X': @@ -6396,7 +6273,7 @@ def newqad(shutup): def sortklings(): # sort Klingons by distance from us # The author liked bubble sort. So we will use it. :-( - if game.nenhere-(thing==game.quadrant)-game.ithere < 2: + if game.nenhere-(thing==game.quadrant)-(game.tholian!=None) < 2: return while True: sw = False @@ -6567,7 +6444,6 @@ def makemoves(): chew() setwnd(prompt_window) clrscr() - proutn("COMMAND> ") if scan() == IHEOL: if game.options & OPTION_CURSES: makechart() @@ -6605,7 +6481,7 @@ def makemoves(): elif cmd == "MOVE": # move under warp warp(False) elif cmd == "SHIELDS": # shields - doshield(False) + doshield(shraise=False) if game.ididit: hitme = True game.shldchg = False @@ -6658,7 +6534,7 @@ def makemoves(): elif cmd == "EMEXIT": # Emergency exit clrscr() # Hide screen freeze(True) # forced save - os.exit(1) # And quick exit + raise SysExit,1 # And quick exit elif cmd == "PROBE": probe() # Launch probe if game.ididit: @@ -6686,14 +6562,6 @@ def makemoves(): game.alldone = True # quit the game elif cmd == "HELP": helpme() # get help - elif cmd == "SEED": # set random-number seed - key = scan() - if key == IHREAL: - seed = int(aaitem) -#ifdef BSD_BUG_FOR_BUG -# elif cmd == "VISUAL": -# visual() # perform visual scan -#endif while True: if game.alldone: break # Game has ended @@ -6735,22 +6603,18 @@ def cramen(cmd): else: s = "Unknown??" proutn(s) -def cramlc(loctype, w): - # name a location - if loctype == "quadrant": - buf = _("Quadrant ") - elif loctype == "sector": - buf = _("Sector ") - buf += ("%d - %d" % (w.x, w.y)) - return buf - def crmena(stars, enemy, loctype, w): # print an enemy and his location if stars: proutn("***") cramen(enemy) proutn(_(" at ")) - proutn(cramlc(loctype, w)) + buf = "" + if loctype == "quadrant": + buf = _("Quadrant ") + elif loctype == "sector": + buf = _("Sector ") + proutn(buf + `w`) def crmshp(): # print our ship name @@ -6789,7 +6653,7 @@ def chew2(): def scan(): # Get a token from the user - global inqueue, line, citem + global inqueue, line, citem, aaitem aaitem = 0.0 citem = '' @@ -6919,13 +6783,13 @@ def debugme(): prout("Event %d canceled, no x coordinate." % (i)) unschedule(i) continue - w.x = int(aaitem) + w.x = int(round(aaitem)) key = scan() if key != IHREAL: prout("Event %d canceled, no y coordinate." % (i)) unschedule(i) continue - w.y = int(aaitem) + w.y = int(round(aaitem)) ev.quadrant = w chew() proutn("Induce supernova here? ") @@ -6941,29 +6805,28 @@ if __name__ == '__main__': iqengry = False game = gamestate() idebug = 0 - game.options = OPTION_ALL &~ (OPTION_IOMODES | OPTION_SHOWME | OPTION_PLAIN | OPTION_ALMY) # Disable curses mode until the game logic is working. # if os.getenv("TERM"): # game.options |= OPTION_CURSES | OPTION_SHOWME # else: game.options |= OPTION_TTY - seed = time.time() (options, arguments) = getopt.getopt(sys.argv[1:], "r:tx") for (switch, val) in options: if switch == '-r': try: - replayfp = open(optarg, "r") + replayfp = open(val, "r") except IOError: - sys.stderr.write("sst: can't open replay file %s\n" % optarg) - os.exit(1) + sys.stderr.write("sst: can't open replay file %s\n" % val) + raise SysExit, 1 line = replayfp.readline().strip() try: (key, seed) = line.split() seed = int(seed) + sys.stderr.write("sst2k: seed set to %d\n" % seed) except ValueError: - sys.stderr.write("sst: replay file %s is ill-formed\n"%optarg) + sys.stderr.write("sst: replay file %s is ill-formed\n"% val) os.exit(1) game.options |= OPTION_TTY game.options &=~ OPTION_CURSES @@ -6984,13 +6847,11 @@ if __name__ == '__main__': #setlinebuf(logfp) logfp.write("seed %d\n" % (seed)) random.seed(seed) - iostart() if arguments: inqueue = arguments else: inqueue = None - while True: # Play a game setwnd(fullscreen_window) clrscr() @@ -7004,16 +6865,15 @@ if __name__ == '__main__': skip(1) stars() skip(1) - if game.tourn and game.alldone: proutn(_("Do you want your score recorded?")) if ja() == True: chew2() freeze(False) + chew() proutn(_("Do you want to play again? ")) if not ja(): break skip(1) prout(_("May the Great Bird of the Galaxy roost upon your home planet.")) raise SysExit, 0 -