Silence some compile warnings.
[super-star-trek.git] / src / sst.py
index 920fbd13b66c5d24165a92a3d415f69bb3a0315e..a3455bfbf20e076b7c6439e1ecf5422cefadd0ec 100644 (file)
@@ -13,8 +13,7 @@ ion how to modify (and how not to modify!) this code.
 """
 import os, sys, math, curses, time, readline, cPickle, random, copy, gettext, getpass
 
 """
 import os, sys, math, curses, time, readline, cPickle, random, copy, gettext, getpass
 
-SSTDOC         = "/usr/share/doc/sst/sst.doc"
-DOC_NAME       = "sst.doc"
+docpath        = (".", "../doc", "/usr/share/doc/sst")
 
 def _(str): return gettext.gettext(str)
 
 
 def _(str): return gettext.gettext(str)
 
@@ -33,6 +32,24 @@ MINCMDR      = 10            # Minimum number of Klingon commanders
 DOCKFAC                = 0.25          # Repair faster when docked
 PHASEFAC       = 2.0           # Unclear what this is, it was in the C version
 
 DOCKFAC                = 0.25          # Repair faster when docked
 PHASEFAC       = 2.0           # Unclear what this is, it was in the C version
 
+DEFAULT      = -1
+BLACK        = 0
+BLUE         = 1
+GREEN        = 2
+CYAN         = 3
+RED          = 4
+MAGENTA      = 5
+BROWN        = 6
+LIGHTGRAY    = 7
+DARKGRAY     = 8
+LIGHTBLUE    = 9
+LIGHTGREEN   = 10
+LIGHTCYAN    = 11
+LIGHTRED     = 12
+LIGHTMAGENTA = 13
+YELLOW       = 14
+WHITE        = 15
+
 class TrekError:
     pass
 
 class TrekError:
     pass
 
@@ -183,6 +200,7 @@ OPTION_WORLDS       = 0x00000800    # logic for inhabited worlds (ESR, 2006)
 OPTION_AUTOSCAN        = 0x00001000    # automatic LRSCAN before CHART (ESR, 2006)
 OPTION_PLAIN   = 0x01000000    # user chose plain game 
 OPTION_ALMY    = 0x02000000    # user chose Almy variant 
 OPTION_AUTOSCAN        = 0x00001000    # automatic LRSCAN before CHART (ESR, 2006)
 OPTION_PLAIN   = 0x01000000    # user chose plain game 
 OPTION_ALMY    = 0x02000000    # user chose Almy variant 
+OPTION_COLOR    = 0x04000000   # enable color display (experimental, ESR, 2010)
 
 # Define devices 
 DSRSENS        = 0
 
 # Define devices 
 DSRSENS        = 0
@@ -319,7 +337,7 @@ class gamestate:
         self.iplnet = None     # planet # in quadrant
         self.inplan = 0                # initial planets
         self.irhere = 0                # Romulans in quadrant
         self.iplnet = None     # planet # in quadrant
         self.inplan = 0                # initial planets
         self.irhere = 0                # Romulans in quadrant
-        self.isatb = 0         # =1 if super commander is attacking base
+        self.isatb = 0         # =2 if super commander is attacking base
         self.tourn = None      # tournament number
         self.nprobes = 0       # number of probes available
         self.inresor = 0.0     # initial resources
         self.tourn = None      # tournament number
         self.nprobes = 0       # number of probes available
         self.inresor = 0.0     # initial resources
@@ -649,7 +667,7 @@ def movescom(iq, avoid):
     game.state.kscmdr = iq
     game.state.galaxy[game.state.kscmdr.i][game.state.kscmdr.j].klingons += 1
     if game.state.kscmdr==game.quadrant:
     game.state.kscmdr = iq
     game.state.galaxy[game.state.kscmdr.i][game.state.kscmdr.j].klingons += 1
     if game.state.kscmdr==game.quadrant:
-       # SC has scooted, Remove him from current quadrant 
+       # SC has scooted, remove him from current quadrant 
        game.iscate=False
        game.isatb=0
        game.ientesc = False
        game.iscate=False
        game.isatb=0
        game.ientesc = False
@@ -870,7 +888,6 @@ def doshield(shraise):
        if action=="NONE":
            proutn(_("Do you wish to change shield energy? "))
            if ja() == True:
        if action=="NONE":
            proutn(_("Do you wish to change shield energy? "))
            if ja() == True:
-               proutn(_("Energy to transfer to shields- "))
                action = "NRG"
            elif damaged(DSHIELD):
                prout(_("Shields damaged and down."))
                action = "NRG"
            elif damaged(DSHIELD):
                prout(_("Shields damaged and down."))
@@ -918,21 +935,22 @@ def doshield(shraise):
        while scanner.next() != "IHREAL":
            scanner.chew()
            proutn(_("Energy to transfer to shields- "))
        while scanner.next() != "IHREAL":
            scanner.chew()
            proutn(_("Energy to transfer to shields- "))
+        nrg = scanner.real
        scanner.chew()
        scanner.chew()
-       if scanner.real == 0:
+       if nrg == 0:
            return
            return
-       if scanner.real > game.energy:
+       if nrg > game.energy:
            prout(_("Insufficient ship energy."))
            return
        game.ididit = True
            prout(_("Insufficient ship energy."))
            return
        game.ididit = True
-       if game.shield+scanner.real >= game.inshld:
+       if game.shield+nrg >= game.inshld:
            prout(_("Shield energy maximized."))
            prout(_("Shield energy maximized."))
-           if game.shield+scanner.real > game.inshld:
+           if game.shield+nrg > game.inshld:
                prout(_("Excess energy requested returned to ship energy"))
            game.energy -= game.inshld-game.shield
            game.shield = game.inshld
            return
                prout(_("Excess energy requested returned to ship energy"))
            game.energy -= game.inshld-game.shield
            game.shield = game.inshld
            return
-       if scanner.real < 0.0 and game.energy-scanner.real > game.inenrg:
+       if nrg < 0.0 and game.energy-nrg > game.inenrg:
            # Prevent shield drain loophole 
            skip(1)
            prout(_("Engineering to bridge--"))
            # Prevent shield drain loophole 
            skip(1)
            prout(_("Engineering to bridge--"))
@@ -940,18 +958,18 @@ def doshield(shraise):
            prout(_("  I can't drain the shields."))
            game.ididit = False
            return
            prout(_("  I can't drain the shields."))
            game.ididit = False
            return
-       if game.shield+scanner.real < 0:
+       if game.shield+nrg < 0:
            prout(_("All shield energy transferred to ship."))
            game.energy += game.shield
            game.shield = 0.0
            return
        proutn(_("Scotty- \""))
            prout(_("All shield energy transferred to ship."))
            game.energy += game.shield
            game.shield = 0.0
            return
        proutn(_("Scotty- \""))
-       if scanner.real > 0:
+       if nrg > 0:
            prout(_("Transferring energy to shields.\""))
        else:
            prout(_("Draining energy from shields.\""))
            prout(_("Transferring energy to shields.\""))
        else:
            prout(_("Draining energy from shields.\""))
-       game.shield += scanner.real
-       game.energy -= scanner.real
+       game.shield += nrg
+       game.energy -= nrg
        return
 
 def randdevice():
        return
 
 def randdevice():
@@ -970,11 +988,12 @@ def randdevice():
        15,     # DCOMPTR: computer                      1.5% 
        20,     # NAVCOMP: navigation system             2.0% 
        75,     # DTRANSP: transporter                   7.5% 
        15,     # DCOMPTR: computer                      1.5% 
        20,     # NAVCOMP: navigation system             2.0% 
        75,     # DTRANSP: transporter                   7.5% 
-       20,     # DSHCTRL: high-speed shield controller 2.0% 
+       20,     # DSHCTRL: high-speed shield controller  2.0% 
        10,     # DDRAY: death ray                       1.0% 
        30,     # DDSP: deep-space probes                3.0% 
     )
        10,     # DDRAY: death ray                       1.0% 
        30,     # DDSP: deep-space probes                3.0% 
     )
-    idx = randrange(1000)      # weights must sum to 1000 
+    assert(sum(weights) == 1000)
+    idx = randrange(1000)
     sum = 0
     for (i, w) in enumerate(weights):
        sum += w
     sum = 0
     for (i, w) in enumerate(weights):
        sum += w
@@ -1463,8 +1482,8 @@ def targetcheck(w):
        return None
     return delta.bearing()
 
        return None
     return delta.bearing()
 
-def photon():
-    "Launch photon torpedo."
+def torps():
+    "Launch photon torpedo salvo."
     course = []
     game.ididit = False
     if damaged(DPHOTON):
     course = []
     game.ididit = False
     if damaged(DPHOTON):
@@ -2326,7 +2345,7 @@ def events():
                else:
                    prout(_("Uhura- Starfleet reports increased Klingon activity"))
                    if q.planet != None:
                else:
                    prout(_("Uhura- Starfleet reports increased Klingon activity"))
                    if q.planet != None:
-                       proutn(_("near %s") % q.planet)
+                       proutn(_("near %s ") % q.planet)
                    prout(_("in Quadrant %s.") % w)
                                
 def wait():
                    prout(_("in Quadrant %s.") % w)
                                
 def wait():
@@ -2904,8 +2923,6 @@ def score():
        klship = 1
     else:
        klship = 2
        klship = 1
     else:
        klship = 2
-    if not game.gamewon:
-       game.state.nromrem = 0 # None captured if no win
     iscore = 10*(game.inkling - game.state.remkl) \
              + 50*(game.incom - len(game.state.kcmdr)) \
              + ithperd + iwon \
     iscore = 10*(game.inkling - game.state.remkl) \
              + 50*(game.incom - len(game.state.kcmdr)) \
              + ithperd + iwon \
@@ -2920,7 +2937,7 @@ def score():
     if game.inrom - game.state.nromrem:
        prout(_("%6d Romulans destroyed                 %5d") %
              (game.inrom - game.state.nromrem, 20*(game.inrom - game.state.nromrem)))
     if game.inrom - game.state.nromrem:
        prout(_("%6d Romulans destroyed                 %5d") %
              (game.inrom - game.state.nromrem, 20*(game.inrom - game.state.nromrem)))
-    if game.state.nromrem:
+    if game.state.nromrem and game.gamewon:
        prout(_("%6d Romulans captured                  %5d") %
              (game.state.nromrem, game.state.nromrem))
     if game.inkling - game.state.remkl:
        prout(_("%6d Romulans captured                  %5d") %
              (game.state.nromrem, game.state.nromrem))
     if game.inkling - game.state.remkl:
@@ -2943,7 +2960,7 @@ def score():
              (game.state.nplankl, -10*game.state.nplankl))
     if (game.options & OPTION_WORLDS) and game.state.nworldkl:
        prout(_("%6d inhabited planets destroyed by your action   %5d") %
              (game.state.nplankl, -10*game.state.nplankl))
     if (game.options & OPTION_WORLDS) and game.state.nworldkl:
        prout(_("%6d inhabited planets destroyed by your action   %5d") %
-             (game.state.nplankl, -300*game.state.nworldkl))
+             (game.state.nworldkl, -300*game.state.nworldkl))
     if game.state.basekl:
        prout(_("%6d bases destroyed by your action     %5d") %
              (game.state.basekl, -100*game.state.basekl))
     if game.state.basekl:
        prout(_("%6d bases destroyed by your action     %5d") %
              (game.state.basekl, -100*game.state.basekl))
@@ -3059,6 +3076,17 @@ def iostart():
        stdscr.keypad(True)
        curses.nonl()
        curses.cbreak()
        stdscr.keypad(True)
        curses.nonl()
        curses.cbreak()
+        if game.options & OPTION_COLOR:
+            curses.start_color();
+            curses.use_default_colors()
+            curses.init_pair(curses.COLOR_BLACK,   curses.COLOR_BLACK, -1);
+            curses.init_pair(curses.COLOR_GREEN,   curses.COLOR_GREEN, -1);
+            curses.init_pair(curses.COLOR_RED,     curses.COLOR_RED, -1);
+            curses.init_pair(curses.COLOR_CYAN,    curses.COLOR_CYAN, -1);
+            curses.init_pair(curses.COLOR_WHITE,   curses.COLOR_WHITE, -1);
+            curses.init_pair(curses.COLOR_MAGENTA, curses.COLOR_MAGENTA, -1);
+            curses.init_pair(curses.COLOR_BLUE,    curses.COLOR_BLUE, -1);
+            curses.init_pair(curses.COLOR_YELLOW,  curses.COLOR_YELLOW, -1);
         global fullscreen_window, srscan_window, report_window, status_window
         global lrscan_window, message_window, prompt_window
         (rows, columns)   = stdscr.getmaxyx()
         global fullscreen_window, srscan_window, report_window, status_window
         global lrscan_window, message_window, prompt_window
         (rows, columns)   = stdscr.getmaxyx()
@@ -3205,7 +3233,48 @@ def clrscr():
        curwnd.move(0, 0)
        curwnd.refresh()
     linecount = 0
        curwnd.move(0, 0)
        curwnd.refresh()
     linecount = 0
-    
+
+def textcolor(color=DEFAULT):
+    if game.options & OPTION_COLOR:
+       if color == DEFAULT: 
+           curwnd.attrset(0);
+       elif color ==  BLACK: 
+           curwnd.attron(curses.color_pair(curses.COLOR_BLACK));
+       elif color ==  BLUE: 
+           curwnd.attron(curses.color_pair(curses.COLOR_BLUE));
+       elif color ==  GREEN: 
+           curwnd.attron(curses.color_pair(curses.COLOR_GREEN));
+       elif color ==  CYAN: 
+           curwnd.attron(curses.color_pair(curses.COLOR_CYAN));
+       elif color ==  RED: 
+           curwnd.attron(curses.color_pair(curses.COLOR_RED));
+       elif color ==  MAGENTA: 
+           curwnd.attron(curses.color_pair(curses.COLOR_MAGENTA));
+       elif color ==  BROWN: 
+           curwnd.attron(curses.color_pair(curses.COLOR_YELLOW));
+       elif color ==  LIGHTGRAY: 
+           curwnd.attron(curses.color_pair(curses.COLOR_WHITE));
+       elif color ==  DARKGRAY: 
+           curwnd.attron(curses.color_pair(curses.COLOR_BLACK) | curses.A_BOLD);
+       elif color ==  LIGHTBLUE: 
+           curwnd.attron(curses.color_pair(curses.COLOR_BLUE) | curses.A_BOLD);
+       elif color ==  LIGHTGREEN: 
+           curwnd.attron(curses.color_pair(curses.COLOR_GREEN) | curses.A_BOLD);
+       elif color ==  LIGHTCYAN: 
+           curwnd.attron(curses.color_pair(curses.COLOR_CYAN) | curses.A_BOLD);
+       elif color ==  LIGHTRED: 
+           curwnd.attron(curses.color_pair(curses.COLOR_RED) | curses.A_BOLD);
+       elif color ==  LIGHTMAGENTA: 
+           curwnd.attron(curses.color_pair(curses.COLOR_MAGENTA) | curses.A_BOLD);
+       elif color ==  YELLOW: 
+           curwnd.attron(curses.color_pair(curses.COLOR_YELLOW) | curses.A_BOLD);
+       elif color ==  WHITE:
+           curwnd.attron(curses.color_pair(curses.COLOR_WHITE) | curses.A_BOLD);
+
+def highvideo():
+    if game.options & OPTION_COLOR:
+        curwnd.attron(curses.A_REVERSE)
+
 #
 # Things past this point have policy implications.
 # 
 #
 # Things past this point have policy implications.
 # 
@@ -4108,10 +4177,12 @@ def mayday():
        elif m == 3: proutn(_("3rd"))
        proutn(_(" attempt to re-materialize ") + crmshp())
        game.quad[ix][iy]=('-','o','O')[m-1]
        elif m == 3: proutn(_("3rd"))
        proutn(_(" attempt to re-materialize ") + crmshp())
        game.quad[ix][iy]=('-','o','O')[m-1]
+        textcolor(RED)
        warble()
        if randreal() > probf:
            break
        prout(_("fails."))
        warble()
        if randreal() > probf:
            break
        prout(_("fails."))
+        textcolor(DEFAULT)
        curses.delay_output(500)
     if m > 3:
        game.quad[ix][iy]='?'
        curses.delay_output(500)
     if m > 3:
        game.quad[ix][iy]='?'
@@ -4121,7 +4192,9 @@ def mayday():
        finish(FMATERIALIZE)
        return
     game.quad[ix][iy]=game.ship
        finish(FMATERIALIZE)
        return
     game.quad[ix][iy]=game.ship
+    textcolor(GREEN);
     prout(_("succeeds."))
     prout(_("succeeds."))
+    textcolor(DEFAULT);
     dock(False)
     skip(1)
     prout(_("Lt. Uhura-  \"Captain, we made it!\""))
     dock(False)
     skip(1)
     prout(_("Lt. Uhura-  \"Captain, we made it!\""))
@@ -4460,7 +4533,7 @@ def usecrystals():
     skip(1)
     prouts(_("Scotty-  \"Keep your fingers crossed, Sir!\""))
     skip(1)
     skip(1)
     prouts(_("Scotty-  \"Keep your fingers crossed, Sir!\""))
     skip(1)
-    if with(game.cryprob):
+    if withprob(game.cryprob):
        prouts(_("  \"Activating now! - - No good!  It's***"))
        skip(2)
        prouts(_("***RED ALERT!  RED A*L********************************"))
        prouts(_("  \"Activating now! - - No good!  It's***"))
        skip(2)
        prouts(_("***RED ALERT!  RED A*L********************************"))
@@ -4869,7 +4942,15 @@ def chart():
 def sectscan(goodScan, i, j):
     "Light up an individual dot in a sector."
     if goodScan or (abs(i-game.sector.i)<= 1 and abs(j-game.sector.j) <= 1):
 def sectscan(goodScan, i, j):
     "Light up an individual dot in a sector."
     if goodScan or (abs(i-game.sector.i)<= 1 and abs(j-game.sector.j) <= 1):
+        textcolor({"green":GREEN,
+                   "yellow":YELLOW,
+                   "red":RED,
+                   "docked":CYAN,
+                   "dead":BROWN}[game.condition]) 
+        if game.quad[i][j] != game.ship: 
+            highvideo();
        proutn("%c " % game.quad[i][j])
        proutn("%c " % game.quad[i][j])
+        textcolor(DEFAULT)
     else:
        proutn("- ")
 
     else:
        proutn("- ")
 
@@ -5473,7 +5554,7 @@ def choose():
     # Choose game options -- added by ESR for SST2K
     if scanner.next() != "IHALPHA":
        scanner.chew()
     # Choose game options -- added by ESR for SST2K
     if scanner.next() != "IHALPHA":
        scanner.chew()
-       proutn(_("Choose your game style (or just press enter): "))
+       proutn(_("Choose your game style (plain, almy, fancy or just press enter): "))
        scanner.next()
     if scanner.sees("plain"):
        # Approximates the UT FORTRAN version.
        scanner.next()
     if scanner.sees("plain"):
        # Approximates the UT FORTRAN version.
@@ -5487,6 +5568,7 @@ def choose():
        pass
     elif len(scanner.token):
         proutn(_("What is \"%s\"?") % scanner.token)
        pass
     elif len(scanner.token):
         proutn(_("What is \"%s\"?") % scanner.token)
+    game.options &=~ OPTION_COLOR
     setpassword()
     if game.passwd == "debug":
        idebug = True
     setpassword()
     if game.passwd == "debug":
        idebug = True
@@ -5729,7 +5811,7 @@ def helpme():
        setwnd(message_window)
        if key == "IHEOL":
            return
        setwnd(message_window)
        if key == "IHEOL":
            return
-        if scanner.token in commands or scanner.token == "ABBREV":
+        if scanner.token.upper() in commands or scanner.token == "ABBREV":
            break
        skip(1)
        listCommands()
            break
        skip(1)
        listCommands()
@@ -5737,22 +5819,20 @@ def helpme():
        scanner.chew()
        skip(1)
     cmd = scanner.token.upper()
        scanner.chew()
        skip(1)
     cmd = scanner.token.upper()
-    try:
-        fp = open(SSTDOC, "r")
-    except IOError:
+    for directory in docpath:
         try:
         try:
-            fp = open(DOC_NAME, "r")
+            fp = open(os.path.join(directory, "sst.doc"), "r")
+            break
         except IOError:
         except IOError:
-            prout(_("Spock-  \"Captain, that information is missing from the"))
-            proutn(_("   computer. You need to find "))
-            proutn(DOC_NAME)
-            prout(_(" and put it in the"))
-            proutn(_("   current directory or to "))
-            proutn(SSTDOC)
-            prout(".\"")
-            # This used to continue: "You need to find SST.DOC and put 
-            # it in the current directory."
-            return
+            pass
+    else:
+        prout(_("Spock-  \"Captain, that information is missing from the"))
+        prout(_("   computer. You need to find sst.doc and put it somewhere"))
+        proutn(_("   in these directories: %s") % ":".join(docpath))
+        prout(".\"")
+        # This used to continue: "You need to find SST.DOC and put 
+        # it in the current directory."
+        return
     while True:
         linebuf = fp.readline()
        if linebuf == '':
     while True:
         linebuf = fp.readline()
        if linebuf == '':
@@ -5761,12 +5841,13 @@ def helpme():
            return
        if linebuf[0] == '%' and linebuf[1] == '%' and linebuf[2] == ' ':
             linebuf = linebuf[3:].strip()
            return
        if linebuf[0] == '%' and linebuf[1] == '%' and linebuf[2] == ' ':
             linebuf = linebuf[3:].strip()
-            if cmd == linebuf:
+            if cmd.upper() == linebuf:
                break
     skip(1)
     prout(_("Spock- \"Captain, I've found the following information:\""))
     skip(1)
                break
     skip(1)
     prout(_("Spock- \"Captain, I've found the following information:\""))
     skip(1)
-    while linebuf in fp:
+    while True:
+        linebuf = fp.readline()
         if "******" in linebuf:
            break
        proutn(linebuf)
         if "******" in linebuf:
            break
        proutn(linebuf)
@@ -5817,8 +5898,8 @@ def makemoves():
            phasers()
            if game.ididit:
                hitme = True
            phasers()
            if game.ididit:
                hitme = True
-       elif cmd == "TORPEDO":          # photon torpedos
-           photon()
+       elif cmd in ("TORPEDO", "PHOTONS"):     # photon torpedos
+           torps()
            if game.ididit:
                hitme = True
        elif cmd == "MOVE":             # move under warp
            if game.ididit:
                hitme = True
        elif cmd == "MOVE":             # move under warp
@@ -6199,8 +6280,12 @@ if __name__ == '__main__':
                 sys.stderr.write("usage: sst [-t] [-x] [startcommand...].\n")
                 raise SystemExit, 1
         # where to save the input in case of bugs
                 sys.stderr.write("usage: sst [-t] [-x] [startcommand...].\n")
                 raise SystemExit, 1
         # where to save the input in case of bugs
+        if "TMPDIR" in os.environ:
+            tmpdir = os.environ['TMPDIR']
+        else:
+            tmpdir = "/tmp"
         try:
         try:
-            logfp = open("/tmp/sst-input.log", "w")
+            logfp = open(os.path.join(tmpdir, "sst-input.log"), "w")
         except IOError:
             sys.stderr.write("sst: warning, can't open logfile\n")
             sys.exit(1)
         except IOError:
             sys.stderr.write("sst: warning, can't open logfile\n")
             sys.exit(1)