Rejiggered players to have a thing in the map, and made the inventory system better.
This commit is contained in:
parent
ed7d265b48
commit
5010042430
4 changed files with 347 additions and 287 deletions
327
gamebase.py
327
gamebase.py
|
@ -42,12 +42,9 @@ class GameBase(object):
|
||||||
self.nextThing = 0
|
self.nextThing = 0
|
||||||
|
|
||||||
# player info
|
# player info
|
||||||
self.playerx = -1
|
|
||||||
self.playery = -1
|
|
||||||
self.prevx = -1 # prevx and prevy are for moving the player out of the way
|
|
||||||
self.prevy = -1 # when the tile they're standing on becomes blocked.
|
|
||||||
self.playerName = 'You'
|
self.playerName = 'You'
|
||||||
self.playerInv = {}
|
self.playerDescription = 'The main character.'
|
||||||
|
self.player = None # reference to the player's 'thing'
|
||||||
|
|
||||||
# function deligates
|
# function deligates
|
||||||
self.onLevelLoad = None # str : level name? -> None
|
self.onLevelLoad = None # str : level name? -> None
|
||||||
|
@ -125,6 +122,8 @@ to get input from stdin."""
|
||||||
def parseCoords(self, args, usePlayerCoords = True, allowInventory = True):
|
def parseCoords(self, args, usePlayerCoords = True, allowInventory = True):
|
||||||
"""Takes an argument list, and figures out what it's talking about.
|
"""Takes an argument list, and figures out what it's talking about.
|
||||||
Returns (thing, x, y). "Thing" can be None."""
|
Returns (thing, x, y). "Thing" can be None."""
|
||||||
|
if self.level == None:
|
||||||
|
raise GameError('Coordinates cannot be parsed because there is no map.')
|
||||||
#print(coordStr)
|
#print(coordStr)
|
||||||
x = -1
|
x = -1
|
||||||
y = -1
|
y = -1
|
||||||
|
@ -140,10 +139,8 @@ Returns (thing, x, y). "Thing" can be None."""
|
||||||
|
|
||||||
# Second, try by name for objects in the inventory
|
# Second, try by name for objects in the inventory
|
||||||
if allowInventory:
|
if allowInventory:
|
||||||
for i in self.playerInv:
|
if name in self.player.thingNames:
|
||||||
thingName = self.playerInv[i].name
|
return self.player.getThingByName(name), -1, -1
|
||||||
if name == thingName:
|
|
||||||
return self.playerInv[i], -1, -1
|
|
||||||
|
|
||||||
# Third, try by location
|
# Third, try by location
|
||||||
coordStr = args[0]
|
coordStr = args[0]
|
||||||
|
@ -208,14 +205,16 @@ Returns (thing, x, y). "Thing" can be None."""
|
||||||
val = True
|
val = True
|
||||||
elif arg.casefold() == 'false':
|
elif arg.casefold() == 'false':
|
||||||
val = False
|
val = False
|
||||||
elif arg.casefold() == 'playerx':
|
elif arg.casefold() == 'playerx' and self.player != None:
|
||||||
val = self.playerx
|
val = self.player.x
|
||||||
elif arg.casefold() == 'playery':
|
elif arg.casefold() == 'playery' and self.player != None:
|
||||||
val = self.playery
|
val = self.player.y
|
||||||
elif arg.casefold() == 'playername':
|
elif arg.casefold() == 'playername' and self.player != None:
|
||||||
val = self.playerName
|
val = self.player.name
|
||||||
elif arg.casefold() == 'playerinv':
|
elif arg.casefold() == 'playerinv' and self.player != None:
|
||||||
val = self.playerInv
|
val = self.player.inventory
|
||||||
|
elif arg.casefold() == 'playerdesc' and self.player != None:
|
||||||
|
val = self.player.description
|
||||||
elif validIdent != None:
|
elif validIdent != None:
|
||||||
group = validIdent.group()
|
group = validIdent.group()
|
||||||
if 'scriptLocal' in self.customValues and group in self.customValues['scriptLocal']:
|
if 'scriptLocal' in self.customValues and group in self.customValues['scriptLocal']:
|
||||||
|
@ -274,10 +273,7 @@ Returns (thing, x, y). "Thing" can be None."""
|
||||||
return lval > rval
|
return lval > rval
|
||||||
elif operator == 'in':
|
elif operator == 'in':
|
||||||
if args[2].casefold() == 'playerinv':
|
if args[2].casefold() == 'playerinv':
|
||||||
for i in rval:
|
return lval in self.player.thingNames
|
||||||
if rval[i].name == lval:
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
else:
|
else:
|
||||||
return lval in rval
|
return lval in rval
|
||||||
else:
|
else:
|
||||||
|
@ -298,6 +294,8 @@ wanted to go to D6, one could say "go to D6", "go to d 6", or "go to 3 6".
|
||||||
The letter is not case-sensitive."""
|
The letter is not case-sensitive."""
|
||||||
if self.level == None:
|
if self.level == None:
|
||||||
raise GameError("Cannot move: No level has been loaded.")
|
raise GameError("Cannot move: No level has been loaded.")
|
||||||
|
if self.player == None:
|
||||||
|
raise GameError("Cannot move: Player character doesn't exist.")
|
||||||
speed = 0.6666667
|
speed = 0.6666667
|
||||||
if args[0] == '-r' or args[0] == 'r' or args[0] == 'run':
|
if args[0] == '-r' or args[0] == 'r' or args[0] == 'run':
|
||||||
speed = 0.3333333
|
speed = 0.3333333
|
||||||
|
@ -309,20 +307,20 @@ The letter is not case-sensitive."""
|
||||||
thing, x, y = self.parseCoords(args, allowInventory = False)
|
thing, x, y = self.parseCoords(args, allowInventory = False)
|
||||||
|
|
||||||
# Now we have a heading! Let's see if we can get there...
|
# Now we have a heading! Let's see if we can get there...
|
||||||
if (x, y) == (self.playerx, self.playery):
|
if (x, y) == (self.player.x, self.player.y):
|
||||||
#_hq.heappush(self.eventQueue, (self.gameTime, _ge.ArriveEvent(self.playerName, x, y, 0.0)))
|
#_hq.heappush(self.eventQueue, (self.gameTime, _ge.ArriveEvent(self.playerName, x, y, 0.0)))
|
||||||
self.setEvent(0.0, _ge.ArriveEvent(self.playerName, self.playerx, self.playery, 0.0))
|
self.setEvent(0.0, _ge.ArriveEvent(self.player, self.player.x, self.player.y, 0.0))
|
||||||
return
|
return
|
||||||
dist, path = self.level.path(x, y, self.playerx, self.playery)
|
dist, path = self.level.path(x, y, self.player.x, self.player.y)
|
||||||
if dist == -1:
|
if dist == -1:
|
||||||
print('{0} cannot reach {1}{2}.'.format(self.playerName, self.numberToLetter(x), y), file = self.outstream)
|
print('{0} cannot reach {1}{2}.'.format(self.player.name, self.numberToLetter(x), y), file = self.outstream)
|
||||||
#_hq.heappush(self.eventQueue, (self.gameTime, _ge.NoOpEvent()))
|
#_hq.heappush(self.eventQueue, (self.gameTime, _ge.NoOpEvent()))
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
pos = self.level.coordsToInt(self.playerx, self.playery)
|
pos = self.level.coordsToInt(self.player.x, self.player.y)
|
||||||
space = path[pos]
|
space = path[pos]
|
||||||
if space == -1:
|
if space == -1:
|
||||||
self.setEvent(0.0, _ge.ArriveEvent(self.playerName, self.playerx, self.playery, 0.0))
|
self.setEvent(0.0, _ge.ArriveEvent(self.player, self.player.x, self.player.y, 0.0))
|
||||||
return
|
return
|
||||||
#target = self.level.coordsToInt(x, y)
|
#target = self.level.coordsToInt(x, y)
|
||||||
t = 1
|
t = 1
|
||||||
|
@ -331,13 +329,13 @@ The letter is not case-sensitive."""
|
||||||
newx, newy = self.level.intToCoords(space)
|
newx, newy = self.level.intToCoords(space)
|
||||||
space = path[space]
|
space = path[space]
|
||||||
if space != -1:
|
if space != -1:
|
||||||
self.setEvent(t * speed, _ge.GoEvent(self.playerName, newx, newy))
|
self.setEvent(t * speed, _ge.GoEvent(self.player, newx, newy))
|
||||||
else:
|
else:
|
||||||
self.setEvent(t * speed, _ge.ArriveEvent(self.playerName, newx, newy, t * speed))
|
self.setEvent(t * speed, _ge.ArriveEvent(self.player, newx, newy, t * speed))
|
||||||
break
|
break
|
||||||
t += 1
|
t += 1
|
||||||
#newx, newy = self.level.intToCoords(space)
|
#newx, newy = self.level.intToCoords(space)
|
||||||
#_hq.heappush(self.eventQueue, (self.gameTime + t * speed, _ge.ArriveEvent(self.playerName, newx, newy, t * speed)))
|
#_hq.heappush(self.eventQueue, (self.gameTime + t * speed, _ge.ArriveEvent(self.player, newx, newy, t * speed)))
|
||||||
return
|
return
|
||||||
|
|
||||||
def look(self, args):
|
def look(self, args):
|
||||||
|
@ -347,6 +345,10 @@ Describe an object.
|
||||||
make more sense from a linguistic perspective (for instance, one could
|
make more sense from a linguistic perspective (for instance, one could
|
||||||
say "look at the balcony" rather than just "look balcony").
|
say "look at the balcony" rather than just "look balcony").
|
||||||
Object can be the name of the object, or its coordinates."""
|
Object can be the name of the object, or its coordinates."""
|
||||||
|
if self.level == None:
|
||||||
|
raise GameError("Cannot look: No level has been loaded.")
|
||||||
|
if self.player == None:
|
||||||
|
raise GameError("Cannot look: Player character doesn't exist.")
|
||||||
if len(args) == 0:
|
if len(args) == 0:
|
||||||
print(self.justifyText(self.level.description), file = self.outstream)
|
print(self.justifyText(self.level.description), file = self.outstream)
|
||||||
else:
|
else:
|
||||||
|
@ -355,8 +357,8 @@ Object can be the name of the object, or its coordinates."""
|
||||||
if args[0] == 'the':
|
if args[0] == 'the':
|
||||||
args.pop(0)
|
args.pop(0)
|
||||||
thing, x, y = self.parseCoords(args, usePlayerCoords = False)
|
thing, x, y = self.parseCoords(args, usePlayerCoords = False)
|
||||||
if not self.level.lineOfSight(self.playerx, self.playery, x, y):
|
if not self.level.lineOfSight(self.player.x, self.player.y, x, y):
|
||||||
print("{} cannot see that.".format(self.playerName), file = self.outstream)
|
print("{} cannot see that.".format(self.player.name), file = self.outstream)
|
||||||
elif thing == None:
|
elif thing == None:
|
||||||
print("There is nothing to see here.\n", file = self.outstream)
|
print("There is nothing to see here.\n", file = self.outstream)
|
||||||
else:
|
else:
|
||||||
|
@ -370,6 +372,10 @@ Talk to a character.
|
||||||
make more sense from a linguistic perspective (for instance, one could
|
make more sense from a linguistic perspective (for instance, one could
|
||||||
say "talk to the guard" rather than just "talk guard").
|
say "talk to the guard" rather than just "talk guard").
|
||||||
Character can be the name of the character, or their coordinates."""
|
Character can be the name of the character, or their coordinates."""
|
||||||
|
if self.level == None:
|
||||||
|
raise GameError("Cannot talk: No level has been loaded.")
|
||||||
|
if self.player == None:
|
||||||
|
raise GameError("Cannot talk: Player character doesn't exist.")
|
||||||
if len(args) == 0:
|
if len(args) == 0:
|
||||||
print(self.justifyText(self.level.description), file = self.outstream)
|
print(self.justifyText(self.level.description), file = self.outstream)
|
||||||
else:
|
else:
|
||||||
|
@ -378,8 +384,8 @@ Character can be the name of the character, or their coordinates."""
|
||||||
if args[0] == 'the':
|
if args[0] == 'the':
|
||||||
args.pop(0)
|
args.pop(0)
|
||||||
thing, x, y = self.parseCoords(args, usePlayerCoords = False, allowInventory = False)
|
thing, x, y = self.parseCoords(args, usePlayerCoords = False, allowInventory = False)
|
||||||
if not self.level.lineOfSight(self.playerx, self.playery, x, y):
|
if not self.level.lineOfSight(self.player.x, self.player.y, x, y):
|
||||||
print("{} cannot talk to {}.".format(self.playerName, thing.name), file = self.outstream)
|
print("{} cannot talk to {}.".format(self.player.name, thing.name), file = self.outstream)
|
||||||
elif thing == None:
|
elif thing == None:
|
||||||
print("There is nobody here.\n", file = self.outstream)
|
print("There is nobody here.\n", file = self.outstream)
|
||||||
else:
|
else:
|
||||||
|
@ -407,6 +413,10 @@ make more sense from a linguistic perspective (for instance, one could
|
||||||
say "use the lever" rather than just "use lever").
|
say "use the lever" rather than just "use lever").
|
||||||
Object can be the name of the object, or its coordinates. It can also be
|
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."""
|
the name of an item in the player's inventory."""
|
||||||
|
if self.level == None:
|
||||||
|
raise GameError("Cannot use: No level has been loaded.")
|
||||||
|
if self.player == None:
|
||||||
|
raise GameError("Cannot use: Player character doesn't exist.")
|
||||||
speed = 0.6666667
|
speed = 0.6666667
|
||||||
useArgs = []
|
useArgs = []
|
||||||
if args[0] == '-r' or args[0] == 'r' or args[0] == 'run':
|
if args[0] == '-r' or args[0] == 'r' or args[0] == 'run':
|
||||||
|
@ -424,22 +434,22 @@ the name of an item in the player's inventory."""
|
||||||
print("There is nothing to use.", file = self.outstream)
|
print("There is nothing to use.", file = self.outstream)
|
||||||
#_hq.heappush(self.eventQueue, (self.gameTime, _ge.NoOpEvent()))
|
#_hq.heappush(self.eventQueue, (self.gameTime, _ge.NoOpEvent()))
|
||||||
return
|
return
|
||||||
if thing.thingType != 'u' and thing.thingID not in self.playerInv:
|
if thing.thingType != 'u' and thing not in self.player.inventory:
|
||||||
print("The {0} cannot be used.".format(thing.name), file = self.outstream)
|
print("The {0} cannot be used.".format(thing.name), file = self.outstream)
|
||||||
#_hq.heappush(self.eventQueue, (self.gameTime, _ge.NoOpEvent()))
|
#_hq.heappush(self.eventQueue, (self.gameTime, _ge.NoOpEvent()))
|
||||||
return
|
return
|
||||||
|
|
||||||
# Similar to go, but not quite the same.
|
# Similar to go, but not quite the same.
|
||||||
if (x, y) == (self.playerx, self.playery) or thing.thingID in self.playerInv:
|
if (x, y) == (self.player.x, self.player.y) or thing in self.player.inventory:
|
||||||
self.setEvent(0.125, _ge.UseEvent(thing, useArgs))
|
self.setEvent(0.125, _ge.UseEvent(thing, useArgs))
|
||||||
return
|
return
|
||||||
dist, path = self.level.path(x, y, self.playerx, self.playery)
|
dist, path = self.level.path(x, y, self.player.x, self.player.y)
|
||||||
if dist == -1:
|
if dist == -1:
|
||||||
print('{0} cannot reach the {1}.'.format(self.playerName, thing.name), file = self.outstream)
|
print('{0} cannot reach the {1}.'.format(self.player.name, thing.name), file = self.outstream)
|
||||||
#_hq.heappush(self.eventQueue, (self.gameTime, _ge.NoOpEvent()))
|
#_hq.heappush(self.eventQueue, (self.gameTime, _ge.NoOpEvent()))
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
pos = self.level.coordsToInt(self.playerx, self.playery)
|
pos = self.level.coordsToInt(self.player.x, self.player.y)
|
||||||
space = path[pos]
|
space = path[pos]
|
||||||
#target = self.level.coordsToInt(x, y)
|
#target = self.level.coordsToInt(x, y)
|
||||||
t = 1
|
t = 1
|
||||||
|
@ -447,7 +457,7 @@ the name of an item in the player's inventory."""
|
||||||
while space != -1:
|
while space != -1:
|
||||||
newx, newy = self.level.intToCoords(space)
|
newx, newy = self.level.intToCoords(space)
|
||||||
space = path[space]
|
space = path[space]
|
||||||
self.setEvent(t * speed, _ge.GoEvent(self.playerName, newx, newy))
|
self.setEvent(t * speed, _ge.GoEvent(self.player, newx, newy))
|
||||||
t += 1
|
t += 1
|
||||||
#newx, newy = self.level.intToCoords(space)
|
#newx, newy = self.level.intToCoords(space)
|
||||||
#_hq.heappush(self.eventQueue, (self.gameTime + t * speed, _ge.GoEvent(self.playerName, newx, newy)))
|
#_hq.heappush(self.eventQueue, (self.gameTime + t * speed, _ge.GoEvent(self.playerName, newx, newy)))
|
||||||
|
@ -464,7 +474,7 @@ the name of an item in the player's inventory."""
|
||||||
useArgs = []
|
useArgs = []
|
||||||
if 'with' in args:
|
if 'with' in args:
|
||||||
useArgs = args[args.index('with')+1:]
|
useArgs = args[args.index('with')+1:]
|
||||||
if item == None or item.thingID not in self.playerInv:
|
if item == None or item not in self.player.inventory:
|
||||||
print("There is no such item in the inventory.", file = self.outstream)
|
print("There is no such item in the inventory.", file = self.outstream)
|
||||||
#_hq.heappush(self.eventQueue, (self.gameTime, _ge.NoOpEvent()))
|
#_hq.heappush(self.eventQueue, (self.gameTime, _ge.NoOpEvent()))
|
||||||
return
|
return
|
||||||
|
@ -473,32 +483,40 @@ the name of an item in the player's inventory."""
|
||||||
#_hq.heappush(self.eventQueue, (self.gameTime, _ge.NoOpEvent()))
|
#_hq.heappush(self.eventQueue, (self.gameTime, _ge.NoOpEvent()))
|
||||||
return
|
return
|
||||||
|
|
||||||
# Similar to go, but not quite the same.
|
if not item.ranged:
|
||||||
if (x, y) == (self.playerx, self.playery):
|
# Similar to go, but not quite the same.
|
||||||
self.setEvent(0.125, _ge.UseOnEvent(item, thing, useArgs))
|
if (x, y) == (self.player.x, self.player.y):
|
||||||
return
|
self.setEvent(0.125, _ge.UseOnEvent(item, thing, useArgs))
|
||||||
dist, path = self.level.path(x, y, self.playerx, self.playery)
|
return
|
||||||
if dist == -1:
|
dist, path = self.level.path(x, y, self.player.x, self.player.y)
|
||||||
if thing != None:
|
if dist == -1:
|
||||||
print('{0} cannot reach the {1}.'.format(self.playerName, thing.name), file = self.outstream)
|
if thing != None:
|
||||||
|
print('{0} cannot reach the {1}.'.format(self.player.name, thing.name), file = self.outstream)
|
||||||
|
else:
|
||||||
|
print('{0} cannot reach {1}{2}.'.format(self.player.name, self.numberToLetter(x), y), file = self.outstream)
|
||||||
|
#_hq.heappush(self.eventQueue, (self.gameTime, _ge.NoOpEvent()))
|
||||||
|
return
|
||||||
else:
|
else:
|
||||||
print('{0} cannot reach {1}{2}.'.format(self.playerName, self.numberToLetter(x), y), file = self.outstream)
|
pos = self.level.coordsToInt(self.player.x, self.player.y)
|
||||||
#_hq.heappush(self.eventQueue, (self.gameTime, _ge.NoOpEvent()))
|
space = path[pos]
|
||||||
return
|
#target = self.level.coordsToInt(x, y)
|
||||||
|
t = 1
|
||||||
|
#while space != target:
|
||||||
|
while space != -1:
|
||||||
|
newx, newy = self.level.intToCoords(space)
|
||||||
|
space = path[space]
|
||||||
|
self.setEvent(t * speed, _ge.GoEvent(self.player, newx, newy))
|
||||||
|
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, useArgs))
|
||||||
else:
|
else:
|
||||||
pos = self.level.coordsToInt(self.playerx, self.playery)
|
if not self.level.lineOfSight(self.player.x, self.player.y, x, y):
|
||||||
space = path[pos]
|
print("{} cannot use the {} on that from here.".format(self.player.name, item.name), file = self.outstream)
|
||||||
#target = self.level.coordsToInt(x, y)
|
elif thing == None:
|
||||||
t = 1
|
print("There is nothing to use the {} on here.".format(item.name), file = self.outstream)
|
||||||
#while space != target:
|
else:
|
||||||
while space != -1:
|
self.setEvent(0, _ge.UseOnEvent(item, thing, useArgs))
|
||||||
newx, newy = self.level.intToCoords(space)
|
|
||||||
space = path[space]
|
|
||||||
self.setEvent(t * speed, _ge.GoEvent(self.playerName, newx, newy))
|
|
||||||
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, useArgs))
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def take(self, args):
|
def take(self, args):
|
||||||
|
@ -509,6 +527,10 @@ If the player is not already close to it, they will go to it.
|
||||||
make more sense from a linguistic perspective (for instance, one could
|
make more sense from a linguistic perspective (for instance, one could
|
||||||
say "take the flask" rather than just "take flask").
|
say "take the flask" rather than just "take flask").
|
||||||
Object can be the name of the object, or its coordinates."""
|
Object can be the name of the object, or its coordinates."""
|
||||||
|
if self.level == None:
|
||||||
|
raise GameError("Cannot take: No level has been loaded.")
|
||||||
|
if self.player == None:
|
||||||
|
raise GameError("Cannot take: Player character doesn't exist.")
|
||||||
speed = 0.6666667
|
speed = 0.6666667
|
||||||
if args[0] == '-r' or args[0] == 'r' or args[0] == 'run':
|
if args[0] == '-r' or args[0] == 'r' or args[0] == 'run':
|
||||||
speed = 0.3333333
|
speed = 0.3333333
|
||||||
|
@ -525,16 +547,16 @@ Object can be the name of the object, or its coordinates."""
|
||||||
return
|
return
|
||||||
|
|
||||||
# Similar to go, but not quite the same.
|
# Similar to go, but not quite the same.
|
||||||
if (x, y) == (self.playerx, self.playery):
|
if (x, y) == (self.player.x, self.player.y):
|
||||||
self.setEvent(0.125, _ge.TakeEvent(thing))
|
self.setEvent(0.125, _ge.TakeEvent(self.player, thing))
|
||||||
return
|
return
|
||||||
dist, path = self.level.path(x, y, self.playerx, self.playery)
|
dist, path = self.level.path(x, y, self.player.x, self.player.y)
|
||||||
if dist == -1:
|
if dist == -1:
|
||||||
print('{0} cannot reach the {1}.'.format(self.playerName, thing.name), file = self.outstream)
|
print('{0} cannot reach the {1}.'.format(self.player.name, thing.name), file = self.outstream)
|
||||||
#_hq.heappush(self.eventQueue, (self.gameTime, _ge.NoOpEvent()))
|
#_hq.heappush(self.eventQueue, (self.gameTime, _ge.NoOpEvent()))
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
pos = self.level.coordsToInt(self.playerx, self.playery)
|
pos = self.level.coordsToInt(self.player.x, self.player.y)
|
||||||
space = path[pos]
|
space = path[pos]
|
||||||
#target = self.level.coordsToInt(x, y)
|
#target = self.level.coordsToInt(x, y)
|
||||||
t = 1
|
t = 1
|
||||||
|
@ -542,23 +564,31 @@ Object can be the name of the object, or its coordinates."""
|
||||||
while space != -1:
|
while space != -1:
|
||||||
newx, newy = self.level.intToCoords(space)
|
newx, newy = self.level.intToCoords(space)
|
||||||
space = path[space]
|
space = path[space]
|
||||||
self.setEvent(t * speed, _ge.GoEvent(self.playerName, newx, newy))
|
self.setEvent(t * speed, _ge.GoEvent(self.player, newx, newy))
|
||||||
t += 1
|
t += 1
|
||||||
#newx, newy = self.level.intToCoords(space)
|
#newx, newy = self.level.intToCoords(space)
|
||||||
#_hq.heappush(self.eventQueue, (self.gameTime + t * speed, _ge.GoEvent(self.playerName, newx, newy)))
|
#_hq.heappush(self.eventQueue, (self.gameTime + t * speed, _ge.GoEvent(self.player.name, newx, newy)))
|
||||||
self.setEvent(t * speed + 0.125, _ge.TakeEvent(thing))
|
self.setEvent(t * speed + 0.125, _ge.TakeEvent(self.player, thing))
|
||||||
return
|
return
|
||||||
|
|
||||||
def drop(self, args):
|
def drop(self, args):
|
||||||
"""drop [the] item"""
|
"""drop [the] item"""
|
||||||
|
if self.level == None:
|
||||||
|
raise GameError("Cannot drop: No level has been loaded.")
|
||||||
|
if self.player == None:
|
||||||
|
raise GameError("Cannot drop: Player character doesn't exist.")
|
||||||
if args[0] == 'the':
|
if args[0] == 'the':
|
||||||
args.pop(0)
|
args.pop(0)
|
||||||
for i in self.playerInv:
|
#for i in self.player.inventory:
|
||||||
thingName = self.playerInv[i].name
|
# thingName = self.player.inventory[i].name
|
||||||
if ' '.join(args) == thingName:
|
# if ' '.join(args) == thingName:
|
||||||
self.setEvent(0.0, _ge.DropEvent(self.playerInv[i]))
|
# self.setEvent(0.0, _ge.DropEvent(self.player.inventory[i]))
|
||||||
return
|
# return
|
||||||
print('{0} does not have a {1}.'.format(self.playerName, args[0]), file = self.outstream)
|
thingName = ' '.join(args)
|
||||||
|
if thingName in self.player.thingNames:
|
||||||
|
self.setEvent(0.0, _ge.DropEvent(self.player.getThingByName(thingName)))
|
||||||
|
else:
|
||||||
|
print('{0} does not have a {1}.'.format(self.player.name, args[0]), file = self.outstream)
|
||||||
|
|
||||||
def loadMap(self, args):
|
def loadMap(self, args):
|
||||||
# loadMap (fileName)
|
# loadMap (fileName)
|
||||||
|
@ -593,15 +623,27 @@ Object can be the name of the object, or its coordinates."""
|
||||||
|
|
||||||
print(self.level.openingText, file = self.outstream)
|
print(self.level.openingText, file = self.outstream)
|
||||||
#print(self.outstream.getvalue())
|
#print(self.outstream.getvalue())
|
||||||
if len(args) <= 2:
|
x, y = self.level.playerStart
|
||||||
self.playerx, self.playery = self.level.playerStart
|
if len(args) == 3:
|
||||||
|
x, y = int(args[1]), int(args[2])
|
||||||
|
if self.player == None:
|
||||||
|
# create a player to put in the level.
|
||||||
|
self.player = _gm.PlayerCharacter(x, y, self.playerDescription, {}, {}, self.playerName)
|
||||||
|
print("Player created.")
|
||||||
else:
|
else:
|
||||||
self.playerx, self.playery = int(args[1]), int(args[2])
|
self.player.x, self.player.y = x, y
|
||||||
self.prevx, self.prevy = self.playerx, self.playery
|
print("Player moved.")
|
||||||
|
self.player.prevx, self.player.prevy = self.player.x, self.player.y
|
||||||
|
self.nextThing = self.level.addThing(self.player, self.nextThing) # The player needs to be added to the new level.
|
||||||
if self.onLevelLoad != None:
|
if self.onLevelLoad != None:
|
||||||
self.onLevelLoad()
|
self.onLevelLoad()
|
||||||
self.parseScript(self.level.enterScript)
|
self.parseScript(self.level.enterScript)
|
||||||
|
|
||||||
|
def unloadMap(self, args):
|
||||||
|
"""Args is only there just in case."""
|
||||||
|
self.level = None
|
||||||
|
self.player = None
|
||||||
|
|
||||||
def saveGame(self, args):
|
def saveGame(self, args):
|
||||||
if len(args) < 1:
|
if len(args) < 1:
|
||||||
print("Save file must have a name!", file = self.outstream)
|
print("Save file must have a name!", file = self.outstream)
|
||||||
|
@ -619,7 +661,7 @@ Object can be the name of the object, or its coordinates."""
|
||||||
self.persist[self.level.name][i] = self.level.getThingByID(i)
|
self.persist[self.level.name][i] = self.level.getThingByID(i)
|
||||||
|
|
||||||
# build data object to be saved
|
# build data object to be saved
|
||||||
data = (self.playerName, self.playerx, self.playery, self.playerInv, self.level.name, self.persist, self.eventQueue, self.customValues, self.gameTime, self.nextThing)
|
data = (self.player, self.level.name, self.persist, self.eventQueue, self.customValues, self.gameTime, self.nextThing)
|
||||||
|
|
||||||
# save it!
|
# save it!
|
||||||
fileName = 'saves/' + args[0].replace(' ', '_') + '.dat'
|
fileName = 'saves/' + args[0].replace(' ', '_') + '.dat'
|
||||||
|
@ -650,9 +692,9 @@ Object can be the name of the object, or its coordinates."""
|
||||||
fileName = args[0]
|
fileName = args[0]
|
||||||
x, y, levelname = 1, 1, 'testing/test1.txt'
|
x, y, levelname = 1, 1, 'testing/test1.txt'
|
||||||
with open(fileName, 'rb') as f:
|
with open(fileName, 'rb') as f:
|
||||||
self.playerName, x, y, self.playerInv, levelname, self.persist, self.eventQueue, self.customValues, self.gameTime, self.nextThing = _pi.load(f)
|
self.player, levelname, self.persist, self.eventQueue, self.customValues, self.gameTime, self.nextThing = _pi.load(f)
|
||||||
#print(levelname, x, y, file = self.outstream)
|
#print(levelname, x, y, file = self.outstream)
|
||||||
self.loadMap((levelname, x, y))
|
self.loadMap((levelname, self.player.x, self.player.y))
|
||||||
#_hq.heappush(self.eventQueue, (self.gameTime, _ge.NoOpEvent()))
|
#_hq.heappush(self.eventQueue, (self.gameTime, _ge.NoOpEvent()))
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -788,41 +830,59 @@ Object can be the name of the object, or its coordinates."""
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def handleGo(self, e):
|
def handleGo(self, e):
|
||||||
if e.actor == self.playerName:
|
#if e.actor == self.playerName:
|
||||||
self.prevx, self.prevy = self.playerx, self.playery
|
# self.prevx, self.prevy = self.playerx, self.playery
|
||||||
self.playerx, self.playery = e.x, e.y
|
# self.playerx, self.playery = e.x, e.y
|
||||||
else:
|
#else:
|
||||||
actor = self.level.getThingByName(e.actor)
|
if e.actor == None:
|
||||||
self.level.moveThing(actor, e.x, e.y)
|
raise GameError("'Go' event raised for no object.")
|
||||||
|
self.level.moveThing(e.actor, e.x, e.y)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def handleArrive(self, e):
|
def handleArrive(self, e):
|
||||||
if e.actor == self.playerName:
|
#if e.actor == self.playerName:
|
||||||
self.prevx, self.prevy = self.playerx, self.playery
|
# self.prevx, self.prevy = self.playerx, self.playery
|
||||||
self.playerx, self.playery = e.x, e.y
|
# self.playerx, self.playery = e.x, e.y
|
||||||
print('{0} arrived at {1}{2} after {3:.1f} seconds.'.format(self.playerName, self.numberToLetter(e.x), e.y, e.t), file = self.outstream)
|
# print('{0} arrived at {1}{2} after {3:.1f} seconds.'.format(self.playerName, self.numberToLetter(e.x), e.y, e.t), file = self.outstream)
|
||||||
thing = self.level.getThingAtCoords(self.playerx, self.playery)
|
# thing = self.level.getThingAtCoords(self.playerx, self.playery)
|
||||||
if thing:
|
# if thing:
|
||||||
if thing.thingType == 'x':
|
# if thing.thingType == 'x':
|
||||||
|
# self.parseScript(thing.onUse)
|
||||||
|
# if (isinstance(thing.key, bool) and thing.key == True) or (isinstance(thing.key, str) and self.parseScript(thing.key)):
|
||||||
|
# a = self.requestInput('Do you want to go {0}? (Y/n)'.format(str(thing)))
|
||||||
|
# if a != 'n' and a != 'N':
|
||||||
|
# self.loadMap((thing.destination, thing.exitid))
|
||||||
|
# return True
|
||||||
|
#else:
|
||||||
|
# actor = self.level.getThingByName(e.actor)
|
||||||
|
# if actor:
|
||||||
|
# self.level.moveThing(e.actor, e.x, e.y)
|
||||||
|
# print('{0} arrived at {1}{2} after {3:.1f} seconds.'.format(actor.name, self.numberToLetter(e.x), e.y, e.t), file = self.outstream)
|
||||||
|
# thing = self.level.getThingAtCoords(actor.x, actor.y)
|
||||||
|
# if thing and thing != actor:
|
||||||
|
# if thing.thingType == 'x':
|
||||||
|
# print('{0} went {1}.'.format(actor.name, str(thing)))
|
||||||
|
# self.level.removeThing(actor.name)
|
||||||
|
# else:
|
||||||
|
# print('There is nothing by the name of {0}.'.format(e.actor), file = self.outstream)
|
||||||
|
# return False
|
||||||
|
if e.actor == None:
|
||||||
|
raise GameError("'Go' event raised for no object.")
|
||||||
|
thing = self.level.getThingAtCoords(e.x, e.y)
|
||||||
|
self.level.moveThing(e.actor, e.x, e.y)
|
||||||
|
print('{0} arrived at {1}{2} after {3:.1f} seconds.'.format(e.actor.name, self.numberToLetter(e.x), e.y, e.t), file = self.outstream)
|
||||||
|
if thing:
|
||||||
|
if thing.thingType == 'x':
|
||||||
|
if e.actor == self.player:
|
||||||
self.parseScript(thing.onUse)
|
self.parseScript(thing.onUse)
|
||||||
if (isinstance(thing.key, bool) and thing.key == True) or (isinstance(thing.key, str) and self.parseScript(thing.key)):
|
if (isinstance(thing.key, bool) and thing.key == True) or (isinstance(thing.key, str) and self.parseScript(thing.key)):
|
||||||
a = self.requestInput('Do you want to go {0}? (Y/n)'.format(str(thing)))
|
a = self.requestInput('Do you want to go {0}? (Y/n)'.format(str(thing)))
|
||||||
if a != 'n' and a != 'N':
|
if a != 'n' and a != 'N':
|
||||||
self.loadMap((thing.destination, thing.exitid))
|
self.loadMap((thing.destination, thing.exitid))
|
||||||
return True
|
else:
|
||||||
else:
|
print('{0} went {1}.'.format(actor.name, str(thing)))
|
||||||
actor = self.level.getThingByName(e.actor)
|
self.level.removeThing(actor.name)
|
||||||
if actor:
|
return True
|
||||||
self.level.moveThing(e.actor, e.x, e.y)
|
|
||||||
print('{0} arrived at {1}{2} after {3:.1f} seconds.'.format(actor.name, self.numberToLetter(e.x), e.y, e.t), file = self.outstream)
|
|
||||||
thing = self.level.getThingAtCoords(actor.x, actor.y)
|
|
||||||
if thing and thing != actor:
|
|
||||||
if thing.thingType == 'x':
|
|
||||||
print('{0} went {1}.'.format(actor.name, str(thing)))
|
|
||||||
self.level.removeThing(actor.name)
|
|
||||||
else:
|
|
||||||
print('There is nothing by the name of {0}.'.format(e.actor), file = self.outstream)
|
|
||||||
return False
|
|
||||||
|
|
||||||
def handleUse(self, e):
|
def handleUse(self, e):
|
||||||
if e.thing.useFunc == '':
|
if e.thing.useFunc == '':
|
||||||
|
@ -839,15 +899,19 @@ Object can be the name of the object, or its coordinates."""
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def handleTake(self, e):
|
def handleTake(self, e):
|
||||||
|
if e.actor == None or e.actor.thingType not in 'np' or e.item == None:
|
||||||
|
raise GameError("'Take' event cannot be handled.")
|
||||||
self.level.removeThingByID(e.item.thingID)
|
self.level.removeThingByID(e.item.thingID)
|
||||||
self.playerInv[e.item.thingID] = e.item
|
e.actor.addThing(e.item)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def handleDrop(self, e):
|
def handleDrop(self, e):
|
||||||
e.item.x = self.playerx
|
if e.actor == None or e.actor.thingType not in 'np':
|
||||||
e.item.y = self.playery
|
raise GameError("'Drop' event cannot be handled.")
|
||||||
|
e.item.x = e.actor.x
|
||||||
|
e.item.y = e.actor.y
|
||||||
self.nextThing = self.level.addThing(e.item, self.nextThing, True) # nextThing shouldn't change
|
self.nextThing = self.level.addThing(e.item, self.nextThing, True) # nextThing shouldn't change
|
||||||
del self.playerInv[e.item.thingID]
|
self.actor.removeThing(e.item)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def handleBehave(self, e):
|
def handleBehave(self, e):
|
||||||
|
@ -890,7 +954,7 @@ Object can be the name of the object, or its coordinates."""
|
||||||
def container(self, thing, args):
|
def container(self, thing, args):
|
||||||
"""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 = list(thing.customValues['items'])
|
items = list(thing.customValues['items'])
|
||||||
self.playerInv, thing.customValues['items'], timeOpen = self.getIO('container')(self.playerInv, items)
|
thing.customValues['items'], timeOpen = self.getIO('container')(self.player, items)
|
||||||
return timeOpen
|
return timeOpen
|
||||||
|
|
||||||
def info(self, thing, args):
|
def info(self, thing, args):
|
||||||
|
@ -901,31 +965,24 @@ Object can be the name of the object, or its coordinates."""
|
||||||
def wear(self, item, args):
|
def wear(self, item, args):
|
||||||
"""Wear clotherg or otherwise equip a passive item."""
|
"""Wear clotherg or otherwise equip a passive item."""
|
||||||
# An item must be in the player's inventory in order to wear it.
|
# An item must be in the player's inventory in order to wear it.
|
||||||
inInv = False
|
inInv = item in self.player.inventory
|
||||||
for i in self.playerInv:
|
|
||||||
if i == item.thingID:
|
|
||||||
inInv = True
|
|
||||||
break
|
|
||||||
if not inInv:
|
if not inInv:
|
||||||
print("You cannot wear what you are not carrying.", file = self.outstream)
|
print("You cannot wear what you are not carrying.", file = self.outstream)
|
||||||
return 0.0
|
return 0.0
|
||||||
if 'wearing' not in self.customValues:
|
if 'wearing' not in self.customValues:
|
||||||
self.customValues['wearing'] = {}
|
self.customValues['wearing'] = {}
|
||||||
if item.customValues['slot'] not in self.customValues['wearing']:
|
if item.customValues['slot'] not in self.customValues['wearing']:
|
||||||
self.customValues['wearing'][item.customValues['slot']] = item
|
self.customValues['wearing'][item.customValues['slot']] = self.player.removeThing(item)
|
||||||
# This is so a player can't put on a garment, then drop it while
|
# This is so a player can't put on a garment, then drop it while
|
||||||
# still also wearing it.
|
# still also wearing it.
|
||||||
del self.playerInv[item.thingID]
|
print("{} put on the {}.".format(self.player.name, item.name), file = self.outstream)
|
||||||
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
|
else: # the player must be wearing something that will get in the way
|
||||||
# put the old clothes back in the inventory
|
# put the old clothes back in the inventory
|
||||||
oldItem = self.customValues['wearing'][item.customValues['slot']]
|
self.player.addThing(self.customValues['wearing'][item.customValues['slot']])
|
||||||
self.playerInv[oldItem.thingID] = oldItem
|
self.customValues['wearing'][item.customValues['slot']] = self.player.removeThing(item)
|
||||||
self.customValues['wearing'][item.customValues['slot']] = item
|
|
||||||
# This is so a player can't put on a garment, then drop it while
|
# This is so a player can't put on a garment, then drop it while
|
||||||
# still also wearing it.
|
# still also wearing it.
|
||||||
del self.playerInv[item.thingID]
|
print("{} took off the {} and put on the {}.".format(self.player.name, oldItem.name, item.name), file = self.outstream)
|
||||||
print("{} took off the {} and put on the {}.".format(self.playerName, oldItem.name, item.name), file = self.outstream)
|
|
||||||
return 1.0
|
return 1.0
|
||||||
|
|
||||||
# item use-on functions
|
# item use-on functions
|
||||||
|
@ -937,8 +994,8 @@ Object can be the name of the object, or its coordinates."""
|
||||||
return 0.0
|
return 0.0
|
||||||
if thing.lock(item.name):
|
if thing.lock(item.name):
|
||||||
print("The key fits the lock.", file = self.outstream)
|
print("The key fits the lock.", file = self.outstream)
|
||||||
if not thing.passable and self.playerx == thing.x and self.playery == thing.y:
|
if not thing.passable and self.player.x == thing.x and self.player.y == thing.y:
|
||||||
self.playerx, self.playery = self.prevx, self.prevy
|
self.player.x, self.player.y = self.player.prevx, self.player.prevy
|
||||||
else:
|
else:
|
||||||
print("The key doesn't fit that lock.", file = self.outstream)
|
print("The key doesn't fit that lock.", file = self.outstream)
|
||||||
return 0.125
|
return 0.125
|
||||||
|
@ -1191,7 +1248,7 @@ Object can be the name of the object, or its coordinates."""
|
||||||
equalsign = i.index('=')
|
equalsign = i.index('=')
|
||||||
cv = i[3:equalsign]
|
cv = i[3:equalsign]
|
||||||
customValues[cv] = self.getValueFromString(i[equalsign+1:])
|
customValues[cv] = self.getValueFromString(i[equalsign+1:])
|
||||||
thing = _gm.NPC(name, x, y, description, behavior, inv, customValues, playerx, playery, False, (bgc, fgc, shape))
|
thing = _gm.NPC(name, x, y, description, behavior, inv, customValues, playerx, playery, (bgc, fgc, shape))
|
||||||
elif args[0].casefold() == 'door':
|
elif args[0].casefold() == 'door':
|
||||||
# spawn a door
|
# spawn a door
|
||||||
description = 'a nondescript door.'
|
description = 'a nondescript door.'
|
||||||
|
@ -1303,7 +1360,7 @@ Object can be the name of the object, or its coordinates."""
|
||||||
customValues[cv] = getValueFromString(i[equalsign+1:])
|
customValues[cv] = getValueFromString(i[equalsign+1:])
|
||||||
thing = _gm.Item(name, x, y, description, useFunc, useOnFunc, customValues, ranged, (bgc, fgc, shape))
|
thing = _gm.Item(name, x, y, description, useFunc, useOnFunc, customValues, ranged, (bgc, fgc, shape))
|
||||||
thing.thingID = self.nextThing
|
thing.thingID = self.nextThing
|
||||||
self.playerInv[thing.thingID] = thing
|
self.player.addThing(thing)
|
||||||
self.nextThing += 1
|
self.nextThing += 1
|
||||||
return thing
|
return thing
|
||||||
|
|
||||||
|
|
|
@ -92,13 +92,15 @@ class UseOnEvent(GameEvent):
|
||||||
self.args = args
|
self.args = args
|
||||||
|
|
||||||
class TakeEvent(GameEvent):
|
class TakeEvent(GameEvent):
|
||||||
def __init__(self, item):
|
def __init__(self, actor, item):
|
||||||
super(TakeEvent, self).__init__('take')
|
super(TakeEvent, self).__init__('take')
|
||||||
|
self.actor = actor
|
||||||
self.item = item
|
self.item = item
|
||||||
|
|
||||||
class DropEvent(GameEvent):
|
class DropEvent(GameEvent):
|
||||||
def __init__(self, item):
|
def __init__(self, actor, item):
|
||||||
super(DropEvent, self).__init__('drop')
|
super(DropEvent, self).__init__('drop')
|
||||||
|
self.actor = actor
|
||||||
self.item = item
|
self.item = item
|
||||||
|
|
||||||
class BehaveEvent(GameEvent):
|
class BehaveEvent(GameEvent):
|
||||||
|
|
215
gamemap.py
215
gamemap.py
|
@ -16,6 +16,8 @@ class Thing(object):
|
||||||
self.y = y
|
self.y = y
|
||||||
self.playerx = x
|
self.playerx = x
|
||||||
self.playery = y
|
self.playery = y
|
||||||
|
self.prevx = x # if an area gets double-occupied, a thing can get pushed back.
|
||||||
|
self.prevy = y
|
||||||
if playerx:
|
if playerx:
|
||||||
self.playerx = playerx
|
self.playerx = playerx
|
||||||
if playery:
|
if playery:
|
||||||
|
@ -179,27 +181,84 @@ class Useable(Thing):
|
||||||
return cls(parts['name'], parts['location'][0], parts['location'][1],
|
return cls(parts['name'], parts['location'][0], parts['location'][1],
|
||||||
parts['description'], useFunc, customValues, playerx, playery, graphic)
|
parts['description'], useFunc, customValues, playerx, playery, graphic)
|
||||||
|
|
||||||
class NPC(Thing):
|
class Character(Thing):
|
||||||
|
defaultGraphic = ('clear', '#000000', 'o')
|
||||||
|
|
||||||
|
def __init__(self, thingType: str, name: str, x: int, y: int,
|
||||||
|
description: str, inventory: dict, customValues: dict,
|
||||||
|
flags: int, playerx = None, playery = None, graphic = defaultGraphic):
|
||||||
|
super(Character, self).__init__(thingType, name, x, y, description, flags)
|
||||||
|
if inventory == None:
|
||||||
|
inventory = {} # create a new dict for the inventory.
|
||||||
|
# This couldn't be in the NPC constructor because
|
||||||
|
# then all characters would share a reference to
|
||||||
|
# the same empty inventory.
|
||||||
|
self.__inventory = inventory
|
||||||
|
self.customValues = customValues
|
||||||
|
self.graphic = graphic
|
||||||
|
self.thingNames = {}
|
||||||
|
# set up inventory shtuff
|
||||||
|
for i in self.__inventory:
|
||||||
|
if self.__inventory[i].name in self.thingNames:
|
||||||
|
self.thingNames[self.__inventory[i].name].append(i)
|
||||||
|
else:
|
||||||
|
self.thingNames[self.__inventory[i].name] = [i]
|
||||||
|
|
||||||
|
def addThing(self, thing):
|
||||||
|
if not isinstance(thing, Item):
|
||||||
|
raise TypeError("Only items can be added to a character's inventory.")
|
||||||
|
self.__inventory[thing.thingID] = thing
|
||||||
|
if thing.name in self.thingNames:
|
||||||
|
self.thingNames[thing.name].append(thing.thingID)
|
||||||
|
else:
|
||||||
|
self.thingNames[thing.name] = [thing.thingID]
|
||||||
|
|
||||||
|
def getThingByID(self, thingID):
|
||||||
|
return self.__inventory[thingID]
|
||||||
|
|
||||||
|
def getThingByName(self, name):
|
||||||
|
if name in self.thingNames:
|
||||||
|
return self.__inventory[self.thingNames[name][0]]
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def removeThingByID(self, thingID):
|
||||||
|
ret = self.__inventory[thingID]
|
||||||
|
self.thingNames[ret.name].remove(thingID)
|
||||||
|
if len(self.thingNames[ret.name]) == 0:
|
||||||
|
del self.thingNames[ret.name]
|
||||||
|
del self.__inventory[thingID]
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def removeThingByName(self, name):
|
||||||
|
ret = self.getThingByName(name)
|
||||||
|
self.thingNames[ret.name].remove(thingID)
|
||||||
|
if len(self.thingNames[ret.name]) == 0:
|
||||||
|
del self.thingNames[ret.name]
|
||||||
|
del self.__inventory[thingID]
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def removeThing(self, ret):
|
||||||
|
self.thingNames[ret.name].remove(ret.thingID)
|
||||||
|
if len(self.thingNames[ret.name]) == 0:
|
||||||
|
del self.thingNames[ret.name]
|
||||||
|
del self.__inventory[ret.thingID]
|
||||||
|
return ret
|
||||||
|
|
||||||
|
@property
|
||||||
|
def inventory(self):
|
||||||
|
"""Get the inventory as a list."""
|
||||||
|
return list(self.__inventory.values())
|
||||||
|
|
||||||
|
class NPC(Character):
|
||||||
yaml_flag = u'!NPC'
|
yaml_flag = u'!NPC'
|
||||||
defaultGraphic = ('clear', '#000000', 'o')
|
defaultGraphic = ('clear', '#000000', 'o')
|
||||||
|
|
||||||
def __init__(self, name, x: int, y: int, description: str, behavior: str, inventory: list, customValues: dict, playerx = None, playery = None, following = False, graphic = defaultGraphic):
|
def __init__(self, name, x: int, y: int, description: str, behavior: str, inventory: list, customValues: dict, playerx = None, playery = None, graphic = defaultGraphic):
|
||||||
super(NPC, self).__init__('c', name, x, y, description, 6, playerx, playery)
|
super(NPC, self).__init__('n', name, x, y, description, None, customValues, 6, playerx, playery, graphic)
|
||||||
self.behavior = behavior
|
self.behavior = behavior
|
||||||
self.following = following
|
|
||||||
self.inventory = inventory
|
|
||||||
self.customValues = customValues
|
|
||||||
self.graphic = graphic
|
|
||||||
self.behaveEvent = None
|
self.behaveEvent = None
|
||||||
|
self.tempInventory = inventory # should be deleted once NPC is loaded
|
||||||
def give(self, item):
|
|
||||||
self.inventory.append(item)
|
|
||||||
|
|
||||||
def drop(self, index):
|
|
||||||
return self.inventory.pop(index)
|
|
||||||
|
|
||||||
def dialog(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def to_yaml(cls, representer, node):
|
def to_yaml(cls, representer, node):
|
||||||
|
@ -217,8 +276,6 @@ class NPC(Thing):
|
||||||
if len(graphic) > 0:
|
if len(graphic) > 0:
|
||||||
ret['graphic'] = graphic
|
ret['graphic'] = graphic
|
||||||
# save use functions
|
# save use functions
|
||||||
if node.following:
|
|
||||||
ret['following'] = node.following
|
|
||||||
if len(node.inventory) > 0:
|
if len(node.inventory) > 0:
|
||||||
ret['inventory'] = node.inventory
|
ret['inventory'] = node.inventory
|
||||||
if len(node.customValues) > 0:
|
if len(node.customValues) > 0:
|
||||||
|
@ -249,8 +306,6 @@ class NPC(Thing):
|
||||||
shape = parts['graphic']['shape']
|
shape = parts['graphic']['shape']
|
||||||
graphic = (bgc, fgc, shape)
|
graphic = (bgc, fgc, shape)
|
||||||
# load use functions
|
# load use functions
|
||||||
if 'following' in parts:
|
|
||||||
useFunc = parts['following']
|
|
||||||
if 'inventory' in parts:
|
if 'inventory' in parts:
|
||||||
inventory = parts['inventory']
|
inventory = parts['inventory']
|
||||||
if 'customValues' in parts:
|
if 'customValues' in parts:
|
||||||
|
@ -262,7 +317,7 @@ class NPC(Thing):
|
||||||
playerx, playery = parts['useLocation']
|
playerx, playery = parts['useLocation']
|
||||||
return cls(parts['name'], parts['location'][0], parts['location'][1],
|
return cls(parts['name'], parts['location'][0], parts['location'][1],
|
||||||
parts['description'], parts['behavior'], inventory, customValues,
|
parts['description'], parts['behavior'], inventory, customValues,
|
||||||
playerx, playery, following, graphic)
|
playerx, playery, graphic)
|
||||||
|
|
||||||
class Door(Thing):
|
class Door(Thing):
|
||||||
yaml_flag = u'!Door'
|
yaml_flag = u'!Door'
|
||||||
|
@ -445,6 +500,13 @@ class MapEntrance(Thing):
|
||||||
# set default values for optional arguments
|
# set default values for optional arguments
|
||||||
return cls(parts['location'][0], parts['location'][1], parts['id'])
|
return cls(parts['location'][0], parts['location'][1], parts['id'])
|
||||||
|
|
||||||
|
class PlayerCharacter(Character):
|
||||||
|
"""Player object. Cannot be created with yaml."""
|
||||||
|
defaultGraphic = ('clear', '#0000FF', 'o')
|
||||||
|
|
||||||
|
def __init__(self, x: int, y: int, description: str, inventory: dict, customValues: dict, name = 'You', graphic = defaultGraphic):
|
||||||
|
super(PlayerCharacter, self).__init__('p', name, x, y, description, inventory, customValues, 5, graphic=graphic)
|
||||||
|
|
||||||
class MapError(RuntimeError):
|
class MapError(RuntimeError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -493,86 +555,6 @@ class GameMap(object):
|
||||||
break
|
break
|
||||||
return text.replace('\n', end)
|
return text.replace('\n', end)
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def convert(infile: str):
|
|
||||||
"""Convert an XML map to a YAML one."""
|
|
||||||
data = None
|
|
||||||
with open(infile, 'r') as f:
|
|
||||||
data = f.read()
|
|
||||||
info = ET.fromstring(data)
|
|
||||||
layout = info.find('layout')
|
|
||||||
ret = {}
|
|
||||||
if layout == None:
|
|
||||||
raise MapError('No layout in {0}.'.format(infile))
|
|
||||||
|
|
||||||
# "Layout" needs some work before we convert it.
|
|
||||||
ret['layout'] = GameMap.__cleanStr(layout.text.strip())
|
|
||||||
|
|
||||||
# now the rest of the things
|
|
||||||
if 'openingText' in info.attrib:
|
|
||||||
ret['openingText'] = info.attrib['openingText']
|
|
||||||
else:
|
|
||||||
raise MapError('No opening text in {0}.'.format(infile))
|
|
||||||
if 'playerStart' in info.attrib:
|
|
||||||
ps = info.attrib['playerStart'].split(',')
|
|
||||||
ret['playerStart'] = (int(ps[0]), int(ps[1]))
|
|
||||||
else:
|
|
||||||
raise MapError('No player start position in {0}.'.format(infile))
|
|
||||||
if info.text != None:
|
|
||||||
ret['description'] = GameMap.__cleanStr(info.text, ' ')
|
|
||||||
else:
|
|
||||||
raise MapError('No description in {0}.'.format(infile))
|
|
||||||
|
|
||||||
# get map colors
|
|
||||||
floorColors = ['#9F7F5F']
|
|
||||||
floorColorsStr = info.find('floorColors')
|
|
||||||
if floorColorsStr != None:
|
|
||||||
floorColors = floorColorsStr.text.lstrip().split()
|
|
||||||
if len(floorColors) == 0:
|
|
||||||
floorColors.append('#9F7F5F')
|
|
||||||
ret['floorColors'] = floorColors
|
|
||||||
wallColors = ['#7F3F0F']
|
|
||||||
wallColorsStr = info.find('wallColors')
|
|
||||||
if wallColorsStr != None:
|
|
||||||
wallColors = wallColorsStr.text.lstrip().split()
|
|
||||||
if len(wallColors) == 0:
|
|
||||||
wallColors.append('#7F3F0F')
|
|
||||||
ret['wallColors'] = wallColors
|
|
||||||
|
|
||||||
# get things
|
|
||||||
ret['loadAlways'] = []
|
|
||||||
ret['loadOnce'] = []
|
|
||||||
for node in info:
|
|
||||||
if node.tag == 'loadOnce':
|
|
||||||
# Things in the load-once section are only loaded the first
|
|
||||||
# time that the map is loaded, and saved in the player's
|
|
||||||
# save file.
|
|
||||||
for node1 in node:
|
|
||||||
if node1.tag == 'door':
|
|
||||||
ret['loadOnce'].append(GameMap.__loadDoor(node1))
|
|
||||||
elif node1.tag == 'useable':
|
|
||||||
ret['loadOnce'].append(GameMap.__loadUseable(node1))
|
|
||||||
elif node1.tag == 'item':
|
|
||||||
ret['loadOnce'].append(GameMap.__loadItem(node1))
|
|
||||||
elif node.tag == 'exit':
|
|
||||||
ret['loadAlways'].append(GameMap.__loadExit(None, node, -1)) # weird arguments: there is no actual level
|
|
||||||
elif node.tag == 'door':
|
|
||||||
ret['loadAlways'].append(GameMap.__loadDoor(node))
|
|
||||||
elif node.tag == 'useable':
|
|
||||||
ret['loadAlways'].append(GameMap.__loadUseable(node))
|
|
||||||
|
|
||||||
#start saving
|
|
||||||
outfile = infile[:-3] + 'yml'
|
|
||||||
yaml = ruamel.yaml.YAML()
|
|
||||||
yaml.indent(mapping=4, sequence=4, offset=2)
|
|
||||||
yaml.register_class(Item)
|
|
||||||
yaml.register_class(Useable)
|
|
||||||
yaml.register_class(Door)
|
|
||||||
yaml.register_class(MapExit)
|
|
||||||
with open(outfile, 'w') as f:
|
|
||||||
f.write('%YAML 1.2\n---\n')
|
|
||||||
yaml.dump(ret, f)
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def read(infile = None, prevMap = None, preLoaded = False, nextThing = 0):
|
def read(infile = None, prevMap = None, preLoaded = False, nextThing = 0):
|
||||||
"""Read map data and return a Map object. If infile is not provided, then
|
"""Read map data and return a Map object. If infile is not provided, then
|
||||||
|
@ -729,12 +711,15 @@ list of lists of tuples."""
|
||||||
nextThing += 1
|
nextThing += 1
|
||||||
# Some things, like containers, have other things as custom values,
|
# Some things, like containers, have other things as custom values,
|
||||||
# so they need IDs as well.
|
# so they need IDs as well.
|
||||||
if thing.thingType in 'iuc':
|
if thing.thingType in 'iun':
|
||||||
nextThing = self.addThingRecursive(thing.customValues, nextThing)
|
nextThing = self.addThingRecursive(thing.customValues, nextThing)
|
||||||
if thing.thingType == 'c':
|
if thing.thingType == 'n':
|
||||||
for i in thing.inventory:
|
for i in thing.tempInventory:
|
||||||
i.thingID = nextThing
|
if i.thingID == -1:
|
||||||
nextThing += 1
|
i.thingID = nextThing
|
||||||
|
nextThing = self.addThingRecursive(i.customValues, nextThing + 1)
|
||||||
|
thing.addThing(i)
|
||||||
|
del thing.tempInventory
|
||||||
pos = self.coordsToInt(thing.x, thing.y)
|
pos = self.coordsToInt(thing.x, thing.y)
|
||||||
if pos not in self.thingPos:
|
if pos not in self.thingPos:
|
||||||
self.thingPos[pos] = [thing.thingID]
|
self.thingPos[pos] = [thing.thingID]
|
||||||
|
@ -751,8 +736,12 @@ list of lists of tuples."""
|
||||||
|
|
||||||
def addThingRecursive(self, container, nextThing = 0):
|
def addThingRecursive(self, container, nextThing = 0):
|
||||||
if isinstance(container, Thing):
|
if isinstance(container, Thing):
|
||||||
container.thingID = nextThing
|
if container.thingID == -1:
|
||||||
return nextThing + 1
|
container.thingID = nextThing
|
||||||
|
nextThing = self.addThingRecursive(container.customValues, nextThing)
|
||||||
|
return nextThing + 1
|
||||||
|
else:
|
||||||
|
return nextThing
|
||||||
elif isinstance(container, dict):
|
elif isinstance(container, dict):
|
||||||
for i in container:
|
for i in container:
|
||||||
nextThing = self.addThingRecursive(container[i], nextThing)
|
nextThing = self.addThingRecursive(container[i], nextThing)
|
||||||
|
@ -838,6 +827,10 @@ The closeEnough parameter will create a path that lands beside the source if nec
|
||||||
# return -1, [] # meaning you can't get there
|
# return -1, [] # meaning you can't get there
|
||||||
|
|
||||||
def lineOfSight(self, x1, y1, x2, y2):
|
def lineOfSight(self, x1, y1, x2, y2):
|
||||||
|
"""Test for line of signt from one tile to another."""
|
||||||
|
# Trivial case first:
|
||||||
|
if abs(x1 - x2) <= 1 and abs(y1 - y2) <= 1:
|
||||||
|
return True
|
||||||
Dx = x2 - x1
|
Dx = x2 - x1
|
||||||
Dy = y2 - y1
|
Dy = y2 - y1
|
||||||
y = y1 + 0.5
|
y = y1 + 0.5
|
||||||
|
@ -913,10 +906,7 @@ The closeEnough parameter will create a path that lands beside the source if nec
|
||||||
|
|
||||||
def getThingsAtPos(self, pos):
|
def getThingsAtPos(self, pos):
|
||||||
if pos in self.thingPos:
|
if pos in self.thingPos:
|
||||||
ret = []
|
return [self.things[i] for i in self.thingPos[pos]]
|
||||||
for i in self.thingPos[pos]:
|
|
||||||
ret.append(self.things[i])
|
|
||||||
return ret
|
|
||||||
else:
|
else:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
@ -1019,6 +1009,7 @@ The closeEnough parameter will create a path that lands beside the source if nec
|
||||||
else:
|
else:
|
||||||
self.thingPos[newPos].append(thing.thingID)
|
self.thingPos[newPos].append(thing.thingID)
|
||||||
relPlayerx, relPlayery = thing.playerx - thing.x, thing.playery - thing.y
|
relPlayerx, relPlayery = thing.playerx - thing.x, thing.playery - thing.y
|
||||||
|
thing.prevx, thing.prevy = thing.x, thing.y
|
||||||
thing.x, thing.y = x, y
|
thing.x, thing.y = x, y
|
||||||
thing.playerx, thing.playery = thing.x + relPlayerx, thing.y + relPlayery
|
thing.playerx, thing.playery = thing.x + relPlayerx, thing.y + relPlayery
|
||||||
else:
|
else:
|
||||||
|
|
84
gameshell.py
84
gameshell.py
|
@ -46,7 +46,6 @@ class GameShell(Shell):
|
||||||
self.gameBase.registerIO('dialog', self.dialog)
|
self.gameBase.registerIO('dialog', self.dialog)
|
||||||
self.gameBase.registerIO('info', self.info)
|
self.gameBase.registerIO('info', self.info)
|
||||||
self.gameBase.registerIO('playercmd', self.playercmd)
|
self.gameBase.registerIO('playercmd', self.playercmd)
|
||||||
self.menuMode()
|
|
||||||
|
|
||||||
# Helper functions
|
# Helper functions
|
||||||
|
|
||||||
|
@ -148,25 +147,33 @@ If -l is given, a map legend will be printed under the map."""
|
||||||
level = self.gameBase.level
|
level = self.gameBase.level
|
||||||
textColor = level.wallColors[0]
|
textColor = level.wallColors[0]
|
||||||
floorColor = level.floorColors[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]):
|
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.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:]))
|
rows[-1].append(self.color(textColor[1:]))
|
||||||
for x in range(level.dimensions[0]):
|
for x in range(level.dimensions[0]):
|
||||||
pos = level.mapMatrix[y][x]
|
pos = level.mapMatrix[y][x]
|
||||||
thing = level.getThingAtPos(index)
|
things = level.getThingsAtPos(index)
|
||||||
if x == self.gameBase.playerx and y == self.gameBase.playery:
|
#if x == self.gameBase.playerx and y == self.gameBase.playery:
|
||||||
if '#0000FF' != textColor:
|
# if self.gameBase.player != textColor:
|
||||||
textColor = '#0000FF'
|
# textColor = '#0000FF'
|
||||||
rows[-1].append(self.color(textColor[1:]))
|
# rows[-1].append(self.color(textColor[1:]))
|
||||||
rows[-1].append('()')
|
# rows[-1].append('()')
|
||||||
elif thing:
|
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[1] != textColor:
|
if thing.graphic[1] != textColor:
|
||||||
textColor = thing.graphic[1]
|
textColor = thing.graphic[1]
|
||||||
rows[-1].append(self.color(textColor[1:]))
|
rows[-1].append(self.color(textColor[1:]))
|
||||||
if thing.thingType == 'x': # exit
|
if thing.thingType == 'p': # player
|
||||||
|
rows[-1].append('()')
|
||||||
|
elif thing.thingType == 'x': # exit
|
||||||
rows[-1].append('X{0}'.format(thing.exitid))
|
rows[-1].append('X{0}'.format(thing.exitid))
|
||||||
exits[thing.exitid] = (thing.name, thing.graphic[1])
|
exits[thing.exitid] = (thing.name, thing.graphic[1])
|
||||||
elif thing.thingType == 'c': # useable
|
elif thing.thingType == 'n': # NPC
|
||||||
characters[len(characters)+1] = (thing.name, thing.graphic[1])
|
characters[len(characters)+1] = (thing.name, thing.graphic[1])
|
||||||
rows[-1].append('C{0}'.format(len(characters)))
|
rows[-1].append('C{0}'.format(len(characters)))
|
||||||
elif thing.thingType == 'd': # door
|
elif thing.thingType == 'd': # door
|
||||||
|
@ -178,7 +185,7 @@ If -l is given, a map legend will be printed under the map."""
|
||||||
elif thing.thingType == 'i': # item
|
elif thing.thingType == 'i': # item
|
||||||
items[len(items)+1] = (thing.name, thing.graphic[1])
|
items[len(items)+1] = (thing.name, thing.graphic[1])
|
||||||
rows[-1].append('I{0}'.format(len(items)))
|
rows[-1].append('I{0}'.format(len(items)))
|
||||||
elif thing.thingType == 'a': # entrance
|
else: # entrance
|
||||||
rows[-1].append(' ')
|
rows[-1].append(' ')
|
||||||
elif pos[0] == 'w':
|
elif pos[0] == 'w':
|
||||||
if level.wallColors[level.mapMatrix[y][x][1]] != textColor:
|
if level.wallColors[level.mapMatrix[y][x][1]] != textColor:
|
||||||
|
@ -245,12 +252,12 @@ If -l is given, a map legend will be printed under the map."""
|
||||||
ret.append("custom values:")
|
ret.append("custom values:")
|
||||||
for i in self.gameBase.customValues:
|
for i in self.gameBase.customValues:
|
||||||
ret.append("{0:<22}: {1}".format(i, self.gameBase.customValues[i]))
|
ret.append("{0:<22}: {1}".format(i, self.gameBase.customValues[i]))
|
||||||
ret.append("Player name:{0:.>68}".format(self.gameBase.playerName))
|
ret.append("Player name:{0:.>68}".format(self.gameBase.player.name))
|
||||||
ret.append("Player position:{0:.>64}".format("{0}{1}".format(self.gameBase.numberToLetter(self.gameBase.playerx), self.gameBase.playery)))
|
ret.append("Player position:{0:.>64}".format("{0}{1}".format(self.gameBase.numberToLetter(self.gameBase.player.x), self.gameBase.player.y)))
|
||||||
ret.append("Prev. position:{0:.>65}".format("{0}{1}".format(self.gameBase.numberToLetter(self.gameBase.prevx), self.gameBase.prevy)))
|
ret.append("Prev. position:{0:.>65}".format("{0}{1}".format(self.gameBase.numberToLetter(self.gameBase.player.prevx), self.gameBase.player.prevy)))
|
||||||
ret.append("Inventory:")
|
ret.append("Inventory:")
|
||||||
for i in self.gameBase.playerInv:
|
for i in self.gameBase.player.inventory:
|
||||||
ret.append("{0:<8}: {1}".format(i, self.gameBase.playerInv[i].name))
|
ret.append("{0:<8}: {1}".format(i.thingID, i.name))
|
||||||
ret.append("Things:\nID Name X Y")
|
ret.append("Things:\nID Name X Y")
|
||||||
for i in self.gameBase.level.things:
|
for i in self.gameBase.level.things:
|
||||||
j = self.gameBase.level.things[i]
|
j = self.gameBase.level.things[i]
|
||||||
|
@ -263,7 +270,7 @@ If -l is given, a map legend will be printed under the map."""
|
||||||
return
|
return
|
||||||
|
|
||||||
def inv(self, args):
|
def inv(self, args):
|
||||||
print('\n'.join([self.gameBase.playerInv[i].name for i in self.gameBase.playerInv]))
|
print('\n'.join([i for i in self.gameBase.player.thingNames]))
|
||||||
|
|
||||||
def newGame(self, args):
|
def newGame(self, args):
|
||||||
if self.__inGame:
|
if self.__inGame:
|
||||||
|
@ -351,22 +358,23 @@ If -l is given, a map legend will be printed under the map."""
|
||||||
|
|
||||||
# IO calls
|
# IO calls
|
||||||
|
|
||||||
def container(self, inv, cont):
|
def container(self, player, cont):
|
||||||
"""container IO"""
|
"""container IO
|
||||||
|
Player is modified through side-effect."""
|
||||||
# Pretty print: get length of the longest inventory item's name
|
# Pretty print: get length of the longest inventory item's name
|
||||||
longestLen = 0
|
longestLen = 0
|
||||||
for i in inv:
|
for i in player.thingNames:
|
||||||
if len(inv[i].name) > longestLen:
|
if len(i) > longestLen:
|
||||||
longestLen = len(inv[i].name)
|
longestLen = len(i)
|
||||||
if longestLen > 0:
|
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:"))
|
print('{{0:<{0}}}{1}'.format(max(6, longestLen+2), "Container:").format("Inv:"))
|
||||||
i = 0
|
i = 0
|
||||||
invKeys = tuple(inv.keys())
|
while i < len(inv) and i < len(cont):
|
||||||
while i < len(invKeys) and i < len(cont):
|
print('{{0:<{0}}}{1}'.format(longestLen+2, cont[i].name).format(inv[i].name))
|
||||||
print('{{0:<{0}}}{1}'.format(longestLen+2, cont[i].name).format(inv[invKeys[i]].name))
|
|
||||||
i += 1
|
i += 1
|
||||||
while i < len(invKeys):
|
while i < len(inv):
|
||||||
print(inv[invKeys[i]].name)
|
print(inv[i].name)
|
||||||
i += 1
|
i += 1
|
||||||
while i < len(cont):
|
while i < len(cont):
|
||||||
print(' '*(longestLen+2) + cont[i].name)
|
print(' '*(longestLen+2) + cont[i].name)
|
||||||
|
@ -387,26 +395,27 @@ If -l is given, a map legend will be printed under the map."""
|
||||||
thing = ' '.join(instr[1:])
|
thing = ' '.join(instr[1:])
|
||||||
for i in range(len(cont)):
|
for i in range(len(cont)):
|
||||||
if thing == cont[i].name:
|
if thing == cont[i].name:
|
||||||
inv[cont[i].thingID] = cont[i]
|
player.addThing(cont[i])
|
||||||
del cont[i]
|
del cont[i]
|
||||||
timeSpent += 0.5
|
timeSpent += 0.5
|
||||||
print("{0} taken.".format(thing))
|
print("{0} taken.".format(thing))
|
||||||
break
|
break
|
||||||
|
else:
|
||||||
|
# If it got here, it didn't find it.
|
||||||
|
print("No {0} in container.".format(thing))
|
||||||
elif instr[0] == "store":
|
elif instr[0] == "store":
|
||||||
# store something in the container
|
# store something in the container
|
||||||
if instr[1] == "the":
|
if instr[1] == "the":
|
||||||
del instr[1]
|
del instr[1]
|
||||||
thingName = ' '.join(instr[1:])
|
thingName = ' '.join(instr[1:])
|
||||||
for i in inv:
|
if thingName in player.thingNames:
|
||||||
thing = inv[i].name
|
cont.append(player.removeThingByName(thingName))
|
||||||
if thing == thingName:
|
print("{0} stored.".format(thingName))
|
||||||
cont.append(inv[i])
|
timeSpent += 0.5
|
||||||
del inv[i]
|
else:
|
||||||
print("{0} stored.".format(thing))
|
print("No {0} in inventory.".format(thingName))
|
||||||
timeSpent += 0.5
|
|
||||||
break # so that all things with the same name don't get stored
|
|
||||||
instr = input("Take, store, or exit: ")
|
instr = input("Take, store, or exit: ")
|
||||||
return inv, cont, timeSpent
|
return cont, timeSpent
|
||||||
|
|
||||||
def info(self, items):
|
def info(self, items):
|
||||||
"""IO for collections of information"""
|
"""IO for collections of information"""
|
||||||
|
@ -532,4 +541,5 @@ If -l is given, a map legend will be printed under the map."""
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
sh = GameShell(GameBase())
|
sh = GameShell(GameBase())
|
||||||
|
sh.menuMode()
|
||||||
sh.run()
|
sh.run()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue