added "info" and "wear" use functions, and fixed many bugs related to storing things by ID.

This commit is contained in:
Patrick Marsee 2019-05-28 14:23:15 -04:00
parent 1b41c46105
commit 8355dccb33
4 changed files with 165 additions and 44 deletions

View file

@ -25,7 +25,7 @@ class GameBase(object):
self.__behaviors = {}
self.__gameEvents = {}
self.__IOCalls = {} # {str : function}
self.customVals = {} # for setting flags and such
self.customValues = {} # for setting flags and such
self.level = None
self.persist = {} # {level : {thingName : thing}}
self.ps2 = '? '
@ -58,6 +58,8 @@ class GameBase(object):
self.registerUseFunc('examine', self.examine)
self.registerUseFunc('key', self.key)
self.registerUseFunc('container', self.container)
self.registerUseFunc('info', self.info)
self.registerUseFunc('wear', self.wear)
self.registerBehavior('wander', self.wander)
# Helper functions
@ -138,16 +140,16 @@ Returns (thing, x, y). "Thing" can be None."""
elif thing != None:
return thing, thing.x, thing.y
elif allowInventory:
if name in self.playerInv:
thing = self.playerInv[name]
if thing != None:
return thing, -1, -1
else:
return None, -1, -1
#raise RuntimeError("'None' item named '{0}' in player inventory.".format(name))
else:
return None, -1, -1
#raise ValueError("{0} cannot be reached.".format(name))
for i in self.playerInv:
thingName = self.playerInv[i].name
if name == thingName:
thing = self.playerInv[i]
if thing != None:
return thing, -1, -1
else:
return None, -1, -1
#raise RuntimeError("'None' item named '{0}' in player inventory.".format(name))
return None, -1, -1
else: # nothing
return None, -1, -1
#raise ValueError("{0} cannot be reached.".format(name))
@ -295,6 +297,7 @@ say "use the lever" rather than just "use lever").
Object can be the name of the object, or its coordinates. It can also be
the name of an item in the player's inventory."""
speed = 0.6666667
useArgs = []
if args[0] == '-r' or args[0] == 'r' or args[0] == 'run':
speed = 0.3333333
args.pop(0)
@ -303,19 +306,21 @@ the name of an item in the player's inventory."""
if 'on' in args:
self.useOn(args, speed)
return
if 'with' in args:
useArgs = args[args.index('with')+1:]
thing, x, y = self.parseCoords(args)
if thing == None:
print("There is nothing to use.", file = self.outstream)
#_hq.heappush(self.eventQueue, (self.gameTime, _ge.NoOpEvent()))
return
if thing.thingType != 'u' and thing.name not in self.playerInv:
if thing.thingType != 'u' and thing.thingID not in self.playerInv:
print("The {0} cannot be used.".format(thing.name), file = self.outstream)
#_hq.heappush(self.eventQueue, (self.gameTime, _ge.NoOpEvent()))
return
# Similar to go, but not quite the same.
if (x, y) == (self.playerx, self.playery) or thing.name in self.playerInv:
self.setEvent(0.125, _ge.UseEvent(thing))
if (x, y) == (self.playerx, self.playery) or thing.thingID in self.playerInv:
self.setEvent(0.125, _ge.UseEvent(thing, useArgs))
return
dist, path = self.level.path(x, y, self.playerx, self.playery)
if dist == -1:
@ -335,7 +340,7 @@ the name of an item in the player's inventory."""
t += 1
#newx, newy = self.level.intToCoords(space)
#_hq.heappush(self.eventQueue, (self.gameTime + t * speed, _ge.GoEvent(self.playerName, newx, newy)))
self.setEvent(t * speed + 0.125, _ge.UseEvent(thing))
self.setEvent(t * speed + 0.125, _ge.UseEvent(thing, useArgs))
return
def useOn(self, args, speed):
@ -345,7 +350,10 @@ the name of an item in the player's inventory."""
if args[onIndex+1] == 'the':
onIndex += 1
thing, x, y = self.parseCoords(args[onIndex+1:])
if item == None or item.name not in self.playerInv:
useArgs = []
if 'with' in args:
useArgs = args[args.index('with')+1:]
if item == None or item.thingID not in self.playerInv:
print("There is no {0} in the inventory.".format(item.name), file = self.outstream)
#_hq.heappush(self.eventQueue, (self.gameTime, _ge.NoOpEvent()))
return
@ -356,7 +364,7 @@ the name of an item in the player's inventory."""
# Similar to go, but not quite the same.
if (x, y) == (self.playerx, self.playery):
self.setEvent(0.125, _ge.UseOnEvent(item, thing))
self.setEvent(0.125, _ge.UseOnEvent(item, thing, useArgs))
return
dist, path = self.level.path(x, y, self.playerx, self.playery)
if dist == -1:
@ -379,7 +387,7 @@ the name of an item in the player's inventory."""
t += 1
#newx, newy = self.level.intToCoords(space)
#_hq.heappush(self.eventQueue, (self.gameTime + t * speed, _ge.GoEvent(self.playerName, newx, newy)))
self.setEvent(t * speed + 0.125, _ge.UseOnEvent(item, thing))
self.setEvent(t * speed + 0.125, _ge.UseOnEvent(item, thing, useArgs))
return
def take(self, args):
@ -434,10 +442,12 @@ Object can be the name of the object, or its coordinates."""
"""drop [the] item"""
if args[0] == 'the':
args.pop(0)
if args[0] in self.playerInv:
self.setEvent(0.0, _ge.DropEvent(self.playerInv[args[0]]))
else:
print('{0} do not have a {1}.'.format(self.playerName, args[0]), file = self.outstream)
for i in self.playerInv:
thingName = self.playerInv[i].name
if ' '.join(args) == thingName:
self.setEvent(0.0, _ge.DropEvent(self.playerInv[args[0]]))
return
print('{0} does not have a {1}.'.format(self.playerName, args[0]), file = self.outstream)
def loadMap(self, args):
# loadMap (fileName)
@ -602,26 +612,26 @@ Object can be the name of the object, or its coordinates."""
if e.thing.useFunc == '':
print('The {0} cannot be used by itself.'.format(e.thing.name), file = self.outstream)
return True
self.setEvent(self.__useFuncs[e.thing.useFunc](e.thing), _ge.NoOpEvent())
self.setEvent(self.__useFuncs[e.thing.useFunc](e.thing, e.args), _ge.NoOpEvent())
return False
def handleUseOn(self, e):
if e.item.useOnFunc == '':
print('The {0} cannot be used on other objects.'.format(e.item.name), file = self.outstream)
return True
self.setEvent(self.__useFuncs[e.item.useOnFunc](e.item, e.thing), _ge.NoOpEvent())
self.setEvent(self.__useFuncs[e.item.useOnFunc](e.item, e.thing, e.args), _ge.NoOpEvent())
return False
def handleTake(self, e):
self.level.removeThingByName(e.item.name)
self.playerInv[e.item.name] = e.item
self.level.removeThingByID(e.item.thingID)
self.playerInv[e.item.thingID] = e.item
return True
def handleDrop(self, e):
e.item.x = self.playerx
e.item.y = self.playery
self.level.addThing(e.item, True)
del self.playerInv[e.item.name]
del self.playerInv[e.item.thingID]
return True
def handleBehave(self, e):
@ -629,7 +639,7 @@ Object can be the name of the object, or its coordinates."""
# default useFuncs: take a list of arguments, return the time the use took
def examine(self, thing):
def examine(self, thing, args):
"""Just prints the given text."""
if 'pattern' not in thing.customValues or 'text' not in thing.customValues:
raise ValueError("Non-examinable thing {0} examined.".format(thing.name))
@ -661,13 +671,50 @@ Object can be the name of the object, or its coordinates."""
self.customVals[thing.customValues['set']] = 0
return 0.0
def container(self, thing):
def container(self, thing, args):
"""Acts as a container. Items can be traded between the container and the player's inventory."""
items = list(thing.customValues['items'])
self.playerInv, thing.customValues['items'], timeOpen = self.getIO('container')(self.playerInv, items)
return timeOpen
def key(self, item, thing):
def info(self, thing, args):
"""Acts as a bookshelf, filing cabinet, bulletin board, or anything that contains raw info."""
items = dict(thing.customValues['items'])
return self.getIO('info')(items)
def wear(self, item, args):
"""Wear clotherg or otherwise equip a passive item."""
# An item must be in the player's inventory in order to wear it.
inInv = False
for i in self.playerInv:
if i == item.thingID:
inInv = True
break
if not inInv:
print("You cannot wear what you are not carrying.", file = self.outstream)
return 0.0
if 'wearing' not in self.customValues:
self.customValues['wearing'] = {}
if item.customValues['slot'] not in self.customValues['wearing']:
self.customValues['wearing'][item.customValues['slot']] = item
# This is so a player can't put on a garment, then drop it while
# still also wearing it.
del self.playerInv[item.thingID]
print("{} put on the {}.".format(self.playerName, item.name), file = self.outstream)
else: # the player must be wearing something that will get in the way
# put the old clothes back in the inventory
oldItem = self.customValues['wearing'][item.customValues['slot']]
self.playerInv[oldItem.thingID] = oldItem
self.customValues['wearing'][item.customValues['slot']] = item
# This is so a player can't put on a garment, then drop it while
# still also wearing it.
del self.playerInv[item.thingID]
print("{} took off the {} and put on the {}.".format(self.playerName, oldItem.name, item.name), file = self.outstream)
return 1.0
# item use-on functions
def key(self, item, thing, args):
"""Item is a key, which unlocks a door. This may be implemented for containers later."""
if isinstance(thing, tuple) or thing.thingType != 'd':
print("That is not a door.", file = self.outstream)