X-Git-Url: https://jxself.org/git/?p=super-star-trek.git;a=blobdiff_plain;f=sst.py;h=e2bf5c378288421101bbd0fdce810982e122e7e0;hp=9fb3da9c4eda16b8f6eb64478c9321b5ccc0bcfc;hb=f0e227dceb9638e3797dc28134930d114577f987;hpb=f946bf57cf69447a95ff4ef2b5e6bc32ecb9af17 diff --git a/sst.py b/sst.py index 9fb3da9..e2bf5c3 100755 --- a/sst.py +++ b/sst.py @@ -131,6 +131,8 @@ class Thingy(Coord): self.angered = False def angry(self): self.angered = True + def at(self, q): + return (q.i, q.j) == (self.i, self.j) class Planet: def __init__(self): @@ -139,7 +141,7 @@ class Planet: self.pclass = None # could be ""M", "N", "O", or "destroyed" self.crystals = "absent"# could be "mined", "present", "absent" self.known = "unknown" # could be "unknown", "known", "shuttle_down" - self.inhabited = False # is it inhabites? + self.inhabited = False # is it inhabited? def __str__(self): return self.name @@ -157,8 +159,10 @@ class Quadrant: class Page: def __init__(self): self.stars = None - self.starbase = None + self.starbase = False self.klingons = None + def __repr__(self): + return "<%s,%s,%s>" % (self.klingons, self.starbase, self.stars) def fill2d(size, fillfun): "Fill an empty list in 2D." @@ -449,19 +453,14 @@ def tryexit(enemy, look, irun): # avoid intruding on another commander's territory if enemy.type == 'C': if iq in game.state.kcmdr: - return False + return [] # refuse to leave if currently attacking starbase if game.battle == game.quadrant: - return False + return [] # don't leave if over 1000 units of energy if enemy.power > 1000.0: - return False - # 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": - prout(crmena(True, enemy.type, "sector", enemy.location) + \ - (_(" escapes to Quadrant %s (and regains strength).") % iq)) + return [] + oldloc = copy.copy(enemy.location) # handle local matters related to escape enemy.move(None) game.klhere -= 1 @@ -482,7 +481,8 @@ def tryexit(enemy, look, irun): if cmdr == game.quadrant: game.state.kcmdr.append(iq) break - return True # success + # report move out of quadrant. + return [(True, enemy, oldloc, ibq)] # The bad-guy movement algorithm: # @@ -532,8 +532,8 @@ def movebaddy(enemy): nbaddys = (((game.quadrant in game.state.kcmdr)*2 + (game.state.kscmdr==game.quadrant)*2+game.klhere*1.23+game.irhere*1.5)/2.0) else: nbaddys = (game.quadrant in game.state.kcmdr) + (game.state.kscmdr==game.quadrant) - dist1 = enemy.kdist - mdist = int(dist1 + 0.5) # Nearest integer distance + old_dist = enemy.kdist + mdist = int(old_dist + 0.5) # Nearest integer distance # If SC, check with spy to see if should hi-tail it if enemy.type == 'S' and \ (enemy.power <= 500.0 or (game.condition=="docked" and not damaged(DPHOTON))): @@ -561,14 +561,14 @@ def movebaddy(enemy): motion = ((forces + randreal(200))/150.0) - 5.0 else: if forces > 1000.0: # Very strong -- move in for kill - motion = (1.0 - randreal())**2 * dist1 + 1.0 + motion = (1.0 - randreal())**2 * old_dist + 1.0 if game.condition == "docked" and (game.options & OPTION_BASE): # protected by base -- back off ! motion -= game.skill*(2.0-randreal()**2) if game.idebug: proutn("=== MOTION = %d, FORCES = %1.2f, " % (motion, forces)) # don't move if no motion if motion == 0: - return + return [] # Limit motion according to skill if abs(motion) > game.skill: if motion < 0: @@ -612,15 +612,15 @@ def movebaddy(enemy): while attempts < 20 and not success: attempts += 1 if look.i < 0 or look.i >= QUADSIZE: - if motion < 0 and tryexit(enemy, look, irun): - return + if motion < 0: + return tryexit(enemy, look, irun) if krawli == m.i or m.j == 0: break look.i = goto.i + krawli krawli = -krawli elif look.j < 0 or look.j >= QUADSIZE: - if motion < 0 and tryexit(enemy, look, irun): - return + if motion < 0: + return tryexit(enemy, look, irun) if krawlj == m.j or m.i == 0: break look.j = goto.j + krawlj @@ -630,7 +630,7 @@ def movebaddy(enemy): if game.quad[look.i][look.j] == game.ship and \ (enemy.type == 'C' or enemy.type == 'S'): collision(rammed=True, enemy=enemy) - return + return [] if krawli != m.i and m.j != 0: look.i = goto.i + krawli krawli = -krawli @@ -649,14 +649,8 @@ def movebaddy(enemy): break # done early if game.idebug: skip(1) - if enemy.move(goto): - if not damaged(DSRSENS) or game.condition == "docked": - proutn(_("*** %s from Sector %s") % (cramen(enemy.type), enemy.location)) - if enemy.kdist < dist1: - proutn(_(" advances to ")) - else: - proutn(_(" retreats to ")) - prout("Sector %s." % goto) + # Enemy moved, but is still in sector + return [(False, enemy, old_dist, goto)] def moveklings(): "Sequence Klingon tactical movement." @@ -664,14 +658,15 @@ def moveklings(): prout("== MOVCOM") # Figure out which Klingon is the commander (or Supercommander) # and do move + tacmoves = [] if game.quadrant in game.state.kcmdr: for enemy in game.enemies: if enemy.type == 'C': - movebaddy(enemy) + tacmoves += movebaddy(enemy) if game.state.kscmdr == game.quadrant: for enemy in game.enemies: if enemy.type == 'S': - movebaddy(enemy) + tacmoves += movebaddy(enemy) break # If skill level is high, move other Klingons and Romulans too! # Move these last so they can base their actions on what the @@ -679,8 +674,8 @@ def moveklings(): if game.skill >= SKILL_EXPERT and (game.options & OPTION_MVBADDY): for enemy in game.enemies: if enemy.type in ('K', 'R'): - movebaddy(enemy) - sortenemies() + tacmoves += movebaddy(enemy) + return tacmoves def movescom(iq, avoid): "Commander movement helper." @@ -1035,7 +1030,7 @@ def randdevice(): return None # we should never get here def collision(rammed, enemy): - "Collision handling fot rammong events." + "Collision handling for rammong events." prouts(_("***RED ALERT! RED ALERT!")) skip(1) prout(_("***COLLISION IMMINENT.")) @@ -1186,8 +1181,8 @@ def torpedo(origin, bearing, dispersion, number, nburst): game.state.baseq = filter(lambda x: x != game.quadrant, game.state.baseq) game.quad[w.i][w.j] = '.' game.base.invalidate() - game.state.galaxy[game.quadrant.i][game.quadrant.j].starbase -= 1 - game.state.chart[game.quadrant.i][game.quadrant.j].starbase -= 1 + game.state.galaxy[game.quadrant.i][game.quadrant.j].starbase = False + game.state.chart[game.quadrant.i][game.quadrant.j].starbase = False game.state.basekl += 1 newcnd() return None @@ -1332,9 +1327,26 @@ def attack(torps_ok): return # commanders get a chance to tac-move towards you if (((game.quadrant in game.state.kcmdr or game.state.kscmdr == game.quadrant) and not game.justin) or game.skill == SKILL_EMERITUS) and torps_ok: - moveklings() + for (bugout, enemy, old, goto) in moveklings(): + if bugout: + # we know about this if either short or long range + # sensors are working + if damaged(DSRSENS) and damaged(DLRSENS) \ + and game.condition != "docked": + prout(crmena(True, enemy.type, "sector", old) + \ + (_(" escapes to Quadrant %s (and regains strength).") % goto)) + else: # Enemy still in-sector + if enemy.move(goto): + if not damaged(DSRSENS) or game.condition == "docked": + proutn(_("*** %s from Sector %s") % (cramen(enemy.type), enemy.location)) + if enemy.kdist < old: + proutn(_(" advances to ")) + else: + proutn(_(" retreats to ")) + prout("Sector %s." % goto) + sortenemies() # if no enemies remain after movement, we're done - if len(game.enemies) == 0 or (len(game.enemies) == 1 and thing == game.quadrant and not thing.angered): + if len(game.enemies) == 0 or (len(game.enemies) == 1 and thing.at(game.quadrant) and not thing.angered): return # set up partial hits if attack happens during shield status change pfac = 1.0/game.inshld @@ -5425,10 +5437,14 @@ def setup(): game.instar = 0 for i in range(GALSIZE): for j in range(GALSIZE): - k = randrange(1, QUADSIZE**2/10+1) + # Can't have more stars per quadrant than fit in one decimal digit, + # if we do the chart representation will break. + k = randrange(1, min(10, QUADSIZE**2/10)) game.instar += k game.state.galaxy[i][j].stars = k # Locate star bases in galaxy + if game.idebug: + prout("=== Allocating %d bases" % game.inbase) for i in range(game.inbase): while True: while True: @@ -5451,6 +5467,8 @@ def setup(): prout("=== Saving base #%d, close to #%d" % (i, j)) if not contflag: break + if game.idebug: + prout("=== Placing base #%d in quadrant %s" % (i, w)) game.state.baseq.append(w) game.state.galaxy[w.i][w.j].starbase = game.state.chart[w.i][w.j].starbase = True # Position ordinary Klingon Battle Cruisers @@ -5783,7 +5801,7 @@ def newqad(): prout(_("LEAVE AT ONCE, OR YOU WILL BE DESTROYED!")) # Put in THING if needed if thing == game.quadrant: - Enemy(type='?', loc=dropin(), + Enemy(etype='?', loc=dropin(), power=randreal(6000,6500.0)+250.0*game.skill) if not damaged(DSRSENS): skip(1) @@ -5800,7 +5818,7 @@ def newqad(): w.j = withprob(0.5) * (QUADSIZE-1) if game.quad[w.i][w.j] == '.': break - game.tholian = Enemy(type='T', loc=w, + game.tholian = Enemy(etype='T', loc=w, power=randrange(100, 500) + 25.0*game.skill) # Reserve unoccupied corners if game.quad[0][0]=='.':