YAML maps can now be loaded, and they work well.

This commit is contained in:
Patrick Marsee 2019-03-09 19:50:31 -05:00
parent adfb6b83f4
commit eeab517213
5 changed files with 46 additions and 53 deletions

View file

@ -289,7 +289,7 @@ class Door(Thing):
locked, description, key, graphic)
class MapExit(Thing):
yaml_flag = u'!Exit'
yaml_flag = u'!MapExit'
defaultGraphic = ('clear', '#FF0000', 'x')
def __init__(self, name, x: int, y: int, exitid: int, destination: str, prefix: None, graphic = defaultGraphic):
@ -326,9 +326,9 @@ class MapExit(Thing):
constructor.construct_mapping(node, parts, True)
# set default values for optional arguments
prefix = None
bgc = Door.defaultGraphic[0]
fgc = Door.defaultGraphic[1]
shape = Door.defaultGraphic[2]
bgc = MapExit.defaultGraphic[0]
fgc = MapExit.defaultGraphic[1]
shape = MapExit.defaultGraphic[2]
# load graphic
if 'graphic' in parts:
if 'bgc' in parts['graphic']:
@ -474,12 +474,17 @@ class GameMap(object):
"""Read map data and return a Map object. If infile is not provided, then
it will read from stdin. Otherwise, it should be a valid file name.
Entering a map through stdin will be obsolete once testing is over."""
data = None
info = None
tryToRead = True
yaml = ruamel.yaml.YAML()
yaml.register_class(Item)
yaml.register_class(Useable)
yaml.register_class(Door)
yaml.register_class(MapExit)
if infile != None:
try:
with open(infile, 'r') as f:
data = f.read()
info = yaml.load(f)
except OSError as e:
print("The file could not be read.")
return None
@ -492,12 +497,13 @@ Entering a map through stdin will be obsolete once testing is over."""
tryToRead = False
# Now what we do with the data
info = ET.fromstring(data)
mat = None
layout = info.find('layout')
if 'layout' not in info:
raise MapError('No layout in {0}.'.format(infile))
layout = info['layout']
if layout != None:
#print(layout.text)
match = GameMap.matrixRegex.match(layout.text.lstrip())
match = GameMap.matrixRegex.match(layout.lstrip())
if match == None:
raise RuntimeError('Map read a file without a map matrix.')
mat = match.group()
@ -550,7 +556,7 @@ list of lists of tuples."""
matrixStr = ''
else:
matrixStr = matrixStr[i:]
else: # This shouldn't happen, so if it does, there was an error.
else: # This should happen when it finishes?
raise RuntimeError("Unexpected token in map matrix: '{0}'".format(matrixStr))
y = len(mat) - 1
@ -577,47 +583,34 @@ list of lists of tuples."""
@staticmethod
def loadThings(level, info, prevMap = None, preLoaded = False):
"""load the things from the xml part of the map file."""
if 'openingText' in info.attrib:
level.openingText = info.attrib['openingText']
if 'playerStart' in info.attrib:
ps = info.attrib['playerStart'].split(',')
level.playerStart = (int(ps[0]), int(ps[1]))
if info.text != None:
level.description = info.text
if 'openingText' in info:
level.openingText = info['openingText']
if 'playerStart' in info:
level.playerStart = info['playerStart']
if 'description' in info:
level.description = info['description']
# get map colors
floorColors = info.find('floorColors')
if floorColors != None:
level.floorColors = floorColors.text.lstrip().split()
if 'floorColors' in info:
level.floorColors = info['floorColors']
if 'wallColors' in info:
level.wallColors = info['wallColors']
if len(level.floorColors) == 0:
level.floorColors.append('#9F7F5F')
wallColors = info.find('wallColors')
if wallColors != None:
level.wallColors = wallColors.text.lstrip().split()
if len(level.wallColors) == 0:
level.wallColors.append('#7F3F0F')
# get things
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.
if preLoaded:
continue
for node1 in node:
if node1.tag == 'door':
level.addThing(GameMap.__loadDoor(node1), True)
elif node1.tag == 'useable':
level.addThing(GameMap.__loadUseable(node1), True)
elif node1.tag == 'item':
level.addThing(GameMap.__loadItem(node1), True)
elif node.tag == 'exit':
level.addThing(GameMap.__loadExit(level, node, prevMap))
elif node.tag == 'door':
level.addThing(GameMap.__loadDoor(node))
elif node.tag == 'useable':
level.addThing(GameMap.__loadUseable(node))
if 'loadOnce' in info and not preLoaded:
for thing in info['loadOnce']:
#print(type(thing))
level.addThing(thing, True)
if 'loadAlways' in info:
for thing in info['loadAlways']:
#print(type(thing))
level.addThing(thing)
if thing.thingType == 'x' and prevMap == thing.exitid:
level.playerStart = (thing.x, thing.y)
@staticmethod
def __loadExit(level, node, prevMap):