# HG changeset patch # User Neil Muller # Date 1318930888 -7200 # Node ID 9afaa1969d6ff7bd71143c623fcc5d8aba35eee9 # Parent a85993b00fd758b9c3bb58aac5562ced0b9e3b68 Level format 2 support * * * Allow for blank author * * * Fix thinko in write code diff -r a85993b00fd7 -r 9afaa1969d6f mamba/constants.py --- a/mamba/constants.py Mon Oct 17 18:02:49 2011 +0200 +++ b/mamba/constants.py Tue Oct 18 11:41:28 2011 +0200 @@ -1,5 +1,12 @@ from pygame.locals import K_ESCAPE, K_q, K_BACKSPACE, K_DELETE +# version tuple for maps +# NB: We only compare on the first two elements of the version when loading +# levels - this is so levels saved by later point releases are loadable by +# older versions. So changing the level format (new sprite, etc.) is not +# acceptable in a point release +VERSION = (0, 2, 0) + # Display constants SCREEN = (800, 600) EDIT_SCREEN = (1000, 600) diff -r a85993b00fd7 -r 9afaa1969d6f mamba/level.py --- a/mamba/level.py Mon Oct 17 18:02:49 2011 +0200 +++ b/mamba/level.py Tue Oct 18 11:41:28 2011 +0200 @@ -6,7 +6,7 @@ from pygame.surface import Surface from pygame.sprite import RenderUpdates -from mamba.constants import UP, DOWN, LEFT, RIGHT +from mamba.constants import UP, DOWN, LEFT, RIGHT, VERSION from mamba.data import load_file from mamba import sprites @@ -93,8 +93,70 @@ self.level_name = level_name self.level_namespace = level_namespace self.source = source + self.author = '' self.load_level_data() + def load_format_1(self, level_data): + """Load the original map format""" + self.name = level_data[0].strip() + tileset_name = level_data[1].strip() + self.tileset = Tileset(tileset_name) + self.background_track = level_data[2].strip() + tiles_ascii = [line.strip() for line in level_data[3:]] + try: + end = tiles_ascii.index("end") + except ValueError: + raise InvalidMapError('Missing "end" marker in level') + sprites_ascii = tiles_ascii[end + 1:] + tiles_ascii = tiles_ascii[:end] + self.tiles_ascii = tiles_ascii + self.sprites_ascii = sprites_ascii + + def load_format_2(self, level_data): + """Load the second mamba map format""" + try: + self.name = level_data[1].split('Name:', 1)[1].strip() + tileset_name = level_data[3].split('Tileset:', 1)[1].strip() + self.background_track = level_data[4].split('Music:', 1)[1].strip() + except IndexError: + raise InvalidMapError('Incorrectly formatted map header') + try: + # Missing author isn't fatal + self.author = level_data[2].split('Author:', 1)[1].strip() + except IndexError: + self.author = '' + self.tileset = Tileset(tileset_name) + tiles_ascii = [line.strip() for line in level_data[5:]] + try: + end = tiles_ascii.index("end") + except ValueError: + raise InvalidMapError('Missing "end" marker in level') + sprites_ascii = tiles_ascii[end + 1:] + tiles_ascii = tiles_ascii[:end] + self.tiles_ascii = tiles_ascii + self.sprites_ascii = sprites_ascii + + def check_format(self, level_data): + """Determine which format to load""" + if (level_data[0].startswith('Version: ') and + level_data[3].startswith('Tileset: ')): + # Looks like a version 2 level file + file_version = level_data[0].split('Version: ', 1)[1].strip() + try: + file_version = tuple([int(x) for x in file_version.split('.')]) + # We only compare on the first two elements, so point + # rleases work as expected + if file_version[:2] <= VERSION: + return 2 + else: + raise InvalidMapError("Unsupported map version") + except ValueError: + raise InvalidMapError("Unrecognised map version") + else: + # We assume anything we don't recognise is format 0 and rely on the + # error checking there to save us if we're wrong. + return 1 + def load_level_data(self): """ This file format is potentially yucky. @@ -103,20 +165,17 @@ level_data = StringIO(self.source) else: level_data = load_file('levels/%s.txt' % (self.level_name,)) - self.name = level_data.readline().strip() - tileset_name = level_data.readline().strip() - self.tileset = Tileset(tileset_name) - self.background_track = level_data.readline().strip() - tiles_ascii = [line.strip() for line in level_data.readlines()] - try: - end = tiles_ascii.index("end") - except ValueError: - raise InvalidMapError('Missing "end" marker in level') - sprites_ascii = tiles_ascii[end + 1:] - tiles_ascii = tiles_ascii[:end] - self.tiles_ascii = tiles_ascii - self.sprites_ascii = sprites_ascii - self.setup_level(tiles_ascii, sprites_ascii) + # XXX: Should we have some size restriction here? + level_data = level_data.readlines() + level_format = self.check_format(level_data) + if level_format == 2: + self.load_format_2(level_data) + elif level_format == 1: + self.load_format_1(level_data) + else: + # generic fallback + raise InvalidMapError("Unrecognised map version") + self.setup_level(self.tiles_ascii, self.sprites_ascii) self.make_background() def validate_level(self): @@ -136,9 +195,11 @@ level_dir = 'levels' file_path = '%s/%s.txt' % (level_dir, self.level_name) save_file = load_file(file_path, 'wb', is_user_dir=is_user_dir) - save_file.write('%s\n' % self.name) - save_file.write('%s\n' % self.tileset.name) - save_file.write('%s\n' % self.background_track) + save_file.write('Version: %d.%d\n' % VERSION[:2]) + save_file.write('Name: %s\n' % self.name) + save_file.write('Author: %s\n' % self.author) + save_file.write('Tileset: %s\n' % self.tileset.name) + save_file.write('Music: %s\n' % self.background_track) self.update_tiles_ascii() for tile_row in self.tiles_ascii: save_file.write('%s\n' % tile_row) diff -r a85993b00fd7 -r 9afaa1969d6f setup.py --- a/setup.py Mon Oct 17 18:02:49 2011 +0200 +++ b/setup.py Tue Oct 18 11:41:28 2011 +0200 @@ -11,7 +11,8 @@ except ImportError: pass -VERSION_STR = "0.1" +# This should probably be pulled from constants.py +VERSION_STR = "0.2" setup( # Metadata name="mutable-mamba",