Containers now work. Discovered issue with loading saved games.

This commit is contained in:
Patrick Marsee 2019-03-14 19:52:58 -04:00
parent eeab517213
commit 2719075a33
3 changed files with 94 additions and 11 deletions

View file

@ -19,6 +19,7 @@ class GameBase(object):
self.outstream = _sys.stdout self.outstream = _sys.stdout
self.__useFuncs = {} self.__useFuncs = {}
self.__gameEvents = {} self.__gameEvents = {}
self.__IOCalls = {} # {str : function}
self.customVals = {} # for setting flags and such self.customVals = {} # for setting flags and such
self.level = None self.level = None
self.persist = {} # {level : {thingName : thing}} self.persist = {} # {level : {thingName : thing}}
@ -37,7 +38,7 @@ class GameBase(object):
# function deligates # function deligates
self.onLevelLoad = None # str : level name? -> None self.onLevelLoad = None # str : level name? -> None
self.onContainer = None # list : contents -> list : newContents, float : timeOpen #self.onContainer = None # list : contents -> list : newContents, float : timeOpen
# default events and useFuncs # default events and useFuncs
self.registerEvent('noop', self.handleNoOp) self.registerEvent('noop', self.handleNoOp)
@ -49,6 +50,7 @@ class GameBase(object):
self.registerEvent('drop', self.handleDrop) self.registerEvent('drop', self.handleDrop)
self.registerUseFunc('examine', self.examine) self.registerUseFunc('examine', self.examine)
self.registerUseFunc('key', self.key) self.registerUseFunc('key', self.key)
self.registerUseFunc('container', self.container)
# Helper functions # Helper functions
@ -608,8 +610,8 @@ Object can be the name of the object, or its coordinates."""
def container(self, thing): def container(self, thing):
"""Acts as a container. Items can be traded between the container and the player's inventory.""" """Acts as a container. Items can be traded between the container and the player's inventory."""
items = thing.customValues['items'] items = list(thing.customValues['items'])
thing.customValues['items'], timeOpen = self.onContainer(items) self.playerInv, thing.customValues['items'], timeOpen = self.getIO('container')(self.playerInv, items)
return timeOpen return timeOpen
def key(self, item, thing): def key(self, item, thing):
@ -636,3 +638,11 @@ callable by the player."""
They should take the event as an argument, and return True if it should They should take the event as an argument, and return True if it should
always give the player a turn, False otherwise.""" always give the player a turn, False otherwise."""
self.__gameEvents[name] = func self.__gameEvents[name] = func
def registerIO(self, name, func):
"""Registers a function for useFuncs and such to use."""
self.__IOCalls[name] = func
def getIO(self, name):
"""This is so derived classes can access their IOCalls."""
return self.__IOCalls[name]

View file

@ -25,10 +25,11 @@ class App(ttk.Frame):
self.invTuple = tuple(self.gameBase.playerInv.keys()) self.invTuple = tuple(self.gameBase.playerInv.keys())
self.invNames = StringVar(value=self.invTuple) self.invNames = StringVar(value=self.invTuple)
#self.project = Project() #self.project = Project()
self.tool = StringVar() #self.tool = StringVar()
self.brush = StringVar() #self.brush = StringVar()
self.history = [] #self.history = []
self.redos = [] #self.redos = []
self.useOnCont = None # useOn continued
#self.selectedArea = (0, 0, self.project.x-1, self.project.y-1) #self.selectedArea = (0, 0, self.project.x-1, self.project.y-1)
self.parent.clipboard_clear() self.parent.clipboard_clear()
self.parent.clipboard_append('') self.parent.clipboard_append('')
@ -144,7 +145,7 @@ class App(ttk.Frame):
#print('Making the display work...') #print('Making the display work...')
# level display # level display
self.context = Menu(self.levelDisplay) self.context = Menu(self.levelDisplay)
self.context.add_command(label = 'Load Map', command = lambda: self.loadLevel('maps/apartment.xml')) self.context.add_command(label = 'Load Map', command = lambda: self.loadLevel('maps/apartment.yml'))
self.context.add_command(label = 'Go', command = lambda: self.go(self.selected[0], self.selected[1])) self.context.add_command(label = 'Go', command = lambda: self.go(self.selected[0], self.selected[1]))
self.context.add_command(label = 'Run', command = lambda: self.go(self.selected[0], self.selected[1], True)) self.context.add_command(label = 'Run', command = lambda: self.go(self.selected[0], self.selected[1], True))
self.context.add_command(label = 'Look', command = lambda: self.look(self.selected[0], self.selected[1])) self.context.add_command(label = 'Look', command = lambda: self.look(self.selected[0], self.selected[1]))
@ -164,6 +165,7 @@ class App(ttk.Frame):
self.invContext = Menu(self.invDisplay) self.invContext = Menu(self.invDisplay)
self.invContext.add_command(label = 'Look', command = lambda: self.look(self.invTuple[self.invDisplay.curselection()[0]])) self.invContext.add_command(label = 'Look', command = lambda: self.look(self.invTuple[self.invDisplay.curselection()[0]]))
self.invContext.add_command(label = 'Use', command = lambda: self.use(self.invTuple[self.invDisplay.curselection()[0]])) self.invContext.add_command(label = 'Use', command = lambda: self.use(self.invTuple[self.invDisplay.curselection()[0]]))
self.invContext.add_command(label = 'Use on...', command = lambda: self.useOn(self.invTuple[self.invDisplay.curselection()[0]]))
self.invContext.add_command(label = 'Drop', command = lambda: self.drop(self.invTuple[self.invDisplay.curselection()[0]])) self.invContext.add_command(label = 'Drop', command = lambda: self.drop(self.invTuple[self.invDisplay.curselection()[0]]))
self.invDisplay.bind('<<ListboxSelect>>', lambda e: self.look(self.invTuple[self.invDisplay.curselection()[0]])) self.invDisplay.bind('<<ListboxSelect>>', lambda e: self.look(self.invTuple[self.invDisplay.curselection()[0]]))
self.invDisplay.bind('<3>', lambda e: self.invContext.post(e.x_root, e.y_root)) self.invDisplay.bind('<3>', lambda e: self.invContext.post(e.x_root, e.y_root))
@ -211,9 +213,12 @@ class App(ttk.Frame):
def handleClick(self, event): def handleClick(self, event):
x = int(self.levelDisplay.canvasx(event.x) / 32) x = int(self.levelDisplay.canvasx(event.x) / 32)
y = int(self.levelDisplay.canvasy(event.y) / 32) y = int(self.levelDisplay.canvasy(event.y) / 32)
if (x, y) != self.selected: if self.useOnCont == None:
self.selected = (x, y) if (x, y) != self.selected:
self.look(x, y) self.selected = (x, y)
self.look(x, y)
else:
self.useOn(x, y)
def handleDoubleClick(self, event): def handleDoubleClick(self, event):
x = int(self.levelDisplay.canvasx(event.x) / 32) x = int(self.levelDisplay.canvasx(event.x) / 32)
@ -303,6 +308,17 @@ class App(ttk.Frame):
self.gameBase.gameEventLoop() self.gameBase.gameEventLoop()
self.refreshDisplay() #inefficient, but will work for now. self.refreshDisplay() #inefficient, but will work for now.
def useOn(self, x, y = 1):
if isinstance(x, int):
self.gameBase.use([self.useOnCont, 'on', str(x), str(y)])
self.useOnCont = None
self.gameBase.gameEventLoop()
self.refreshDisplay()
else: # x is a string
self.useOnCont = x
print("Click on something to use {0} on.".format(x), file = self.gameBase.outstream)
self.refreshDisplay()
def take(self, x, y): def take(self, x, y):
self.gameBase.take([str(x), str(y)]) self.gameBase.take([str(x), str(y)])
self.gameBase.gameEventLoop() self.gameBase.gameEventLoop()

View file

@ -49,6 +49,7 @@ class GameShell(Shell):
self.registerCommand('options', self.options) self.registerCommand('options', self.options)
self.registerCommand('colorTest', self.colorTest) self.registerCommand('colorTest', self.colorTest)
self.registerAlias('run', ['go', '-r']) self.registerAlias('run', ['go', '-r'])
self.gameBase.registerIO('container', self.container)
# Helper functions # Helper functions
@ -205,6 +206,62 @@ If -l is given, a map legend will be printed under the map."""
def inv(self, args): def inv(self, args):
print('\n'.join([i for i in self.gameBase.playerInv])) 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): def update(self):
self.gameBase.gameEventLoop() self.gameBase.gameEventLoop()