# gameshell.py from shell import Shell from gamebase import GameBase import sys as _sys #import re import heapq #import gamemap import gameevents #from os import get_terminal_size #import random class GameShell(Shell): UP = 1 RIGHT = 2 DOWN = 4 LEFT = 8 WALLS = ('++', '++', ' +', '++', '++', '||', '++', '|+', '+ ', '++', '==', '++', '++', '+|', '++', '++') def __init__(self, gameBase): super(GameShell, self).__init__() self.outstream = _sys.stdout self.gameBase = gameBase self.colorMode = 0 # register functions self.registerCommand('map', self.showMap) self.registerCommand('ls', self.showMap) self.registerCommand('go', self.gameBase.go) self.registerCommand('move', self.gameBase.go) self.registerCommand('walk', self.gameBase.go) self.registerCommand('look', self.gameBase.look) self.registerCommand('use', self.gameBase.use) self.registerCommand('loadMap', self.gameBase.loadMap) self.registerCommand('man', self.man) self.registerCommand('help', self.man) self.registerCommand('save', self.gameBase.saveGame) self.registerCommand('load', self.gameBase.loadGame) self.registerCommand('take', self.gameBase.take) self.registerCommand('get', self.gameBase.take) self.registerCommand('drop', self.gameBase.drop) self.registerCommand('inv', self.inv) self.registerCommand('bag', self.inv) self.registerCommand('items', self.inv) self.registerCommand('status', self.status) self.registerCommand('options', self.options) self.registerCommand('colorTest', self.colorTest) self.registerAlias('run', ['go', '-r']) self.gameBase.registerIO('container', self.container) # Helper functions def man(self, args): super(GameShell, self).man(args) #heapq.heappush(self.gameBase.eventQueue, (self.gameBase.gameTime, gameevents.NoOpEvent())) def options(self, args): i = 0 while i < len(args): if args[i] == 'color': i += 1 if args[i] in ('0', '3', '4', '8', '24'): self.colorMode = int(args[i]) i += 1 def __colorTestRoutine(self, lower, upper): colors = [] step = int((upper - lower) / 8) #print(step) for g in range(lower, upper, step): colors.append(self.color(upper-1, g, lower, False)) #print(len(colors)) colors.append(self.color(upper-1, upper-1, lower, False)) for r in range(upper-step, lower-1, -step): colors.append(self.color(r, upper-1, lower, False)) #print(len(colors)) for b in range(lower+step, upper, step): colors.append(self.color(lower, upper-1, b, False)) #print(len(colors)) colors.append(self.color(lower, upper-1, upper-1, False)) for g in range(upper-step, lower-1, -step): colors.append(self.color(lower, g, upper-1, False)) #print(len(colors)) for r in range(lower+step, upper, step): colors.append(self.color(r, lower, upper-1, False)) colors.append(self.color(upper-1, lower, upper-1, False)) #print(len(colors)) for b in range(upper-step, lower, -step): colors.append(self.color(upper-1, lower, b, False)) #print(len(colors)) colors.append('\x1b[0m') print(' '.join(colors)) def colorTest(self, args): for i in (3, 4, 8, 24): print(i) self.colorMode = i self.__colorTestRoutine(0, 128) # dark self.__colorTestRoutine(0, 256) # medium self.__colorTestRoutine(128, 256) # light def showMap(self, args): """map [-l] See a map of the local area. "ls" is an alias of map. "l" and "legend" are aliases of -l. If -l is given, a map legend will be printed under the map.""" xAxis = ' ' + ''.join([self.gameBase.numberToLetter(i).ljust(2) for i in range(self.gameBase.level.dimensions[0])]) + '\n' rows = [] index = 0 exits = {} doors = {} useables = {} items = {} level = self.gameBase.level textColor = level.wallColors[0] floorColor = level.floorColors[0] for y in range(level.dimensions[1]): rows.append(['{0}{1:2} {2}{3}'.format(self.clearColor(), y, self.color(textColor[1:]), self.color(floorColor[1:], fg = False))]) rows[-1].append(self.color(textColor[1:])) for x in range(level.dimensions[0]): pos = level.mapMatrix[y][x] thing = level.getThingAtPos(index) if x == self.gameBase.playerx and y == self.gameBase.playery: if '#0000FF' != textColor: textColor = '#0000FF' rows[-1].append(self.color(textColor[1:])) rows[-1].append('()') elif thing: if thing.graphic[1] != textColor: textColor = thing.graphic[1] rows[-1].append(self.color(textColor[1:])) if thing.thingType == 'x': # exit rows[-1].append('X{0}'.format(thing.exitid)) exits[thing.exitid] = (thing.name, thing.graphic[1]) elif thing.thingType == 'd': # door doors[len(doors)+1] = (thing.name, thing.graphic[1]) rows[-1].append('D{0}'.format(len(doors))) elif thing.thingType == 'u': # useable useables[len(useables)+1] = (thing.name, thing.graphic[1]) rows[-1].append('U{0}'.format(len(useables))) elif thing.thingType == 'i': # item items[len(items)+1] = (thing.name, thing.graphic[1]) rows[-1].append('I{0}'.format(len(items))) elif pos[0] == 'w': if level.wallColors[level.mapMatrix[y][x][1]] != textColor: textColor = level.wallColors[level.mapMatrix[y][x][1]] rows[-1].append(self.color(textColor[1:])) sides = 0 if y > 0 and level.mapMatrix[y-1][x][0] == 'w': sides += GameShell.UP if x < level.dimensions[0]-1 and level.mapMatrix[y][x+1][0] == 'w': sides += GameShell.RIGHT if y < level.dimensions[1]-1 and level.mapMatrix[y+1][x][0] == 'w': sides += GameShell.DOWN if x > 0 and level.mapMatrix[y][x-1][0] == 'w': sides += GameShell.LEFT rows[-1].append(GameShell.WALLS[sides]) else: rows[-1].append(' ') index += 1 rows[-1] = ''.join(rows[-1]) print(xAxis) print('{0}\n'.format(self.clearColor(False)).join(rows) + self.clearColor()) self.setClearColor() if len(args) > 0: if args[0] == '-l' or args[0] == 'l' or args[0] == 'legend': legend = ["\n---Legend---\n", "{0}(){1} - {2}".format(self.color('0000FF'), self.clearColor(), self.gameBase.playerName), "Xn - Exit to another area"] for i in exits: legend.append(' {0}X{1}{2} - {3}'.format(self.color(exits[i][1][1:]), i, self.clearColor(), exits[i][0])) legend.append("Un - Useable object") for i in useables: legend.append(' {0}U{1}{2} - {3}'.format(self.color(useables[i][1][1:]), i, self.clearColor(), useables[i][0])) legend.append("In - Item") for i in items: legend.append(' {0}I{1}{2} - {3}'.format(self.color(items[i][1][1:]), i, self.clearColor(), items[i][0])) legend.append("Dn - Door") for i in doors: legend.append(' {0}D{1}{2} - {3}'.format(self.color(doors[i][1][1:]), i, self.clearColor(), doors[i][0])) print('\n'.join(legend)) #heapq.heappush(self.gameBase.eventQueue, (self.gameBase.gameTime, gameevents.NoOpEvent())) return def status(self, args): ret = [] if self.gameBase.level != None: ret.append("Level:{0:.>74}".format(self.gameBase.level.name)) else: ret.append("Level:{0:.>74}".format("None")) ret.append("Gametime:{0:.>71.3}".format(self.gameBase.gameTime)) ret.append("Event queue:") for i in sorted(self.gameBase.eventQueue): ret.append("{0:.<8.3}:{1:.>72}".format(i[0], str(i[1]))) ret.append("Player name:{0:.>68}".format(self.gameBase.playerName)) ret.append("Player position:{0:.>64}".format("{0}{1}".format(self.gameBase.numberToLetter(self.gameBase.playerx), self.gameBase.playery))) ret.append("Prev. position:{0:.>65}".format("{0}{1}".format(self.gameBase.numberToLetter(self.gameBase.prevx), self.gameBase.prevy))) print('\n'.join(ret)) #heapq.heappush(self.gameBase.eventQueue, (self.gameBase.gameTime, gameevents.NoOpEvent())) return def inv(self, args): print('\n'.join([i for i in self.gameBase.playerInv])) def container(self, inv, cont): """container IO""" # Pretty print: get length of the longest inventory item's name longestLen = 0 longestStr = "" for i in inv: if len(i) > longestLen: longestLen = len(i) longestStr = i if longestLen > 0: print('{{0:<{0}}}{1}'.format(longestLen+2, "Container:").format("Inv:")) i = 0 invKeys = tuple(inv.keys()) while i < len(invKeys) and i < len(cont): print('{{0:<{0}}}{1}'.format(longestLen+2, cont[i].name).format(invKeys[i])) i += 1 while i < len(invKeys): print(invKeys[i]) i += 1 while i < len(cont): print(' '*(longestLen+2) + cont[i].name) i += 1 else: print('Container:') for i in cont: print(i.name) # Now, actually interacting with the container timeSpent = 0.5 # using a container always takes at least 1/2 second, even just opening and closing it again. instr = input("Take, store, or exit: ") while instr != "exit": instr = instr.split() if instr[0] == "take": # take something out of the container if instr[1] == "the": del instr[1] thing = ' '.join(instr[1:]) for i in range(len(cont)): if thing == cont[i].name: inv[cont[i].name] = cont[i] del cont[i] timeSpent += 0.5 print("{0} taken.".format(thing)) break elif instr[0] == "store": # store something in the container if instr[1] == "the": del instr[1] thing = ' '.join(instr[1:]) if thing in inv: cont.append(inv[thing]) del inv[thing] print("{0} stored.".format(thing)) timeSpent += 0.5 instr = input("Take, store, or exit: ") return inv, cont, timeSpent def update(self): self.gameBase.gameEventLoop() if __name__ == '__main__': sh = GameShell(GameBase()) sh.run()