Fix another basic error.
[super-star-trek.git] / src / sst.py
index 020e91fefd5c16dad704cbb4fb39daeb5369b431..51ad07b53cdf03fa18d9e7a55bad2bddfbb6c357 100644 (file)
@@ -240,15 +240,21 @@ class coord:
     def is_valid(self):
         return self.x != None and self.y != None
     def __eq__(self, other):
-        return other != None and self.x == other.y and self.x == other.y
+        return other != None and self.x == other.x and self.y == other.y
     def __add__(self, other):
-        return coord(self.x+self.x, self.y+self.y)
+        return coord(self.x+other.x, self.y+other.y)
     def __sub__(self, other):
         return coord(self.x-other.x, self.y-other.y)
     def __mul__(self, other):
         return coord(self.x*other, self.y*other)
     def __rmul__(self, other):
         return coord(self.x*other, self.y*other)
+    def __div__(self, other):
+        return coord(self.x/other, self.y/other)
+    def __rdiv__(self, other):
+        return coord(self.x/other, self.y/other)
+    def snaptogrid(self):
+        return coord(int(round(self.x)), int(round(self.y)))
     def distance(self, other=None):
         if not other: other = coord(0, 0)
         return math.sqrt((self.x - other.x)**2 + (self.y - other.y)**2)
@@ -607,14 +613,13 @@ def randreal(*args):
 # Code from ai.c begins here
 
 def welcoming(iq):
-    # Would this quadrant welcome another Klingon?
+    "Would this quadrant welcome another Klingon?"
     return VALID_QUADRANT(iq.x,iq.y) and \
-       not game.state.galaxy[iq.x][iq.y].supernova or \
+       not game.state.galaxy[iq.x][iq.y].supernova and \
        game.state.galaxy[iq.x][iq.y].klingons < MAXKLQUAD
 
-
 def tryexit(enemy, look, irun):
-    # a bad guy attempts to bug out 
+    "A bad guy attempts to bug out."
     iq = coord()
     iq.x = game.quadrant.x+(look.x+(QUADSIZE-1))/QUADSIZE - 1
     iq.y = game.quadrant.y+(look.y+(QUADSIZE-1))/QUADSIZE - 1
@@ -633,12 +638,12 @@ def tryexit(enemy, look, irun):
        # don't leave if over 1000 units of energy 
        if enemy.kpower > 1000.0:
            return False
-    # print escape message and move out of quadrant.
+    # emit escape message and move out of quadrant.
     # we know this if either short or long range sensors are working
     if not damaged(DSRSENS) or not damaged(DLRSENS) or \
        game.condition == "docked":
-       crmena(True, enemy.type, "sector", enemy.kloc)
-       prout(_(" escapes to Quadrant %s (and regains strength).") % q)
+       prout(crmena(True, enemy.type, "sector", enemy.kloc) + \
+              (_(" escapes to Quadrant %s (and regains strength).") % q))
     # handle local matters related to escape
     enemy.move(None)
     game.klhere -= 1
@@ -702,7 +707,7 @@ def tryexit(enemy, look, irun):
 # 
 
 def movebaddy(enemy):
-    # tactical movement for the bad guys 
+    "Tactical movement for the bad guys."
     next = coord(); look = coord()
     irun = False
     # This should probably be just (game.quadrant in game.state.kcmdr) + (game.state.kscmdr==game.quadrant) 
@@ -841,9 +846,7 @@ def movebaddy(enemy):
        skip(1)
     if enemy.move(next):
        if not damaged(DSRSENS) or game.condition == "docked":
-           proutn("***")
-           cramen(enemy.type)
-           proutn(_(" from Sector %s") % enemy.kloc)
+           proutn(_("*** %s from Sector %s") % (cramen(enemy.type), enemy.kloc))
            if enemy.kdist < dist1:
                proutn(_(" advances to "))
            else:
@@ -851,7 +854,7 @@ def movebaddy(enemy):
            prout("Sector %s." % next)
 
 def moveklings():
-    # Klingon tactical movement 
+    "Sequence Klingon tactical movement."
     if idebug:
        prout("== MOVCOM")
     # Figure out which Klingon is the commander (or Supercommander)
@@ -875,7 +878,7 @@ def moveklings():
     game.enemies.sort(lambda x, y: cmp(x.kdist, y.kdist))
 
 def movescom(iq, avoid):
-    # commander movement helper 
+    "Commander movement helper." 
     # Avoid quadrants with bases if we want to avoid Enterprise 
     if not welcoming(iq) or (avoid and iq in game.state.baseq):
        return True
@@ -915,7 +918,7 @@ def movescom(iq, avoid):
     return False; # looks good! 
                        
 def supercommander():
-    # move the Super Commander 
+    "Move the Super Commander." 
     iq = coord(); sc = coord(); ibq = coord(); idelta = coord()
     basetbl = []
     if idebug:
@@ -1034,7 +1037,7 @@ def supercommander():
     return
 
 def movetholian():
-    # move the Tholian
+    "Move the Tholian."
     if not game.tholian or game.justin:
        return
     id = coord()
@@ -1058,13 +1061,11 @@ def movetholian():
     delta = (id - game.tholian.kloc).sgn()
     # move in x axis 
     while here.x != id.x:
-        #print "Moving in X", delta
         here.x += delta.x
         if game.quad[here.x][here.y]==IHDOT:
             game.tholian.move(here)
     # move in y axis 
     while here.y != id.y:
-        #print "Moving in Y", delta
         here.y += delta.y
         if game.quad[here.x][here.y]==IHDOT:
             game.tholian.move(here)
@@ -1081,16 +1082,14 @@ def movetholian():
     # All plugged up -- Tholian splits 
     game.quad[game.tholian.kloc.x][game.tholian.kloc.y]=IHWEB
     dropin(IHBLANK)
-    crmena(True, IHT, "sector", game.tholian)
-    prout(_(" completes web."))
+    prout(crmena(True, IHT, "sector", game.tholian) + _(" completes web."))
     game.tholian.move(None)
-    print "Tholian movement ends"
     return
 
 # Code from battle.c begins here
 
 def doshield(shraise):
-    # change shield status 
+    "Change shield status."
     action = "NONE"
     game.ididit = False
     if shraise:
@@ -1196,8 +1195,7 @@ def doshield(shraise):
        return
 
 def randdevice():
-    # choose a device to damage, at random. 
-    #
+    "Choose a device to damage, at random."
     # Quoth Eric Allman in the code of BSD-Trek:
     # "Under certain conditions you can get a critical hit.  This
     # sort of hit damages devices.  The probability that a given
@@ -1220,7 +1218,6 @@ def randdevice():
     # We don't have a cloaking device.  The shuttle got the allocation
     # for the cloaking device, then we shaved a half-percent off
     # everything to have some weight to give DSHCTRL/DDRAY/DDSP.
-    # 
     weights = (
        105,    # DSRSENS: short range scanners 10.5% 
        105,    # DLRSENS: long range scanners          10.5% 
@@ -1248,35 +1245,31 @@ def randdevice():
     return None;       # we should never get here
 
 def collision(rammed, enemy):
-    # collision handling
+    "Collision handling fot rammong events."
     prouts(_("***RED ALERT!  RED ALERT!"))
     skip(1)
     prout(_("***COLLISION IMMINENT."))
     skip(2)
     proutn("***")
-    crmshp()
+    proutn(crmshp())
     hardness = {IHR:1.5, IHC:2.0, IHS:2.5, IHT:0.5, IHQUEST:4.0}.get(enemy.type, 1.0)
     if rammed:
         proutn(_(" rammed by "))
     else:
         proutn(_(" rams "))
-    crmena(False, enemy.type, "sector", enemy.kloc)
+    proutn(crmena(False, enemy.type, "sector", enemy.kloc))
     if rammed:
        proutn(_(" (original position)"))
     skip(1)
     deadkl(enemy.kloc, enemy.type, game.sector)
-    proutn("***")
-    crmshp()
-    prout(_(" heavily damaged."))
+    proutn("***" + crmship() + " heavily damaged.")
     icas = randrange(10, 30)
     prout(_("***Sickbay reports %d casualties"), icas)
     game.casual += icas
     game.state.crew -= icas
-    #
     # In the pre-SST2K version, all devices got equiprobably damaged,
     # which was silly.  Instead, pick up to half the devices at
     # random according to our weighting table,
-    # 
     ncrits = randrange(NDEVICES/2)
     for m in range(ncrits):
        dev = randdevice()
@@ -1294,31 +1287,26 @@ def collision(rammed, enemy):
        finish(FWON)
     return
 
-def torpedo(course, dispersion, origin, number, nburst):
-    # let a photon torpedo fly 
-    iquad = 0
+def torpedo(origin, course, dispersion, number, nburst):
+    "Let a photon torpedo fly" 
     shoved = False
     ac = course + 0.25*dispersion
     angle = (15.0-ac)*0.5235988
     bullseye = (15.0 - course)*0.5235988
-    deltax = -math.sin(angle);
-    deltay = math.cos(angle);
+    delta = coord(-math.sin(angle), math.cos(angle))          
+    bigger = max(abs(delta.x), abs(delta.y))
+    delta /= bigger
     x = origin.x; y = origin.y
-    w = coord(); jw = coord()
-    w.x = w.y = jw.x = jw.y = 0
-    bigger = max(math.fabs(deltax), math.fabs(deltay))
-    deltax /= bigger
-    deltay /= bigger
+    w = coord(0, 0); jw = coord(0, 0)
     if not damaged(DSRSENS) or game.condition=="docked":
        setwnd(srscan_window)
     else: 
        setwnd(message_window)
     # Loop to move a single torpedo 
     for step in range(1, 15+1):
-       x += deltax
-       w.x = int(x + 0.5)
-       y += deltay
-       w.y = int(y + 0.5)
+       x += delta.x
+       y += delta.y
+       w = coord(x, y).snaptogrid()
        if not VALID_SECTOR(w.x, w.y):
            break
        iquad=game.quad[w.x][w.y]
@@ -1331,9 +1319,7 @@ def torpedo(course, dispersion, origin, number, nburst):
            skip(1);    # start new line after text track 
        if iquad in (IHE, IHF): # Hit our ship 
            skip(1)
-           proutn(_("Torpedo hits "))
-           crmshp()
-           prout(".")
+           prout(_("Torpedo hits %s.") % crmshp())
            hit = 700.0 + randreal(100) - \
                1000.0 * (w-origin).distance() * math.fabs(math.sin(bullseye-angle))
            newcnd(); # we're blown out of dock 
@@ -1357,20 +1343,19 @@ def torpedo(course, dispersion, origin, number, nburst):
                # can't move into object 
                return hit
            game.sector = jw
-           crmshp()
+           proutn(crmshp())
            shoved = True
        elif iquad in (IHC, IHS): # Hit a commander 
            if withprob(0.05):
-               crmena(True, iquad, "sector", w)
-               prout(_(" uses anti-photon device;"))
+               prout(crmena(True, iquad, "sector", w) + _(" uses anti-photon device;"))
                prout(_("   torpedo neutralized."))
                return None
        elif iquad in (IHR, IHK): # Hit a regular enemy 
            # find the enemy 
             for enemy in game.enemies:
-               if w == game.enemies[ll].kloc:
+               if w == enemy.kloc:
                    break
-           kp = math.fabs(e.kpower)
+           kp = math.fabs(enemy.kpower)
            h1 = 700.0 + randrange(100) - \
                1000.0 * (w-origin).distance() * math.fabs(math.sin(bullseye-angle))
            h1 = math.fabs(h1)
@@ -1383,7 +1368,7 @@ def torpedo(course, dispersion, origin, number, nburst):
            if enemy.kpower == 0:
                deadkl(w, iquad, w)
                return None
-           crmena(True, iquad, "sector", w)
+           proutn(crmena(True, iquad, "sector", w))
            # If enemy damaged but not destroyed, try to displace 
            ang = angle + 2.5*(randreal()-0.5)
            temp = math.fabs(math.sin(ang))
@@ -1420,8 +1405,7 @@ def torpedo(course, dispersion, origin, number, nburst):
            newcnd()
            return None
        elif iquad == IHP: # Hit a planet 
-           crmena(True, iquad, "sector", w)
-           prout(_(" destroyed."))
+           prout(crmena(True, iquad, "sector", w) + _(" destroyed."))
            game.state.nplankl += 1
            game.state.galaxy[game.quadrant.x][game.quadrant.y].planet = None
            game.iplnet.pclass = "destroyed"
@@ -1433,8 +1417,7 @@ def torpedo(course, dispersion, origin, number, nburst):
                finish(FDPLANET)
            return None
        elif iquad == IHW: # Hit an inhabited world -- very bad! 
-           crmena(True, iquad, "sector", w)
-           prout(_(" destroyed."))
+           prout(crmena(True, iquad, "sector", w) + _(" destroyed."))
            game.state.nworldkl += 1
            game.state.galaxy[game.quadrant.x][game.quadrant.y].planet = None
            game.iplnet.pclass = "destroyed"
@@ -1451,8 +1434,7 @@ def torpedo(course, dispersion, origin, number, nburst):
            if withprob(0.9):
                nova(w)
             else:
-                crmena(True, IHSTAR, "sector", w)
-                prout(_(" unaffected by photon blast."))
+                prout(crmena(True, IHSTAR, "sector", w) + _(" unaffected by photon blast."))
            return None
        elif iquad == IHQUEST: # Hit a thingy 
            if not (game.options & OPTION_THINGY) or withprob(0.3):
@@ -1466,18 +1448,15 @@ def torpedo(course, dispersion, origin, number, nburst):
                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 = True
                shoved = True
            return None
        elif iquad == IHBLANK: # Black hole 
            skip(1)
-           crmena(True, IHBLANK, "sector", w)
-           prout(_(" swallows torpedo."))
+           prout(crmena(True, IHBLANK, "sector", w) + _(" swallows torpedo."))
            return None
        elif iquad == IHWEB: # hit the web 
            skip(1)
@@ -1493,7 +1472,7 @@ def torpedo(course, dispersion, origin, number, nburst):
                game.tholian = None
                return None
            skip(1)
-           crmena(True, IHT, "sector", w)
+           proutn(crmena(True, IHT, "sector", w))
            if withprob(0.05):
                prout(_(" survives photon blast."))
                return None
@@ -1505,7 +1484,7 @@ def torpedo(course, dispersion, origin, number, nburst):
         else: # Problem!
            skip(1)
            proutn("Don't know how to handle torpedo collision with ")
-           crmena(True, iquad, "sector", w)
+           proutn(crmena(True, iquad, "sector", w))
            skip(1)
            return None
        break
@@ -1524,7 +1503,7 @@ def torpedo(course, dispersion, origin, number, nburst):
     return None;
 
 def fry(hit):
-    # critical-hit resolution 
+    "Critical-hit resolution." 
     if hit < (275.0-25.0*game.skill)*randreal(1.0, 1.5):
        return
     ncrit = int(1.0 + hit/(500.0+randreal(100)))
@@ -1556,12 +1535,12 @@ def fry(hit):
 def attack(torps_ok):
     # bad guy attacks us 
     # torps_ok == False forces use of phasers in an attack 
+    # game could be over at this point, check
+    if game.alldone:
+       return
     attempt = False; ihurt = False;
     hitmax=0.0; hittot=0.0; chgfac=1.0
     where = "neither"
-    # game could be over at this point, check 
-    if game.alldone:
-       return
     if idebug:
        prout("=== ATTACK!")
     # Tholian gets to move before attacking 
@@ -1617,13 +1596,12 @@ def attack(torps_ok):
            hit = 0
            proutn(_("***TORPEDO INCOMING"))
            if not damaged(DSRSENS):
-               proutn(_(" From "))
-               crmena(False, enemy.type, where, enemy.kloc)
+               proutn(_(" From ") + crmena(False, enemy.type, where, enemy.kloc))
            attempt = True
            prout("  ")
            dispersion = (randreal()+randreal())*0.5 - 0.5
            dispersion += 0.002*enemy.kpower*dispersion
-           hit = torpedo(course, dispersion, origin=enemy.kloc, number=1, nburst=1)
+           hit = torpedo(enemy.kloc, course, dispersion, number=1, nburst=1)
            if (game.state.remkl + len(game.state.kcmdr) + game.state.nscrem)==0:
                finish(FWON); # Klingons did themselves in! 
            if game.state.galaxy[game.quadrant.x][game.quadrant.y].supernova or game.alldone:
@@ -1654,11 +1632,9 @@ def attack(torps_ok):
        ihurt = True
        proutn(_("%d unit hit") % int(hit))
        if (damaged(DSRSENS) and usephasers) or game.skill<=SKILL_FAIR:
-           proutn(_(" on the "))
-           crmshp()
+           proutn(_(" on the ") + crmshp())
        if not damaged(DSRSENS) and usephasers:
-           proutn(_(" from "))
-           crmena(False, enemy.type, where, enemy.kloc)
+           prout(_(" from ") + crmena(False, enemy.type, where, enemy.kloc))
        skip(1)
        # Decide if hit is critical 
        if hit > hitmax:
@@ -1677,7 +1653,7 @@ def attack(torps_ok):
        # Shields fully protect ship 
        proutn(_("Enemy attack reduces shield strength to "))
     else:
-       # Print message if starship suffered hit(s) 
+       # Emit message if starship suffered hit(s) 
        skip(1)
        proutn(_("Energy left %2d    shields ") % int(game.energy))
        if game.shldup:
@@ -1703,9 +1679,9 @@ def attack(torps_ok):
     return
                
 def deadkl(w, type, mv):
-    # kill a Klingon, Tholian, Romulan, or Thingy 
+    "Kill a Klingon, Tholian, Romulan, or Thingy." 
     # Added mv to allow enemy to "move" before dying 
-    crmena(True, type, "sector", mv)
+    proutn(crmena(True, type, "sector", mv))
     # Decide what kind of enemy it is and update appropriately 
     if type == IHR:
         # chalk up a Romulan 
@@ -1752,23 +1728,26 @@ def deadkl(w, type, mv):
     return
 
 def targetcheck(w):
-    # Return None if target is invalid, otherwise return a course angle
+    "Return None if target is invalid, otherwise return a course angle."
     if not VALID_SECTOR(w.x, w.y):
        huh()
        return None
-    delta = 0.1*(w - game.sector)
-    if delta.x==0 and delta.y== 0:
+    delta = coord()
+    # FIXME: C code this was translated from is wacky -- why the sign reversal?
+    delta.y = (w.y - game.sector.y);
+    delta.x = (game.sector.x - w.x);
+    if delta == coord(0, 0):
        skip(1)
        prout(_("Spock-  \"Bridge to sickbay.  Dr. McCoy,"))
        prout(_("  I recommend an immediate review of"))
        prout(_("  the Captain's psychological profile.\""))
        scanner.chew()
        return None
-    return delta.bearing()
+    return 1.90985932*math.atan2(delta.y, delta.x)
 
 def photon():
-    # launch photon torpedo
-    course = [0.0] * MAXBURST
+    "Launch photon torpedo."
+    course = []
     game.ididit = False
     if damaged(DPHOTON):
        prout(_("Photon tubes damaged."))
@@ -1778,16 +1757,17 @@ def photon():
        prout(_("No torpedoes left."))
        scanner.chew()
        return
-    key = scanner.next()
+    # First, get torpedo count
     while True:
-       if key == IHALPHA:
+        scanner.next()
+       if scanner.token == IHALPHA:
            huh()
            return
-       elif key == IHEOL:
+       elif scanner.token == IHEOL or not scanner.waiting():
            prout(_("%d torpedoes left.") % game.torps)
             scanner.chew()
            proutn(_("Number of torpedoes to fire- "))
-           key = scanner.next()
+            continue   # Go back around to get a number
        else: # key == IHREAL
            n = scanner.int()
            if n <= 0: # abort command 
@@ -1796,56 +1776,42 @@ def photon():
            if n > MAXBURST:
                scanner.chew()
                prout(_("Maximum of %d torpedoes per burst.") % MAXBURST)
-               key = IHEOL
                return
-           if n <= game.torps:
-               break
-           scanner.chew()
-           key = IHEOL
-    targ = []
-    for i in range(MAXBURST):
-        targ.append(coord())
+            if n > game.torps:
+                scanner.chew() # User requested more torps than available
+                continue       # Go back around
+            break      # All is good, go to next stage
+    # Next, get targets
+    target = []
     for i in range(n):
        key = scanner.next()
        if i==0 and key == IHEOL:
-           break;      # we will try prompting 
+           break;      # no coordinate waiting, we will try prompting 
        if i==1 and key == IHEOL:
            # direct all torpedoes at one target 
-           while i <= n:
-               targ[i] = targ[0]
-               course[i] = course[0]
+           while i < n:
+               target.append(targets[0])
+               course.append(course[0])
                i += 1
            break
-       if key != IHREAL:
-           huh()
-           return
-       targ[i].x = scanner.int()
-       key = scanner.next()
-       if key != IHREAL:
-           huh()
-           return
-       targ[i].y = scanner.int()
-       course[i] = targetcheck(targ[i])
+        scanner.push(key)
+        target.append(scanner.getcoord())
+        if target[-1] == None:
+            return
+        course.append(targetcheck(target[1]))
         if course[i] == None:
            return
     scanner.chew()
-    if i == 0 and key == IHEOL:
+    if i == 0:
        # prompt for each one 
        for i in range(n):
            proutn(_("Target sector for torpedo number %d- ") % (i+1))
-           key = scanner.next()
-           if key != IHREAL:
-               huh()
-               return
-           targ[i].x = scanner.int()
-           key = scanner.next()
-           if key != IHREAL:
-               huh()
-               return
-           targ[i].y = scanner.int()
            scanner.chew()
-            course[i] = targetcheck(targ[i])
-            if course[i] == None:
+            target.append(scanner.getcoord())
+            if target[-1] == None:
+                return
+            course.append(targetcheck(target[-1]))
+            if course[-1] == None:
                 return
     game.ididit = True
     # Loop for moving <n> torpedoes 
@@ -1869,14 +1835,14 @@ def photon():
            break
        if game.shldup or game.condition == "docked":
            dispersion *= 1.0 + 0.0001*game.shield
-       torpedo(course[i], dispersion, origin=game.sector, number=i, nburst=n)
+       torpedo(game.sector, course[i], dispersion, number=i, nburst=n)
        if game.alldone or game.state.galaxy[game.quadrant.x][game.quadrant.y].supernova:
            return
     if (game.state.remkl + len(game.state.kcmdr) + game.state.nscrem)==0:
        finish(FWON);
 
 def overheat(rpow):
-    # check for phasers overheating 
+    "Check for phasers overheating."
     if rpow > 1500:
         checkburn = (rpow-1500.0)*0.00038
         if withprob(checkburn):
@@ -1884,7 +1850,7 @@ def overheat(rpow):
            game.damage[DPHASER] = game.damfac* randreal(1.0, 2.0) * (1.0+checkburn)
 
 def checkshctrl(rpow):
-    # check shield control 
+    "Check shield control."
     skip(1)
     if withprob(0.998):
        prout(_("Shields lowered."))
@@ -1920,11 +1886,10 @@ def checkshctrl(rpow):
     return True;
 
 def hittem(hits):
-    # register a phaser hit on Klingons and Romulans
+    "Register a phaser hit on Klingons and Romulans."
     nenhr2 = len(game.enemies); kk=0
     w = coord()
     skip(1)
-    print "Hits are:", hits
     for (k, wham) in enumerate(hits):
        if wham==0:
            continue
@@ -1949,7 +1914,7 @@ def hittem(hits):
        ienm = game.quad[w.x][w.y]
        if ienm==IHQUEST:
            thing.angry = True
-       crmena(False, ienm, "sector", w)
+       proutn(crmena(False, ienm, "sector", w))
        skip(1)
        if kpow == 0:
            deadkl(w, ienm, w)
@@ -1968,7 +1933,7 @@ def hittem(hits):
     return
 
 def phasers():
-    # fire phasers 
+    "Fire phasers at bad guys."
     hits = []
     kz = 0; k = 1; irec=0 # Cheating inhibitor 
     ifast = False; no = False; itarg = True; msgflag = True; rpow=0
@@ -2138,8 +2103,7 @@ def phasers():
                rpow = 0.0
            if damaged(DSRSENS) and \
                not game.sector.distance(aim)<2**0.5 and ienm in (IHC, IHS):
-               cramen(ienm)
-               prout(_(" can't be located without short range scan."))
+               prout(cramen(ienm) + _(" can't be located without short range scan."))
                scanner.chew()
                key = IHEOL
                hits[k] = 0; # prevent overflow -- thanks to Alexei Voitenko 
@@ -2156,9 +2120,7 @@ def phasers():
                else:
                    proutn("??")
                proutn(")  ")
-               proutn(_("units to fire at "))
-               crmena(False, ienm, "sector", aim)
-               proutn("-  ")
+               proutn(_("units to fire at %s-  ") % crmena(False, ienm, "sector", aim))                
                key = scanner.next()
            if key == IHALPHA and scanner.sees("no"):
                no = True
@@ -2223,29 +2185,29 @@ def phasers():
 # BSD Trek, from which we swiped the idea, can have up to 5.
 
 def unschedule(evtype):
-    # remove an event from the schedule 
+    "Remove an event from the schedule."
     game.future[evtype].date = FOREVER
     return game.future[evtype]
 
 def is_scheduled(evtype):
-    # is an event of specified type scheduled 
+    "Is an event of specified type scheduled."
     return game.future[evtype].date != FOREVER
 
 def scheduled(evtype):
-    # when will this event happen? 
+    "When will this event happen?"
     return game.future[evtype].date
 
 def schedule(evtype, offset):
-    # schedule an event of specified type
+    "Schedule an event of specified type."
     game.future[evtype].date = game.state.date + offset
     return game.future[evtype]
 
 def postpone(evtype, offset):
-    # postpone a scheduled event 
+    "Postpone a scheduled event."
     game.future[evtype].date += offset
 
 def cancelrest():
-    # rest period is interrupted by event 
+    "Rest period is interrupted by event."
     if game.resting:
        skip(1)
        proutn(_("Mr. Spock-  \"Captain, shall we cancel the rest period?\""))
@@ -2256,7 +2218,7 @@ def cancelrest():
     return False
 
 def events():
-    # run through the event queue looking for things to do 
+    "Run through the event queue looking for things to do."
     i=0
     fintim = game.state.date + game.optime; yank=0
     ictbeam = False; istract = False
@@ -2264,13 +2226,11 @@ def events():
     ev = event(); ev2 = event()
 
     def tractorbeam(yank):
-        # tractor beaming cases merge here 
+        "Tractor-beaming cases merge here." 
         announce()
         game.optime = (10.0/(7.5*7.5))*yank # 7.5 is yank rate (warp 7.5) 
         skip(1)
-        proutn("***")
-        crmshp()
-        prout(_(" caught in long range tractor beam--"))
+        prout("***" + crmshp() + _(" caught in long range tractor beam--"))
         # If Kirk & Co. screwing around on planet, handle 
         atover(True) # atover(true) is Grab 
         if game.alldone:
@@ -2293,8 +2253,7 @@ def events():
         else:
             game.quadrant = game.state.kcmdr[i]
         game.sector = randplace(QUADSIZE)
-        crmshp()
-        prout(_(" is pulled to Quadrant %s, Sector %s") \
+        prout(crmshp() + _(" is pulled to Quadrant %s, Sector %s") \
                % (game.quadrant, game.sector))
         if game.resting:
             prout(_("(Remainder of rest/repair period cancelled.)"))
@@ -2305,7 +2264,7 @@ def events():
                 game.shldchg = False
             else:
                 prout(_("(Shields not currently useable.)"))
-        newqad(False)
+        newqad()
         # Adjust finish time to time of tractor beaming 
         fintim = game.state.date+game.optime
         attack(torps_ok=False)
@@ -2315,7 +2274,7 @@ def events():
             schedule(FTBEAM, game.optime+expran(1.5*game.intime/len(game.state.kcmdr)))
 
     def destroybase():
-        # Code merges here for any commander destroying base 
+        "Code merges here for any commander destroying a starbase." 
         # Not perfect, but will have to do 
         # Handle case where base is in same quadrant as starship 
         if game.battle == game.quadrant:
@@ -2345,7 +2304,6 @@ def events():
             game.isatb = 0
         else:
             game.battle.invalidate()
-
     if idebug:
        prout("=== EVENTS from %.2f to %.2f:" % (game.state.date, fintim))
        for i in range(1, NEVENTS):
@@ -2641,8 +2599,7 @@ def events():
                     else:
                         continue       # search for eligible quadrant failed
                 except "FOUNDIT":
-                    w.x = i
-                    w.y = j
+                    w.x = i; w.y = j
            # deliver the child 
            game.state.remkl += 1
            q.klingons += 1
@@ -2663,7 +2620,7 @@ def events():
                    prout(_("in Quadrant %s.") % w)
                                
 def wait():
-    # wait on events 
+    "Wait on events."
     game.ididit = False
     while True:
        key = scanner.next()
@@ -2721,7 +2678,7 @@ def wait():
 # If the zap is too much, it gets destroyed.
         
 def nova(nov):
-    # star goes nova 
+    "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(); neighbor = coord(); bump = coord(0, 0)
     if withprob(0.05):
@@ -2730,8 +2687,7 @@ def nova(nov):
        return
     # handle initial nova 
     game.quad[nov.x][nov.y] = IHDOT
-    crmena(False, IHSTAR, "sector", nov)
-    prout(_(" novas."))
+    prout(crmena(False, IHSTAR, "sector", nov) + _(" novas."))
     game.state.galaxy[game.quadrant.x][game.quadrant.y].stars -= 1
     game.state.starkl += 1
     # Set up queue to recursively trigger adjacent stars 
@@ -2760,7 +2716,7 @@ def nova(nov):
                         hits.append(neighbor)
                        game.state.galaxy[game.quadrant.x][game.quadrant.y].stars -= 1
                        game.state.starkl += 1
-                       crmena(True, IHSTAR, "sector", neighbor)
+                       proutn(crmena(True, IHSTAR, "sector", neighbor))
                        prout(_(" novas."))
                         game.quad[neighbor.x][neighbor.y] = IHDOT
                         kount += 1
@@ -2770,8 +2726,7 @@ def nova(nov):
                         game.state.nplankl += 1
                     else:
                         game.state.worldkl += 1
-                    crmena(True, iquad, "sector", neighbor)
-                    prout(_(" destroyed."))
+                    prout(crmena(True, IHB, "sector", neighbor) + _(" destroyed."))
                     game.iplnet.pclass = "destroyed"
                     game.iplnet = None
                     game.plnet.invalidate()
@@ -2785,8 +2740,7 @@ def nova(nov):
                     game.base.invalidate()
                     game.state.basekl += 1
                     newcnd()
-                    crmena(True, IHB, "sector", neighbor)
-                    prout(_(" destroyed."))
+                    prout(crmena(True, IHB, "sector", neighbor) + _(" destroyed."))
                     game.quad[neighbor.x][neighbor.y] = IHDOT
                 elif iquad in (IHE, IHF): # Buffet ship 
                     prout(_("***Starship buffeted by nova."))
@@ -2818,16 +2772,14 @@ def nova(nov):
                         deadkl(neighbor, iquad, neighbor)
                         break
                     newc = neighbor + neighbor - hits[mm]
-                    crmena(True, iquad, "sector", neighbor)
-                    proutn(_(" damaged"))
+                    proutn(crmena(True, iquad, "sector", neighbor) + _(" damaged"))
                     if not VALID_SECTOR(newc.x, newc.y):
                         # can't leave quadrant 
                         skip(1)
                         break
                     iquad1 = game.quad[newc.x][newc.y]
                     if iquad1 == IHBLANK:
-                        proutn(_(", blasted into "))
-                        crmena(False, IHBLANK, "sector", newc)
+                        proutn(_(", blasted into ") + crmena(False, IHBLANK, "sector", newc))
                         skip(1)
                         deadkl(neighbor, iquad, newc)
                         break
@@ -2854,7 +2806,7 @@ def nova(nov):
     return
        
 def supernova(induced, w=None):
-    # star goes supernova 
+    "Star goes supernova."
     num = 0; npdead = 0
     nq = coord()
     if w != None: 
@@ -2960,8 +2912,7 @@ def supernova(induced, w=None):
 # Code from finish.c ends here.
 
 def selfdestruct():
-    # self-destruct maneuver 
-    # Finish with a BANG! 
+    "Self-destruct maneuver. Finish with a BANG!" 
     scanner.chew()
     if damaged(DCOMPTR):
        prout(_("Computer damaged; cannot execute destruct sequence."))
@@ -3003,9 +2954,7 @@ def kaboom():
     stars()
     if game.ship==IHE:
        prouts("***")
-    prouts(_("********* Entropy of "))
-    crmshp()
-    prouts(_(" maximized *********"))
+    prouts(_("********* Entropy of %s maximized *********") % crmshp())
     skip(1)
     stars()
     skip(1)
@@ -3134,9 +3083,7 @@ def finish(ifin):
        skip(1)
        prout(_("Your starship is a derelict in space."))
     elif ifin == FBATTLE:
-       proutn(_("The "))
-       crmshp()
-       prout(_(" has been destroyed in battle."))
+       prout(_("The %s has been destroyed in battle.") % crmshp())
        skip(1)
        prout(_("Dulce et decorum est pro patria mori."))
     elif ifin == FNEG3:
@@ -3150,9 +3097,7 @@ def finish(ifin):
        prout(_("That was a great shot."))
        skip(1)
     elif ifin == FSNOVAED:
-       proutn(_("The "))
-       crmshp()
-       prout(_(" has been fried by a supernova."))
+       prout(_("The %s has been fried by a supernova.") % crmshp())
        prout(_("...Not even cinders remain..."))
     elif ifin == FABANDN:
        prout(_("You have been captured by the Klingons. If you still"))
@@ -3165,9 +3110,7 @@ def finish(ifin):
        prout(_("Starbase was unable to re-materialize your starship."))
        prout(_("Sic transit gloria mundi"))
     elif ifin == FPHASER:
-       proutn(_("The "))
-       crmshp()
-       prout(_(" has been cremated by its own phasers."))
+       prout(_("The %s has been cremated by its own phasers.") % crmshp())
     elif ifin == FLOST:
        prout(_("You and your landing party have been"))
        prout(_("converted to energy, disipating through space."))
@@ -3177,9 +3120,7 @@ def finish(ifin):
        skip(1)
        prout(_("They are very fond of \"Captain Kirk\" soup."))
        skip(1)
-       proutn(_("Without your leadership, the "))
-       crmshp()
-       prout(_(" is destroyed."))
+       prout(_("Without your leadership, the %s is destroyed.") % crmshp())
     elif ifin == FDPLANET:
        prout(_("You and your mining party perish."))
        skip(1)
@@ -3189,25 +3130,19 @@ def finish(ifin):
        prout(_("The Galileo is instantly annihilated by the supernova."))
        prout(_("You and your mining party are atomized."))
        skip(1)
-       proutn(_("Mr. Spock takes command of the "))
-       crmshp()
-       prout(_(" and"))
-       prout(_("joins the Romulans, reigning terror on the Federation."))
+       prout(_("Mr. Spock takes command of the %s and") % crmshp())
+       prout(_("joins the Romulans, wreaking terror on the Federation."))
     elif ifin == FPNOVA:
        prout(_("You and your mining party are atomized."))
        skip(1)
-       proutn(_("Mr. Spock takes command of the "))
-       crmshp()
-       prout(_(" and"))
-       prout(_("joins the Romulans, reigning terror on the Federation."))
+       prout(_("Mr. Spock takes command of the %s and") % crmshp())
+       prout(_("joins the Romulans, wreaking terror on the Federation."))
     elif ifin == FSTRACTOR:
        prout(_("The shuttle craft Galileo is also caught,"))
        prout(_("and breaks up under the strain."))
        skip(1)
        prout(_("Your debris is scattered for millions of miles."))
-       proutn(_("Without your leadership, the "))
-       crmshp()
-       prout(_(" is destroyed."))
+       prout(_("Without your leadership, the %s is destroyed.") % crmshp())
     elif ifin == FDRAY:
        prout(_("The mutants attack and kill Spock."))
        prout(_("Your ship is captured by Klingons, and"))
@@ -3251,7 +3186,7 @@ def finish(ifin):
     score()
 
 def score():
-    # compute player's score 
+    "Compute player's score."
     timused = game.state.date - game.indate
     iskill = game.skill
     if (timused == 0 or (game.state.remkl + len(game.state.kcmdr) + game.state.nscrem) != 0) and timused < 5.0:
@@ -3336,7 +3271,7 @@ def score():
     prout(_("TOTAL SCORE                               %5d") % iscore)
 
 def plaque():
-    # emit winner's commemmorative plaque 
+    "Emit winner's commemmorative plaque." 
     skip(2)
     while True:
         proutn(_("File or device name for your plaque: "))
@@ -3408,7 +3343,7 @@ prompt_window     = None
 curwnd = None
 
 def outro():
-    "wrap up, either normally or due to signal"
+    "Wrap up, either normally or due to signal"
     if game.options & OPTION_CURSES:
        #clear()
        #curs_set(1)
@@ -3479,10 +3414,7 @@ def waitfor():
 
 def announce():
     skip(1)
-    if game.skill > SKILL_FAIR:
-       prouts(_("[ANOUNCEMENT ARRIVING...]"))
-    else:
-       prouts(_("[IMPORTANT ANNOUNCEMENT ARRIVING -- PRESS ENTER TO CONTINUE]"))
+    prouts(_("[ANOUNCEMENT ARRIVING...]"))
     skip(1)
 
 def pause_game():
@@ -3542,7 +3474,7 @@ def prout(line):
     skip(1)
 
 def prouts(line):
-    "print slowly!" 
+    "Emit slowly!" 
     for c in line:
         if not replayfp or replayfp.closed:    # Don't slow down replays
             time.sleep(0.03)
@@ -3722,7 +3654,7 @@ def prstat(txt, data):
 # Code from moving.c begins here
 
 def imove(novapush):
-    # movement execution for warp, impulse, supernova, and tractor-beam events 
+    "Movement execution for warp, impulse, supernova, and tractor-beam events."
     w = coord(); final = coord()
     trbeam = False
 
@@ -3834,7 +3766,7 @@ def imove(novapush):
                skip(1)
                prout(_("Entering Quadrant %s.") % game.quadrant)
                game.quad[game.sector.x][game.sector.y] = game.ship
-               newqad(False)
+               newqad()
                if game.skill>SKILL_NOVICE:
                    attack(torps_ok=False)  
                return
@@ -3854,8 +3786,7 @@ def imove(novapush):
                    skip(1)
                    prouts(_("***RED ALERT!  RED ALERT!"))
                    skip(1)
-                   proutn("***")
-                   crmshp()
+                   proutn("***" + crmshp())
                    proutn(_(" pulled into black hole at Sector %s") % w)
                    #
                    # Getting pulled into a black hole was certain
@@ -3875,7 +3806,7 @@ def imove(novapush):
                else:
                    # something else 
                    skip(1)
-                   crmshp()
+                   proutn(crmshp())
                    if iquad == IHWEB:
                        prout(_(" encounters Tholian web at %s;") % w)
                    else:
@@ -3899,7 +3830,7 @@ def imove(novapush):
     return
 
 def dock(verbose):
-    # dock our ship at a starbase 
+    "Dock our ship at a starbase."
     scanner.chew()
     if game.condition == "docked" and verbose:
        prout(_("Already docked."))
@@ -3908,8 +3839,7 @@ def dock(verbose):
        prout(_("You must first leave standard orbit."))
        return
     if not game.base.is_valid() or abs(game.sector.x-game.base.x) > 1 or abs(game.sector.y-game.base.y) > 1:
-       crmshp()
-       prout(_(" not adjacent to base."))
+       prout(crmshp() + _(" not adjacent to base."))
        return
     game.condition = "docked"
     if "verbose":
@@ -3937,7 +3867,7 @@ def dock(verbose):
 # are always displayed y - x, where +y is downward!
 
 def getcourse(isprobe, akey):
-    # get course and distance
+    "Get a course and distance from the user."
     key = 0
     dquad = copy.copy(game.quadrant)
     navmode = "unspecified"
@@ -4056,12 +3986,12 @@ def getcourse(isprobe, akey):
        if key != IHREAL:
            huh()
            return False
-       delta.x = scanner.real
+       delta.y = scanner.real
        key = scanner.next()
        if key != IHREAL:
            huh()
            return False
-       delta.y = scanner.real
+       delta.x = scanner.real
     # Check for zero movement 
     if delta.x == 0 and delta.y == 0:
        scanner.chew()
@@ -4078,7 +4008,7 @@ def getcourse(isprobe, akey):
     return True
 
 def impulse():
-    # move under impulse power 
+    "Move under impulse power."
     game.ididit = False
     if damaged(DIMPULS):
        scanner.chew()
@@ -4125,7 +4055,7 @@ def impulse():
     return
 
 def warp(timewarp):
-    # move under warp drive 
+    "ove under warp drive."
     blooey = False; twarp = False
     if not timewarp: # Not WARPX entry 
        game.ididit = False
@@ -4204,7 +4134,6 @@ def warp(timewarp):
                bigger = math.fabs(deltax)
            else:
                bigger = math.fabs(deltay)
-                       
            deltax /= bigger
            deltay /= bigger
            n = 10.0 * game.dist * bigger +0.5
@@ -4240,7 +4169,7 @@ def warp(timewarp):
     return
 
 def setwarp():
-    # change the warp factor   
+    "Change the warp factor."
     while True:
         key=scanner.next()
         if key != IHEOL:
@@ -4281,7 +4210,7 @@ def setwarp():
     return
 
 def atover(igrab):
-    # cope with being tossed out of quadrant by supernova or yanked by beam 
+    "Cope with being tossed out of quadrant by supernova or yanked by beam."
     scanner.chew()
     # is captain on planet? 
     if game.landed:
@@ -4319,13 +4248,10 @@ def atover(igrab):
        if game.justin:
            prouts(_("***RED ALERT!  RED ALERT!"))
            skip(1)
-           proutn(_("The "))
-           crmshp()
-           prout(_(" has stopped in a quadrant containing"))
+           proutn(_("The %s has stopped in a quadrant containing") % crmshp())
            prouts(_("   a supernova."))
            skip(2)
-       proutn(_("***Emergency automatic override attempts to hurl "))
-       crmshp()
+       prout(_("***Emergency automatic override attempts to hurl ")+crmshp())
        skip(1)
        prout(_("safely out of quadrant."))
        if not damaged(DRADIO):
@@ -4364,7 +4290,7 @@ def atover(igrab):
        finish(FWON) # Snova killed remaining enemy. 
 
 def timwrp():
-    # let's do the time warp again 
+    "Let's do the time warp again."
     prout(_("***TIME WARP ENTERED."))
     if game.state.snap and withprob(0.5):
        # Go back in time 
@@ -4400,10 +4326,8 @@ def timwrp():
        if game.iscraft == "offship" and not gotit and game.damage[DSHUTTL] >= 0.0:
            prout(_("Checkov-  \"Security reports the Galileo has reappeared in the dock!\""))
            game.iscraft = "onship"
-       # 
-#       * There used to be code to do the actual reconstrction here,
-#       * but the starchart is now part of the snapshotted galaxy state.
-#       
+        # 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 
@@ -4412,11 +4336,11 @@ def timwrp():
        # cheat to make sure no tractor beams occur during time warp 
        postpone(FTBEAM, game.optime)
        game.damage[DRADIO] += game.optime
-    newqad(False)
+    newqad()
     events()   # Stas Sergeev added this -- do pending events 
 
 def probe():
-    # launch deep-space probe 
+    "Launch deep-space probe." 
     # New code to launch a deep space probe 
     if game.nprobes == 0:
        scanner.chew()
@@ -4496,7 +4420,7 @@ def probe():
 # problem.
 
 def mayday():
-    # yell for help from nearest starbase 
+    "Yell for help from nearest starbase."
     # There's more than one way to move in this game! 
     scanner.chew()
     # Test for conditions which prevent calling for help 
@@ -4510,9 +4434,7 @@ def mayday():
        prout(_("Lt. Uhura-  \"Captain, I'm not getting any response from Starbase.\""))
        return
     if game.landed:
-       proutn(_("You must be aboard the "))
-       crmshp()
-       prout(".")
+       prout(_("You must be aboard the %s.") % crmshp())
        return
     # OK -- call for help from nearest starbase 
     game.nhelp += 1
@@ -4527,16 +4449,15 @@ def mayday():
                ddist = xdist
        # Since starbase not in quadrant, set up new quadrant 
        game.quadrant = ibq
-       newqad(True)
+       newqad()
     # dematerialize starship 
     game.quad[game.sector.x][game.sector.y]=IHDOT
-    proutn(_("Starbase in Quadrant %s responds--") % game.quadrant)
-    crmshp()
-    prout(_(" dematerializes."))
-    game.sector.x=0
+    proutn(_("Starbase in Quadrant %s responds--%s dematerializes") \
+           % (game.quadrant, crmshp()))
+    game.sector.invalidate()
     for m in range(1, 5+1):
         w = game.base.scatter() 
-       if VALID_SECTOR(ix,iy) and game.quad[ix][iy]==IHDOT:
+       if VALID_SECTOR(w.x,w.y) and game.quad[w.x][w.y]==IHDOT:
            # found one -- finish up 
             game.sector = w
            break
@@ -4550,8 +4471,7 @@ def mayday():
        if m == 1: proutn(_("1st"))
        elif m == 2: proutn(_("2nd"))
        elif m == 3: proutn(_("3rd"))
-       proutn(_(" attempt to re-materialize "))
-       crmshp()
+       proutn(_(" attempt to re-materialize ") + crmshp())
        game.quad[ix][iy]=(IHMATER0,IHMATER1,IHMATER2)[m-1]
        textcolor("red")
        warble()
@@ -4594,7 +4514,7 @@ def mayday():
 # can't happen unless you have taken some prisoners.
 
 def abandon():
-    # abandon ship 
+    "Abandon ship."
     scanner.chew()
     if game.condition=="docked":
        if game.ship!=IHE:
@@ -4617,7 +4537,7 @@ def abandon():
        if game.iscraft != "onship":
            prout(_("Shuttle craft not currently available."))
            return
-       # Print abandon ship messages 
+       # Emit abandon ship messages 
        skip(1)
        prouts(_("***ABANDON SHIP!  ABANDON SHIP!"))
        skip(1)
@@ -4641,7 +4561,6 @@ def abandon():
                    game.state.crew)
            game.casual += game.state.crew
            game.abandoned += game.state.crew
-
        # If at least one base left, give 'em the Faerie Queene 
        skip(1)
        game.icrystl = False # crystals are lost 
@@ -4653,7 +4572,7 @@ def abandon():
        if not game.quadrant == game.state.baseq[nb]:
            game.quadrant = game.state.baseq[nb]
            game.sector.x = game.sector.y = 5
-           newqad(True)
+           newqad()
        while True:
            # position next to base by trial and error 
            game.quad[game.sector.x][game.sector.y] = IHDOT
@@ -4666,7 +4585,7 @@ def abandon():
                break # found a spot 
            game.sector.x=QUADSIZE/2
            game.sector.y=QUADSIZE/2
-           newqad(True)
+           newqad()
     # Get new commission 
     game.quad[game.sector.x][game.sector.y] = game.ship = IHF
     game.state.crew = FULLCREW
@@ -4694,7 +4613,7 @@ def abandon():
 # Code from planets.c begins here.
 
 def consumeTime():
-    # abort a lengthy operation if an event interrupts it 
+    "Abort a lengthy operation if an event interrupts it." 
     game.ididit = True
     events()
     if game.alldone or game.state.galaxy[game.quadrant.x][game.quadrant.y].supernova or game.justin: 
@@ -4702,7 +4621,7 @@ def consumeTime():
     return False
 
 def survey():
-    # report on (uninhabited) planets in the galaxy 
+    "Report on (uninhabited) planets in the galaxy."
     iknow = False
     skip(1)
     scanner.chew()
@@ -4730,7 +4649,7 @@ def survey():
        prout(_("No information available."))
 
 def orbit():
-    # enter standard orbit 
+    "Enter standard orbit." 
     skip(1)
     scanner.chew()
     if game.inorbit:
@@ -4743,8 +4662,7 @@ def orbit():
         prout("There is no planet in this sector.")
         return
     if abs(game.sector.x-game.plnet.x)>1 or abs(game.sector.y-game.plnet.y)>1:
-       crmshp()
-       prout(_(" not adjacent to planet."))
+       prout(crmshp() + _(" not adjacent to planet."))
        skip(1)
        return
     game.optime = randreal(0.02, 0.05)
@@ -4758,7 +4676,7 @@ def orbit():
     game.ididit = True
 
 def sensor():
-    # examine planets in this quadrant 
+    "Examine planets in this quadrant."
     if damaged(DSRSENS):
        if game.options & OPTION_TTY:
            prout(_("Short range sensors damaged."))
@@ -4785,7 +4703,7 @@ def sensor():
         prout(_("        is located at Sector %s, Captain.\"") % game.plnet)
 
 def beam():
-    # use the transporter 
+    "Use the transporter."
     nrgneed = 0
     scanner.chew()
     skip(1)
@@ -4798,8 +4716,7 @@ def beam():
                shuttle()
        return
     if not game.inorbit:
-       crmshp()
-       prout(_(" not in standard orbit."))
+       prout(crmshp() + _(" not in standard orbit."))
        return
     if game.shldup:
        prout(_("Impossible to transport through shields."))
@@ -4877,7 +4794,7 @@ def beam():
     return
 
 def mine():
-    # strip-mine a world for dilithium 
+    "Strip-mine a world for dilithium."
     skip(1)
     scanner.chew()
     if not game.landed:
@@ -4893,9 +4810,7 @@ def mine():
        prout(_("You've already mined enough crystals for this trip."))
        return
     if game.icrystl and game.cryprob == 0.05:
-       proutn(_("With all those fresh crystals aboard the "))
-       crmshp()
-       skip(1)
+       prout(_("With all those fresh crystals aboard the ") + crmshp())
        prout(_("there's no reason to mine more at this time."))
        return
     game.optime = randreal(0.1, 0.3)*(ord(game.iplnet.pclass)-ord("L"))
@@ -4906,7 +4821,7 @@ def mine():
     game.imine = game.ididit = True
 
 def usecrystals():
-    # use dilithium crystals 
+    "Use dilithium crystals."
     game.ididit = False
     skip(1)
     scanner.chew()
@@ -4952,7 +4867,7 @@ def usecrystals():
     game.ididit = True
 
 def shuttle():
-    # use shuttlecraft for planetary jaunt 
+    "Use shuttlecraft for planetary jaunt."
     scanner.chew()
     skip(1)
     if damaged(DSHUTTL):
@@ -4967,8 +4882,7 @@ def shuttle():
            prout(_("Shuttle craft is now serving Big Macs."))
        return
     if not game.inorbit:
-       crmshp()
-       prout(_(" not in standard orbit."))
+       prout(crmshp() + _(" not in standard orbit."))
        return
     if (game.iplnet.known != "shuttle_down") and game.iscraft != "onship":
        prout(_("Shuttle craft not currently available."))
@@ -5036,8 +4950,7 @@ def shuttle():
            prout(_("Trip complete."))
            return
     else:
-       # Kirk on ship 
-       # and so is Galileo 
+       # Kirk on ship and so is Galileo 
        prout(_("Mining party assembles in the hangar deck,"))
        prout(_("ready to board the shuttle craft \"Galileo\"."))
        skip(1)
@@ -5054,7 +4967,7 @@ def shuttle():
        return
 
 def deathray():
-    # use the big zapper 
+    "Use the big zapper."
     game.ididit = False
     skip(1)
     scanner.chew()
@@ -5159,7 +5072,7 @@ def deathray():
 # Code from reports.c begins here
 
 def attackreport(curt):
-    # report status of bases under attack 
+    "eport status of bases under attack."
     if not curt:
        if is_scheduled(FCDBAS):
            prout(_("Starbase in Quadrant %s is currently under Commander attack.") % game.battle)
@@ -5247,7 +5160,7 @@ def report():
     skip(1)
        
 def lrscan(silent):
-    # long-range sensor scan 
+    "Long-range sensor scan."
     if damaged(DLRSENS):
        # Now allow base's sensors if docked 
        if game.condition != "docked":
@@ -5278,7 +5191,7 @@ def lrscan(silent):
        prout(" ")
 
 def damagereport():
-    # damage report 
+    "Damage report."
     jdam = False
     scanner.chew()
 
@@ -5295,7 +5208,7 @@ def damagereport():
        prout(_("All devices functional."))
 
 def rechart():
-    # update the chart in the Enterprise's computer from galaxy data 
+    "Update the chart in the Enterprise's computer from galaxy data."
     game.lastchart = game.state.date
     for i in range(GALSIZE):
        for j in range(GALSIZE):
@@ -5305,7 +5218,7 @@ def rechart():
                game.state.chart[i][j].stars = game.state.galaxy[i][j].stars
 
 def chart():
-    # display the star chart  
+    "Display the star chart."
     scanner.chew()
     if (game.options & OPTION_AUTOSCAN):
         lrscan(silent=True)
@@ -5314,7 +5227,6 @@ def chart():
     if game.lastchart < game.state.date and game.condition == "docked":
        prout(_("Spock-  \"I revised the Star Chart from the starbase's records.\""))
        rechart()
-
     prout(_("       STAR CHART FOR THE KNOWN GALAXY"))
     if game.state.date > game.lastchart:
        prout(_("(Last surveillance update %d stardates ago).") % ((int)(game.state.date-game.lastchart)))
@@ -5344,7 +5256,7 @@ def chart():
            skip(1)
 
 def sectscan(goodScan, i, j):
-    # light up an individual dot in a sector 
+    "Light up an individual dot in a sector."
     if goodScan or (abs(i-game.sector.x)<= 1 and abs(j-game.sector.y) <= 1):
        if (game.quad[i][j]==IHMATER0) or (game.quad[i][j]==IHMATER1) or (game.quad[i][j]==IHMATER2) or (game.quad[i][j]==IHE) or (game.quad[i][j]==IHF):
            if game.condition   == "red": textcolor("red")
@@ -5360,8 +5272,7 @@ def sectscan(goodScan, i, j):
        proutn("- ")
 
 def status(req=0):
-    # print status report lines 
-
+    "Emit status report lines"
     if not req or req == 1:
        prstat(_("Stardate"), _("%.1f, Time Left %.2f") \
                % (game.state.date, game.state.remtime))
@@ -5417,6 +5328,7 @@ def status(req=0):
        attackreport(not req)
 
 def request():
+    "Request specified status data, a historical relic from slow TTYs."
     requests = ("da","co","po","ls","wa","en","to","sh","kl","sy", "ti")
     while scanner.next() == IHEOL:
        proutn(_("Information desired? "))
@@ -5429,7 +5341,7 @@ def request():
        prout(("  energy, torpedoes, shields, klingons, system, time."))
                
 def srscan():
-    # short-range scan 
+    "Short-range scan." 
     goodScan=True
     if damaged(DSRSENS):
        # Allow base's sensors if docked 
@@ -5455,7 +5367,7 @@ def srscan():
        skip(1)
                        
 def eta():
-    # use computer to get estimated time of arrival for a warp jump 
+    "Use computer to get estimated time of arrival for a warp jump."
     w1 = coord(); w2 = coord()
     prompt = False
     if damaged(DCOMPTR):
@@ -5575,12 +5487,11 @@ def eta():
            scanner.chew()
            skip(1)
            return
-                       
 
 # Code from setup.c begins here
 
 def prelim():
-    # issue a historically correct banner 
+    "Issue a historically correct banner."
     skip(2)
     prout(_("-SUPER- STAR TREK"))
     skip(1)
@@ -5589,7 +5500,7 @@ def prelim():
 #    skip(1)
 
 def freeze(boss):
-    # save game 
+    "Save game."
     if boss:
        scanner.token = "emsave.trk"
     else:
@@ -5612,7 +5523,7 @@ def freeze(boss):
     fp.close()
 
 def thaw():
-    # retrieve saved game 
+    "Retrieve saved game." 
     game.passwd[0] = '\0'
     key = scanner.next()
     if key == IHEOL:
@@ -5705,7 +5616,7 @@ device = (
 )
 
 def setup():
-    # prepare to play, set up cosmos 
+    "Prepare to play, set up cosmos."
     w = coord()
     #  Decide how many of everything
     if choose():
@@ -5856,9 +5767,14 @@ def setup():
     unschedule(FENSLV)
     unschedule(FREPRO)
     # 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:
-        thing = randplace(GALSIZE)
+        while True:
+            thing = randplace(GALSIZE)
+            if thing not in game.state.baseq:
+                break
     skip(2)
     game.state.snap = False
     if game.skill == SKILL_NOVICE:
@@ -5891,14 +5807,14 @@ def setup():
     if game.state.nscrem:
        prout(_("  YOU'LL NEED IT."))
     waitfor()
-    newqad(False)
+    newqad()
     if len(game.enemies) - (thing == game.quadrant) - (game.tholian != 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
+    "Choose your game type."
     global thing
     while True:
        game.tourn = 0
@@ -5984,8 +5900,7 @@ def choose():
     setpassword()
     if game.passwd == "debug":
        idebug = True
-       fputs("=== Debug mode enabled\n", sys.stdout)
-
+       prout("=== Debug mode enabled.")
     # Use parameters to generate initial values of things
     game.damfac = 0.5 * game.skill
     game.inbase = randrange(BASEMIN, BASEMAX+1)
@@ -6007,8 +5922,7 @@ def choose():
     return False
 
 def dropin(iquad=None):
-    # drop a feature on a random dot in the current quadrant 
-    w = coord()
+    "Drop a feature on a random dot in the current quadrant."
     while True:
         w = randplace(QUADSIZE)
         if game.quad[w.x][w.y] == IHDOT:
@@ -6018,7 +5932,7 @@ def dropin(iquad=None):
     return w
 
 def newcnd():
-    # update our alert status 
+    "Update our alert status."
     game.condition = "green"
     if game.energy < 1000.0:
        game.condition = "yellow"
@@ -6028,21 +5942,15 @@ def newcnd():
        game.condition="dead"
 
 def newkling():
-    # drop new Klingon into current quadrant
+    "Drop new Klingon into current quadrant."
     return enemy(IHK, loc=dropin(), power=randreal(300,450)+25.0*game.skill)
 
-def newqad(shutup):
-    # set up a new state of quadrant, for when we enter or re-enter it 
-    w = coord()
+def newqad():
+    "Set up a new state of quadrant, for when we enter or re-enter it."
     game.justin = True
-    game.klhere = 0
-    game.irhere = 0
-    game.iplnet = 0
-    game.neutz = False
-    game.inorbit = False
-    game.landed = False
-    game.ientesc = False
-    game.iseenit = False
+    game.iplnet = None
+    game.neutz = game.inorbit = game.landed = False
+    game.ientesc = game.iseenit = False
     # Create a blank quadrant
     game.quad = fill2d(QUADSIZE, lambda i, j: IHDOT)
     if game.iscate:
@@ -6100,15 +6008,14 @@ 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
-       if thing == game.quadrant:
-           enemy(type=IHQUEST, loc=dropin(),
-                      power=randreal(6000,6500.0)+250.0*game.skill)
-           if not damaged(DSRSENS):
-               skip(1)
-               prout(_("Mr. Spock- \"Captain, this is most unusual."))
-               prout(_("    Please examine your short-range scan.\""))
+    # Put in THING if needed
+    if thing == game.quadrant:
+        enemy(type=IHQUEST, loc=dropin(),
+                  power=randreal(6000,6500.0)+250.0*game.skill)
+        if not damaged(DSRSENS):
+            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 withprob(0.02)) or \
@@ -6151,7 +6058,7 @@ def newqad(shutup):
            game.quad[QUADSIZE-1][QUADSIZE-1] = IHDOT
 
 def setpassword():
-    # set the self-destruct password 
+    "Set the self-destruct password."
     if game.options & OPTION_PLAIN:
        while True:
            scanner.chew()
@@ -6209,23 +6116,18 @@ commands = {
     "HELP":            0,
 }
 
-def ACCEPT(cmd):       return (not commands[cmd] or (commands[cmd] & game.options))
-
 def listCommands():
-    # generate a list of legal commands 
-    k = 0
+    "Generate a list of legal commands."
     proutn(_("LEGAL COMMANDS ARE:"))
-    for key in commands:
-       if ACCEPT(key):
+    for (k, key) in enumerate(commands):
+       if not commands[cmd] or (commands[key] & game.options):
             if k % 5 == 0:
                 skip(1)
             proutn("%-12s " % key) 
-            k += 1
     skip(1)
 
 def helpme():
-    # browse on-line help 
-    # Give help on commands 
+    "Browse on-line help."
     key = scanner.next()
     while True:
        if key == IHEOL:
@@ -6281,8 +6183,7 @@ def helpme():
     fp.close()
 
 def makemoves():
-    # command-interpretation loop 
-    v = 0
+    "Command-interpretation loop."
     clrscr()
     setwnd(message_window)
     while True:        # command loop 
@@ -6439,48 +6340,41 @@ def makemoves():
     if idebug:
        prout("=== Ending")
 
-def cramen(cmd):
-    # return an enemy 
-    if   cmd == IHR: s = _("Romulan")
-    elif cmd == IHK: s = _("Klingon")
-    elif cmd == IHC: s = _("Commander")
-    elif cmd == IHS: s = _("Super-commander")
-    elif cmd == IHSTAR: s = _("Star")
-    elif cmd == IHP: s = _("Planet")
-    elif cmd == IHB: s = _("Starbase")
-    elif cmd == IHBLANK: s = _("Black hole")
-    elif cmd == IHT: s = _("Tholian")
-    elif cmd == IHWEB: s = _("Tholian web")
-    elif cmd == IHQUEST: s = _("Stranger")
-    elif cmd == IHW: s = _("Inhabited World")
+def cramen(type):
+    "Emit the name of an enemy or feature." 
+    if   type == IHR: s = _("Romulan")
+    elif type == IHK: s = _("Klingon")
+    elif type == IHC: s = _("Commander")
+    elif type == IHS: s = _("Super-commander")
+    elif type == IHSTAR: s = _("Star")
+    elif type == IHP: s = _("Planet")
+    elif type == IHB: s = _("Starbase")
+    elif type == IHBLANK: s = _("Black hole")
+    elif type == IHT: s = _("Tholian")
+    elif type == IHWEB: s = _("Tholian web")
+    elif type == IHQUEST: s = _("Stranger")
+    elif type == IHW: s = _("Inhabited World")
     else: s = "Unknown??"
-    proutn(s)
+    return s
 
 def crmena(stars, enemy, loctype, w):
-    # print an enemy and his location 
-    if stars:
-       proutn("***")
-    cramen(enemy)
-    proutn(_(" at "))
+    "Emit the name of an enemy and his location."
     buf = ""
+    if stars:
+       buf += "***"
+    buf += cramen(enemy) + _(" at ")
     if loctype == "quadrant":
-       buf = _("Quadrant ")
+       buf += _("Quadrant ")
     elif loctype == "sector":
-       buf = _("Sector ")
-    proutn(buf + `w`)
+       buf += _("Sector ")
+    return buf + `w`
 
 def crmshp():
-    # print our ship name 
-    if game.ship == IHE:
-        s = _("Enterprise")
-    elif game.ship == IHF:
-        s = _("Faerie Queene")
-    else:
-        s = "Ship???"
-    proutn(s)
+    "Emit our ship name." 
+    return{IHE:_("Enterprise"),IHF:_("Faerie Queene")}.get(game.ship,"Ship???")
 
 def stars():
-    # print a line of stars 
+    "Emit a line of stars" 
     prouts("******************************************************")
     skip(1)
 
@@ -6488,7 +6382,7 @@ def expran(avrage):
     return -avrage*math.log(1e-7 + randreal())
 
 def randplace(size):
-    # choose a random location  
+    "Choose a random location."
     w = coord()
     w.x = randrange(size) 
     w.y = randrange(size)
@@ -6535,15 +6429,17 @@ class sstscanner:
         self.type = IHALPHA
         self.real = None
         return IHALPHA
-    def push(self, toklist):
-        self.inqueue += toklist
+    def push(self, tok):
+        self.inqueue.append(tok)
+    def waiting(self):
+        return self.inqueue
     def chew(self):
         # Demand input for next scan
-        self.inqueue = None
+        self.inqueue = []
         self.real = self.token = None
     def chew2(self):
         # return IHEOL next time 
-        self.inqueue = []
+        self.inqueue = [IHEOL]
         self.real = self.token = None
     def sees(self, s):
         # compares s to item and returns true if it matches to the length of s
@@ -6551,9 +6447,22 @@ class sstscanner:
     def int(self):
         # Round token value to nearest integer
         return int(round(scanner.real))
+    def getcoord(self):
+        s = coord()
+        scanner.next()
+       if scanner.type != IHREAL:
+           huh()
+           return None
+       s.x = scanner.int()-1
+        scanner.next()
+       if scanner.type != IHREAL:
+           huh()
+           return None
+       s.y = scanner.int()-1
+        return s
 
 def ja():
-    # yes-or-no confirmation 
+    "Yes-or-no confirmation."
     scanner.chew()
     while True:
        scanner.next()
@@ -6565,13 +6474,13 @@ def ja():
        proutn(_("Please answer with \"y\" or \"n\": "))
 
 def huh():
-    # complain about unparseable input 
+    "Complain about unparseable input."
     scanner.chew()
     skip(1)
     prout(_("Beg your pardon, Captain?"))
 
 def debugme():
-    # access to the internals for debugging 
+    "Access to the internals for debugging."
     proutn("Reset levels? ")
     if ja() == True:
        if game.energy < game.inenrg:
@@ -6594,9 +6503,7 @@ def debugme():
     proutn("Cause selective damage? ")
     if ja() == True:
        for i in range(NDEVICES):
-           proutn("Kill ")
-           proutn(device[i])
-           proutn("? ")
+           proutn("Kill %s?" % device[i])
            scanner.chew()
            key = scanner.next()
             if key == IHALPHA and scanner.sees("y"):
@@ -6714,7 +6621,7 @@ if __name__ == '__main__':
             logfp.write("# options %s\n" % " ".join(arguments))
         random.seed(seed)
         scanner = sstscanner()
-        scanner.push(arguments)
+        map(scanner.push, arguments)
         try:
             iostart()
             while True: # Play a game