595 lines
26 KiB
Python
595 lines
26 KiB
Python
# gameshell.py
|
|
|
|
from shell import Shell
|
|
from gamebase import GameBase
|
|
import sys as _sys
|
|
import os as _os
|
|
#import re
|
|
import heapq
|
|
#import gamemap
|
|
import gameevents
|
|
import textwrap as _tw
|
|
from shutil import get_terminal_size as _gts
|
|
import gameutil as _gu
|
|
#import random
|
|
|
|
TERM_SIZE = _gts()[0]
|
|
|
|
class GameShell(Shell):
|
|
|
|
UP = 1
|
|
RIGHT = 2
|
|
DOWN = 4
|
|
LEFT = 8
|
|
WALLS = ('++', '++', ' +', '++', '++', '||', '++', '|+', '+ ', '++',
|
|
'==', '++', '++', '+|', '++', '++')
|
|
|
|
def __init__(self, gameBase, gameData = 'testing/testdata.yml'):
|
|
super(GameShell, self).__init__()
|
|
self.outstream = _sys.stdout
|
|
self.gameBase = gameBase
|
|
self.colorMode = 0
|
|
data = self.gameBase.loadGameData(gameData)
|
|
self.gameTitle = 'Game Shell' # should be changed for actual games
|
|
if 'title' in data:
|
|
self.gameTitle = data['title']
|
|
self.startLevel = 'testing/test1.yml' # should be changed for actual games
|
|
if 'startLevel' in data:
|
|
self.startLevel = data['startLevel']
|
|
self.openingText = '{}\nIn Development'
|
|
if 'openingText' in data:
|
|
self.openingText = data['openingText']
|
|
if 'playerName' in data:
|
|
self.gameBase.playerName = data['playerName']
|
|
if 'playerDescription' in data:
|
|
self.gameBase.playerDescription = data['playerDescription']
|
|
self.ps2 = '?> '
|
|
self.__inGame = False
|
|
|
|
# register functions
|
|
|
|
self.registerCommand('load', self.loadGame) # should always be available
|
|
self.registerCommand('flippetywick', self.devMode)
|
|
self.registerCommand('options', self.options)
|
|
self.registerCommand('colorTest', self.colorTest)
|
|
self.registerCommand('man', self.man)
|
|
self.registerCommand('help', self.man)
|
|
self.registerCommand('new', self.newGame)
|
|
self.gameBase.registerIO('container', self.container)
|
|
self.gameBase.registerIO('startDialog', self.startDialog)
|
|
self.gameBase.registerIO('openDialog', self.openDialog)
|
|
self.gameBase.registerIO('respondDialog', self.respondDialog)
|
|
self.gameBase.registerIO('endDialog', self.endDialog)
|
|
self.gameBase.registerIO('info', self.info)
|
|
self.gameBase.registerIO('playercmd', self.playercmd)
|
|
|
|
# Helper functions
|
|
|
|
def man(self, args):
|
|
super(GameShell, self).man(args)
|
|
|
|
def options(self, args):
|
|
i = 0
|
|
while i < len(args):
|
|
if args[i] == 'color':
|
|
i += 1
|
|
if len(args) > i:
|
|
if args[i] in ('0', '3', '4', '8', '24'):
|
|
self.colorMode = int(args[i])
|
|
i += 1
|
|
else:
|
|
print("Valid color depths are 0, 3, 4, 8, and 24.")
|
|
else:
|
|
print("Valid color depths are 0, 3, 4, 8, and 24.")
|
|
elif args[i] == 'automove':
|
|
i += 1
|
|
if len(args) > i:
|
|
if args[i] in ('on', 'off'):
|
|
self.gameBase.autoMove = args[i] == 'on'
|
|
i += 1
|
|
else:
|
|
print("Valid options are 'on' and 'off'.")
|
|
else:
|
|
print("Valid options are 'on' and 'off'.")
|
|
else:
|
|
print("Could not identify option {}".format(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 __getAdjFloors(self, level, x, y):
|
|
"""Get the floor colors of the 8 nearest tiles."""
|
|
adjFloors = []
|
|
for i in range(y-1, y+2):
|
|
if i < 0 or i >= level.dimensions[1]:
|
|
continue
|
|
for j in range(x-1, x+2):
|
|
if j < 0 or j >= level.dimensions[0]:
|
|
continue
|
|
if level.mapMatrix[i][j][0] == 'e':
|
|
adjFloors.append(level.mapMatrix[i][j][1])
|
|
return adjFloors
|
|
|
|
def __getUnderWallColor(self, level, x, y):
|
|
adjFloors = self.__getAdjFloors(level, x, y)
|
|
if len(adjFloors) > 0:
|
|
counts = {}
|
|
highestCount = 0
|
|
ret = -1
|
|
for i in adjFloors:
|
|
if i in counts:
|
|
counts[i] += 1
|
|
else:
|
|
counts[i] = 1
|
|
if counts[i] > highestCount:
|
|
ret = i
|
|
highestCount = counts[i]
|
|
elif counts[i] == highestCount and i < ret:
|
|
ret = i
|
|
return ret
|
|
else:
|
|
return -1
|
|
|
|
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([_gu.numberToLetter(i).ljust(2) for i in range(self.gameBase.level.dimensions[0])]) + '\n'
|
|
rows = []
|
|
index = 0
|
|
exits = {}
|
|
characters = {}
|
|
doors = {}
|
|
useables = {}
|
|
items = {}
|
|
level = self.gameBase.level
|
|
textColor = level.wallColors[0]
|
|
floorColor = level.floorColors[0]
|
|
priorities = {'p': 1, 'n': 2, 'i': 3, 'u': 4, 'd': 5, 'x': 6, 'a': 7}
|
|
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]
|
|
things = level.getThingsAtPos(index)
|
|
if len(things) > 0:
|
|
# Prioritize types: p, n, i, u, d, x, a
|
|
thing = things[0]
|
|
for i in things[1:]:
|
|
if priorities[i.thingType] < priorities[thing.thingType]:
|
|
thing = i
|
|
if thing.graphic.foreground != textColor:
|
|
textColor = thing.graphic.foreground
|
|
#print(textColor)
|
|
rows[-1].append(self.color(textColor[1:]))
|
|
if thing.thingType == 'p': # player
|
|
rows[-1].append('()')
|
|
elif thing.thingType == 'x': # exit
|
|
rows[-1].append('X{0}'.format(thing.exitid))
|
|
exits[thing.exitid] = (thing.name, thing.graphic.foreground)
|
|
elif thing.thingType == 'n': # NPC
|
|
characters[len(characters)+1] = (thing.name, thing.graphic.foreground)
|
|
rows[-1].append('C{0}'.format(len(characters)))
|
|
elif thing.thingType == 'd': # door
|
|
doors[len(doors)+1] = (thing.name, thing.graphic.foreground)
|
|
rows[-1].append('D{0}'.format(len(doors)))
|
|
elif thing.thingType == 'u': # useable
|
|
useables[len(useables)+1] = (thing.name, thing.graphic.foreground)
|
|
rows[-1].append('U{0}'.format(len(useables)))
|
|
elif thing.thingType == 'i': # item
|
|
items[len(items)+1] = (thing.name, thing.graphic.foreground)
|
|
rows[-1].append('I{0}'.format(len(items)))
|
|
else: # entrance
|
|
rows[-1].append(' ')
|
|
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
|
|
underWallColor = self.__getUnderWallColor(level, x, y)
|
|
if level.floorColors[underWallColor] != floorColor and underWallColor != -1:
|
|
floorColor = level.floorColors[underWallColor]
|
|
rows[-1].append(self.color(floorColor[1:], fg = False))
|
|
rows[-1].append(GameShell.WALLS[sides])
|
|
else:
|
|
if level.floorColors[level.mapMatrix[y][x][1]] != floorColor:
|
|
floorColor = level.floorColors[level.mapMatrix[y][x][1]]
|
|
rows[-1].append(self.color(floorColor[1:], fg = False))
|
|
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("Cn - Character")
|
|
for i in characters:
|
|
legend.append(' {0}U{1}{2} - {3}'.format(self.color(characters[i][1][1:]), i, self.clearColor(), characters[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:.>71}".format(i[0], str(i[1])))
|
|
ret.append("custom values:")
|
|
for i in self.gameBase.customValues:
|
|
ret.append("{0:<22}: {1}".format(i, self.gameBase.customValues[i]))
|
|
ret.append("Player name:{0:.>68}".format(self.gameBase.player.name))
|
|
ret.append("Player position:{0:.>64}".format("{0}{1}".format(_gu.numberToLetter(self.gameBase.player.x), self.gameBase.player.y)))
|
|
ret.append("Prev. position:{0:.>65}".format("{0}{1}".format(_gu.numberToLetter(self.gameBase.player.prevx), self.gameBase.player.prevy)))
|
|
ret.append("Inventory:")
|
|
for i in self.gameBase.player.inventory:
|
|
ret.append("{0:<8}: {1}".format(i.thingID, i.name))
|
|
ret.append("Things:\nID Name X Y")
|
|
for i in self.gameBase.level.things:
|
|
j = self.gameBase.level.things[i]
|
|
ret.append("{0:<7} {1:<31} {2:<3} {3:<3}".format(i, j.name, j.x, j.y))
|
|
ret.append("Persistent:")
|
|
for i in self.gameBase.level.persistent:
|
|
ret.append(str(i))
|
|
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.player.thingNames]))
|
|
|
|
def newGame(self, args):
|
|
if self.__inGame:
|
|
response = input("Do you want to save before exiting (Y/n/x)? ")
|
|
if len(response) > 0:
|
|
if response[0] in 'Nn':
|
|
pass
|
|
elif response[0] in 'Xx': # cancel
|
|
return
|
|
else:
|
|
sf = input('Save file: ')
|
|
if len(sf) > 0:
|
|
self.gameBase.saveGame([sf])
|
|
else:
|
|
print('No save file given, cancelling exit.')
|
|
else:
|
|
sf = input('Save file: ')
|
|
if len(sf) > 0:
|
|
self.gameBase.saveGame([sf])
|
|
else:
|
|
print('No save file given, cancelling exit.')
|
|
try:
|
|
self.gameBase.loadMap([self.startLevel])
|
|
except RuntimeError as e:
|
|
print(e)
|
|
return
|
|
self.gameMode()
|
|
|
|
def loadGame(self, args):
|
|
# Check if there's a name in args. If not, just present a list of save files.
|
|
if len(args) == 0:
|
|
import pickle as _pi
|
|
for fileName in _os.listdir('saves'):
|
|
with open(f'saves/{fileName}', 'rb') as f:
|
|
player, levelname, persist, eventQueue, customValues, gameTime, nextThing = _pi.load(f)
|
|
print(f'{fileName[:-4]}\n - {levelname[5:-4]}')
|
|
return
|
|
if self.__inGame:
|
|
response = input("Do you want to save before exiting (Y/n/x)? ")
|
|
if len(response) > 0:
|
|
if response[0] in 'Nn':
|
|
pass
|
|
elif response[0] in 'Xx': # cancel
|
|
return
|
|
else:
|
|
sf = input('Save file: ')
|
|
if len(sf) > 0:
|
|
self.gameBase.saveGame([sf])
|
|
else:
|
|
print('No save file given, cancelling exit.')
|
|
return
|
|
else:
|
|
sf = input('Save file: ')
|
|
if len(sf) > 0:
|
|
self.gameBase.saveGame([sf])
|
|
else:
|
|
print('No save file given, cancelling exit.')
|
|
return
|
|
try:
|
|
self.gameBase.loadGame(args)
|
|
except RuntimeError as e:
|
|
print(e)
|
|
return
|
|
self.gameMode()
|
|
|
|
def gameMode(self):
|
|
"""Mode for in-game."""
|
|
if not self.__inGame:
|
|
self.registerCommand('map', self.showMap)
|
|
self.registerCommand('wait', self.gameBase.wait)
|
|
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('talk', self.gameBase.talk)
|
|
self.registerCommand('use', self.gameBase.use)
|
|
self.registerCommand('save', self.gameBase.saveGame)
|
|
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.registerAlias('run', ['go', '-r'])
|
|
self.__inGame = True
|
|
|
|
def menuMode(self, text = None):
|
|
"""Mode for main menus and the like."""
|
|
if self.__inGame:
|
|
self.registerCommand('map', self.showMap)
|
|
self.unregisterCommand('wait', self.gameBase.wait)
|
|
self.unRegisterCommand('ls', self.showMap)
|
|
self.unRegisterCommand('go', self.gameBase.go)
|
|
self.unRegisterCommand('move', self.gameBase.go)
|
|
self.unRegisterCommand('walk', self.gameBase.go)
|
|
self.unRegisterCommand('look', self.gameBase.look)
|
|
self.unRegisterCommand('talk', self.gameBase.talk)
|
|
self.unRegisterCommand('use', self.gameBase.use)
|
|
self.unRegisterCommand('save', self.gameBase.saveGame)
|
|
self.unRegisterCommand('take', self.gameBase.take)
|
|
self.unRegisterCommand('get', self.gameBase.take)
|
|
self.unRegisterCommand('drop', self.gameBase.drop)
|
|
self.unRegisterCommand('inv', self.inv)
|
|
self.unRegisterCommand('bag', self.inv)
|
|
self.unRegisterCommand('items', self.inv)
|
|
self.unRegisterAlias('run', ['go', '-r'])
|
|
self.__inGame = False
|
|
if text == None:
|
|
print(self.openingText.format(self.gameTitle))
|
|
else:
|
|
print(text.format(self.gameTitle))
|
|
|
|
def devMode(self, args):
|
|
print('Dev mode activated. Please dev responsibly.')
|
|
self.gameMode()
|
|
self.registerCommand('dev', self.runScript)
|
|
self.registerCommand('status', self.status)
|
|
self.registerCommand('loadMap', self.gameBase.loadMap)
|
|
|
|
def runScript(self, args):
|
|
"""simple wrapper for gameBase.runscript."""
|
|
self.gameBase.parseScript(' '.join(args))
|
|
|
|
# IO calls
|
|
|
|
def container(self, player, cont: list):
|
|
"""container IO
|
|
Player is modified through side-effect."""
|
|
# Pretty print: get length of the longest inventory item's name
|
|
longestLen = 0
|
|
for i in player.thingNames:
|
|
if len(i) > longestLen:
|
|
longestLen = len(i)
|
|
if longestLen > 0:
|
|
inv = player.inventory # do this assignment because player.inventory is O(n)
|
|
print('{{0:<{0}}}{1}'.format(max(6, longestLen+2), "Container:").format("Inv:"))
|
|
i = 0
|
|
while i < len(inv) and i < len(cont):
|
|
print('{{0:<{0}}}{1}'.format(longestLen+2, cont[i].name).format(inv[i].name))
|
|
i += 1
|
|
while i < len(inv):
|
|
print(inv[i].name)
|
|
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("Look, take, store, or exit: ")
|
|
while instr != "exit":
|
|
instr = instr.split()
|
|
if len(instr) != 0:
|
|
if instr[0] == "take":
|
|
# take something out of the container
|
|
if len(instr) > 1 and instr[1] == "the":
|
|
del instr[1]
|
|
thingName = ' '.join(instr[1:])
|
|
if len(thingName) == 0:
|
|
print(f"{self.gameBase.player.name} takes nothing.")
|
|
else:
|
|
for i in range(len(cont)):
|
|
if thingName == cont[i].name:
|
|
player.addThing(cont[i])
|
|
del cont[i]
|
|
timeSpent += 0.5
|
|
print(f"{thingName} taken.")
|
|
break
|
|
else:
|
|
# If it got here, it didn't find it.
|
|
print(f"No {thingName} in container.")
|
|
elif instr[0] == "store":
|
|
# store something in the container
|
|
if len(instr) > 1 and instr[1] == "the":
|
|
del instr[1]
|
|
thingName = ' '.join(instr[1:])
|
|
if len(thingName) == 0:
|
|
print(f"{self.gameBase.player.name} stores nothing.")
|
|
elif thingName in player.thingNames:
|
|
cont.append(player.removeThingByName(thingName))
|
|
print(f"{thingName} stored.")
|
|
timeSpent += 0.5
|
|
else:
|
|
print(f"No {thingName} in inventory.")
|
|
elif instr[0] == "look":
|
|
# look at something in the container
|
|
if len(instr) > 1 and instr[1] == "at":
|
|
del instr[1]
|
|
if len(instr) > 1 and instr[1] == "the":
|
|
del instr[1]
|
|
thingName = ' '.join(instr[1:])
|
|
if len(thingName) == 0:
|
|
print(f"{self.gameBase.player.name} looks at nothing.")
|
|
else:
|
|
# Check the container first.
|
|
for i in range(len(cont)):
|
|
if thingName == cont[i].name:
|
|
print(self.gameBase.justifyText(str(cont[i])))
|
|
break
|
|
else:
|
|
# If it wasn't there, try the player's inventory.
|
|
if thingName in player.thingNames:
|
|
print(self.gameBase.justifyText(str(player.getThingByName(thingName))))
|
|
else:
|
|
# If we get here, it just isn't there.
|
|
print(f"There is no {thingName} to look at.")
|
|
instr = input("Look, take, store, or exit: ")
|
|
return cont, timeSpent
|
|
|
|
def info(self, items):
|
|
"""IO for collections of information"""
|
|
charsRead = 0
|
|
for i in items:
|
|
print(' ', i)
|
|
instr = input("Choose an item to view, or exit: ")
|
|
while instr != 'exit':
|
|
if instr in items:
|
|
print(_tw.fill(items[instr], width = TERM_SIZE))
|
|
charsRead += len(items[instr])
|
|
else:
|
|
print('{} not here.'.format(instr))
|
|
input('<ENTER>')
|
|
for i in items:
|
|
print(' ', i)
|
|
instr = input("Choose an item to view, or exit: ")
|
|
return charsRead / 27 # based on average 250 words per minute, and word length of 5.5 + 1 for space.
|
|
|
|
def startDialog(self):
|
|
pass
|
|
|
|
def openDialog(self, opener):
|
|
for line in opener:
|
|
print(_tw.fill(line, width = TERM_SIZE))
|
|
input("...")
|
|
|
|
def respondDialog(self, options):
|
|
for lineNo in range(len(options)):
|
|
print(_tw.fill('{}: {}'.format(lineNo+1, options[lineNo]), width = TERM_SIZE))
|
|
answer = -1
|
|
while answer < 0 or answer >= len(options):
|
|
answerString = input(self.ps2)
|
|
if not answerString.isdigit():
|
|
# If the player inputs a non-integer, just prompt again.
|
|
continue
|
|
answer = int(answerString) - 1
|
|
return answer
|
|
|
|
def endDialog(self):
|
|
pass
|
|
|
|
def playercmd(self, args):
|
|
self.handleCommand(args)
|
|
|
|
def update(self):
|
|
self.gameBase.gameEventLoop()
|
|
|
|
def exitShell(self, args):
|
|
if self.__inGame:
|
|
response = input("Do you want to save before exiting (Y/n/x)? ")
|
|
if len(response) > 0:
|
|
if response[0] in 'Nn':
|
|
super(GameShell, self).exitShell(args)
|
|
elif response[0] in 'Xx': # cancel
|
|
return
|
|
else:
|
|
sf = input('Save file: ')
|
|
if len(sf) > 0:
|
|
self.gameBase.saveGame([sf])
|
|
super(GameShell, self).exitShell(args)
|
|
else:
|
|
print('No save file given, cancelling exit.')
|
|
else:
|
|
sf = input('Save file: ')
|
|
if len(sf) > 0:
|
|
self.gameBase.saveGame([sf])
|
|
super(GameShell, self).exitShell(args)
|
|
else:
|
|
print('No save file given, cancelling exit.')
|
|
else:
|
|
super(GameShell, self).exitShell(args)
|
|
|
|
if __name__ == '__main__':
|
|
sh = GameShell(GameBase())
|
|
sh.menuMode()
|
|
sh.run()
|
|
|
|
# |\_/|
|
|
# /0 0\
|
|
# \o/
|