junglejourney
changeset 230:f7b16fb00dda
Added tools created in an experimental map making repository.
| author | David Boddie <david@boddie.org.uk> |
|---|---|
| date | Sun Feb 05 00:28:07 2012 +0100 |
| parents | 114cc13a0af8 |
| children | e24e7d33b5e7 |
| files | tools/maps/make_maps.py tools/maps/series.py tools/maps/tileimages.py |
| diffstat | 3 files changed, 560 insertions(+), 0 deletions(-) [+] |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/tools/maps/make_maps.py Sun Feb 05 00:28:07 2012 +0100 1.3 @@ -0,0 +1,441 @@ 1.4 +#!/usr/bin/env python 1.5 + 1.6 +import os, sys 1.7 +import Image 1.8 +import series 1.9 +from tileimages import blank, tile_size, leaf1, leaf2, visited, flowers, \ 1.10 + flowers2, leaf4, leaf6, flowers3, leaf5, leaf3, \ 1.11 + exit, final_exit1, final_exit2, item_size, player, \ 1.12 + treasure_images 1.13 + 1.14 +image_sets = { 1.15 + 100: [blank, flowers, leaf1, leaf2, exit], 1.16 + 239: [blank, flowers2, leaf6, leaf4, exit], 1.17 + 183: [blank, flowers2, leaf6, leaf4, exit], 1.18 + 144: [blank, flowers3, leaf5, leaf3, exit, final_exit1, final_exit2] 1.19 + } 1.20 + 1.21 +default_image_set = [blank, flowers, leaf1, leaf2] 1.22 + 1.23 +tile_values_map = [0, 1, 0, 0, 0, 0, 2, 3, 4, 5, 6] 1.24 + 1.25 +class Mapper: 1.26 + 1.27 + start_rooms = {100: (5, 5), 36: (0, 0), 44: (9, 7), 4: (7, 0), 5: (5, 10), 1.28 + 8: (0, 8), 10: (0, 10), 17: (7, 10), 26: (0, 9), 1.29 + 33: (10, 0), 127: (0, 0), 144: (10, 8), 183: (5, 1), 1.30 + 239: (3, 8)} 1.31 + exit_rooms = {100: (7, 0), 36: (7, 0), 4: (5, 10), 5: (9, 6), 1.32 + 8: (3, 0), 10: (10, 2), 17: (9, 0), 26: (10, 4), 1.33 + 33: (2, 10), 144: (0, 10), 183: (3, 9), 239: (9, 0)} 1.34 + key_rooms = {100: (1, 0), 17: (0, 0), 26: (9, 0), 33: (10, 6), 144: (1, 4), 1.35 + 183: (10, 6), 239: (5, 2)} 1.36 + extra_life_rooms = {17: (2, 0), 26: (9, 4)} 1.37 + 1.38 + levels = {100: 0, 183: 1, 239: 2, 144: 3} 1.39 + 1.40 + treasure_table = [6, 5, 7, 1, 1, 5, 2, 7, 6, 2, 1, 7, 1, 7, 8, 7, 1.41 + 0, 7, 6, 7, 7, 7, 5, 0, 6, 3, 7, 7, 5, 7, 5, 0] 1.42 + 1.43 + treasure_x = [3, 2, 4, 8, 2, 5, 4, 1, 3, 8, 6, 5, 7, 1, 7, 6] 1.44 + treasure_y = [1, 3, 7, 7, 2, 3, 6, 1, 4, 6, 8, 5, 5, 4, 8, 2] 1.45 + 1.46 + exit_room_offsets = [35, 66, 63, 56, 34, 44, 64, 33, 36, 55, 65, 53, 1.47 + 45, 46, 54, 43] 1.48 + 1.49 + def __init__(self, map_width, map_height, room_width, room_height, seed, 1.50 + image, images, wall_tile, floor_tiles): 1.51 + 1.52 + self.map_width = map_width 1.53 + self.map_height = map_height 1.54 + self.room_width = room_width 1.55 + self.room_height = room_height 1.56 + self.rooms = {} 1.57 + self.exits = {} 1.58 + self.visited = set() 1.59 + self.seed = seed 1.60 + self.image = image 1.61 + self.images = images 1.62 + self.wall_tile = wall_tile 1.63 + self.floor_tiles = floor_tiles 1.64 + 1.65 + self.add_objects() 1.66 + 1.67 + def add_objects(self): 1.68 + 1.69 + self.objects = [] 1.70 + 1.71 + first = (self.seed + 1) & 31 1.72 + second = (self.seed + 2) & 31 1.73 + gen = series.unlimited_values(first, second) 1.74 + 1.75 + # Find the level associated with the seed used for the map. 1.76 + level = self.levels.get(self.seed, 0) 1.77 + 1.78 + k = 0 1.79 + for i in range(self.map_height): 1.80 + 1.81 + for j in range(self.map_width): 1.82 + 1.83 + if self.key_rooms.get(self.seed, ()) == (j, i): 1.84 + 1.85 + self.objects.append(5) 1.86 + 1.87 + else: 1.88 + 1.89 + item = gen.next() & 15 1.90 + if item == 0: 1.91 + self.objects.append(0) 1.92 + else: 1.93 + treasure = self.treasure_table[(item + k) & 31] 1.94 + if 0 <= treasure <= 3: 1.95 + if treasure <= level + 1: 1.96 + self.objects.append(treasure + 1) 1.97 + else: 1.98 + self.objects.append(0) 1.99 + else: 1.100 + self.objects.append(treasure + 1) 1.101 + 1.102 + k += 1 1.103 + 1.104 + def make_room(self, i, j): 1.105 + 1.106 + first = j 1.107 + second = self.seed - i 1.108 + 1.109 + gen = series.unlimited_values(first, second) 1.110 + for k in range(10): 1.111 + gen.next() 1.112 + 1.113 + special_rooms = {self.start_rooms.get(self.seed, ()): 7, 1.114 + self.exit_rooms.get(self.seed, ()): 7, 1.115 + self.key_rooms.get(self.seed, ()): 1} 1.116 + 1.117 + if (j, i) in special_rooms: 1.118 + 1.119 + x = y = 1 1.120 + while True: 1.121 + if (x, y) in [(1, 1), (1, 8), (8, 1), (8, 8)]: 1.122 + yield special_rooms[(j, i)] 1.123 + 1.124 + elif (j, i) == self.exit_rooms.get(self.seed, ()): 1.125 + position = self.exit_room_offsets[(i ^ j) & 15] 1.126 + if x == position % 10 and y == position / 10: 1.127 + yield 8 1.128 + else: 1.129 + yield 0 1.130 + 1.131 + else: 1.132 + yield 0 1.133 + 1.134 + x += 1 1.135 + if x == 9: 1.136 + x = 1 1.137 + y += 1 1.138 + 1.139 + else: 1.140 + while True: 1.141 + yield (gen.next() % 9) & 7 1.142 + 1.143 + def top_exit(self, i, j): 1.144 + 1.145 + if i == 0: 1.146 + return True 1.147 + elif i & 7 == j & 7: 1.148 + return False 1.149 + 1.150 + return ((i ^ j) + i) == j 1.151 + 1.152 + def right_exit(self, i, j): 1.153 + 1.154 + if j == self.map_width - 1: 1.155 + return True 1.156 + 1.157 + return self.left_exit(i, j + 1) 1.158 + 1.159 + def bottom_exit(self, i, j): 1.160 + 1.161 + if i == self.map_height - 1: 1.162 + return True 1.163 + 1.164 + return self.top_exit(i + 1, j) 1.165 + 1.166 + def left_exit(self, i, j): 1.167 + 1.168 + if j == 0: 1.169 + return True 1.170 + elif i & 3 == j & 3: 1.171 + return False 1.172 + 1.173 + return ((i | j) ^ j) == i 1.174 + 1.175 + def make_room_image(self, i, j): 1.176 + 1.177 + im = Image.new("P", (self.room_width * tile_size[0], 1.178 + self.room_height * tile_size[1]), 0) 1.179 + 1.180 + rows, exits = self.read_room((j, i)) 1.181 + 1.182 + for y in range(0, self.room_height): 1.183 + for x in range(0, self.room_width): 1.184 + 1.185 + value = rows[y][x] 1.186 + im.paste(self.images[value], (x * tile_size[0], y * tile_size[1])) 1.187 + 1.188 + item, x, y = self.item_for_room(rows, i, j) 1.189 + if item is not None: 1.190 + 1.191 + im.paste(treasure_images[item], 1.192 + (x * tile_size[0], 1.193 + y * tile_size[1] + (tile_size[1] - item_size[1])/2)) 1.194 + 1.195 + return im 1.196 + 1.197 + def item_for_room(self, rows, i, j): 1.198 + 1.199 + item = self.objects[i * self.map_height + j] 1.200 + if item != 0: 1.201 + 1.202 + item -= 1 1.203 + k = ((i ^ j) + item) & 15 1.204 + a = 15 1.205 + while a >= 0: 1.206 + 1.207 + x, y = self.treasure_x[k], self.treasure_y[k] 1.208 + 1.209 + if rows[y][x] & 0x7f == 0: 1.210 + 1.211 + return item, x, y 1.212 + break 1.213 + 1.214 + if k > 0: 1.215 + k -= 1 1.216 + else: 1.217 + k = 15 1.218 + a -= 1 1.219 + 1.220 + return None, 0, 0 1.221 + 1.222 + def read_room(self, room): 1.223 + 1.224 + gen = self.make_room(room[1], room[0]) 1.225 + 1.226 + if self.rooms.has_key(room): 1.227 + rows = self.rooms[room] 1.228 + exits = self.exits[room] 1.229 + else: 1.230 + exits = [] 1.231 + exits.append(self.top_exit(room[1], room[0])) 1.232 + exits.append(self.right_exit(room[1], room[0])) 1.233 + exits.append(self.bottom_exit(room[1], room[0])) 1.234 + exits.append(self.left_exit(room[1], room[0])) 1.235 + 1.236 + rows = [] 1.237 + cx = self.room_width/2 - 2 1.238 + cy = self.room_height/2 - 2 1.239 + 1.240 + if exits[0]: 1.241 + rows.append([self.wall_tile]*self.room_width) 1.242 + else: 1.243 + rows.append([self.wall_tile]*cx + [0]*(self.room_width - 2*cx) + [self.wall_tile]*cx) 1.244 + 1.245 + if self.levels.get(self.seed) == 3 and room == (2, 0): 1.246 + 1.247 + rows[-1][4] = 5 1.248 + rows[-1][5] = 6 1.249 + 1.250 + for ry in range(1, self.room_height - 1): 1.251 + row = [] 1.252 + if exits[3] or ry < cy or ry > self.room_height - cy - 1: 1.253 + row.append(self.wall_tile) 1.254 + else: 1.255 + row.append(0) 1.256 + 1.257 + for rx in range(1, self.room_width - 1): 1.258 + row.append(tile_values_map[gen.next()]) 1.259 + 1.260 + if exits[1] or ry < cy or ry > self.room_height - cy - 1: 1.261 + row.append(self.wall_tile) 1.262 + else: 1.263 + row.append(0) 1.264 + rows.append(row) 1.265 + 1.266 + if exits[2]: 1.267 + rows.append([self.wall_tile]*self.room_width) 1.268 + else: 1.269 + rows.append([self.wall_tile]*cx + [0]*(self.room_width - 2*cx) + [self.wall_tile]*cx) 1.270 + 1.271 + self.rooms[room] = rows 1.272 + self.exits[room] = exits 1.273 + 1.274 + return rows, exits 1.275 + 1.276 + def find_map_extent(self, room, x = None, y = None): 1.277 + 1.278 + rows, exits = self.read_room(room) 1.279 + 1.280 + if x is None: 1.281 + x = self.room_width/2 - 1 1.282 + y = self.room_height/2 - 1 1.283 + 1.284 + places = [(x, y)] 1.285 + 1.286 + # Use a recursive algorithm to explore the room, but don't recursively 1.287 + # call this function until we leave the room. 1.288 + 1.289 + while places: 1.290 + 1.291 + x, y = places.pop() 1.292 + 1.293 + if rows[y][x] not in self.floor_tiles: 1.294 + # The square has already been visited, so backtrack. 1.295 + continue 1.296 + else: 1.297 + # Mark this room as visited. 1.298 + self.visited.add(room) 1.299 + #self.image.paste(visited, 1.300 + # ((room[0] * self.room_width + x) * tile_size[0] + room[0] + 3 * tile_size[0]/8, 1.301 + # (room[1] * self.room_height + y) * tile_size[1] + room[1] + 3 * tile_size[1]/8)) 1.302 + 1.303 + # Mark this square as visited. 1.304 + rows[y][x] = rows[y][x] | 0x80 1.305 + 1.306 + # Try to move to adjacent squares. 1.307 + if x > 0: 1.308 + if rows[y][x-1] in self.floor_tiles: 1.309 + places.append((x - 1, y)) 1.310 + elif room[0] > 0: 1.311 + self.find_map_extent((room[0] - 1, room[1]), 1.312 + self.room_width - 1, y) 1.313 + 1.314 + if x < self.room_width - 1: 1.315 + if rows[y][x+1] in self.floor_tiles: 1.316 + places.append((x + 1, y)) 1.317 + elif room[0] < self.map_width - 1: 1.318 + self.find_map_extent((room[0] + 1, room[1]), 0, y) 1.319 + 1.320 + if y > 0: 1.321 + if rows[y-1][x] in self.floor_tiles: 1.322 + places.append((x, y - 1)) 1.323 + elif room[1] > 0: 1.324 + self.find_map_extent((room[0], room[1] - 1), 1.325 + x, self.room_height - 1) 1.326 + 1.327 + if y < self.room_height - 1: 1.328 + if rows[y+1][x] in self.floor_tiles: 1.329 + places.append((x, y + 1)) 1.330 + elif room[1] < self.map_height - 1: 1.331 + self.find_map_extent((room[0], room[1] + 1), x, 0) 1.332 + 1.333 +def fade(image, x0, y0, w, h): 1.334 + 1.335 + for i in range(h): 1.336 + 1.337 + y = y0 + i 1.338 + x = x0 + y % 2 1.339 + while x < x0 + w: 1.340 + image.putpixel((x, y), 0) 1.341 + x += 2 1.342 + 1.343 +def select_images(seed): 1.344 + 1.345 + images = image_sets.get(seed, default_image_set) 1.346 + wall_tile = 2 1.347 + floor_tiles = [] 1.348 + 1.349 + for i in range(len(images)): 1.350 + if images[i] in (blank,): 1.351 + floor_tiles.append(i) 1.352 + 1.353 + return images, wall_tile, floor_tiles 1.354 + 1.355 +def make_map(name, width, height, room_width, room_height, seed): 1.356 + 1.357 + images, wall_tile, floor_tiles = select_images(seed) 1.358 + 1.359 + im = Image.new("P", (width * room_width * tile_size[0] + (width - 1), 1.360 + height * room_height * tile_size[1] + (height - 1)), 7) 1.361 + #im.putpalette((0,0,0, 255,0,0, 0,255,0, 255,255,0, 0,0,255, 255,0,255, 0,255,255, 255,255,255)) 1.362 + black = (0,0,0) 1.363 + red = (255,0,0) 1.364 + green = (0,255,0) 1.365 + yellow = (255,255,0) 1.366 + blue = (0,0,255) 1.367 + magenta = (255,0,255) 1.368 + cyan = (0,255,255) 1.369 + white = (255,255,255) 1.370 + im.putpalette(black + red + green + yellow + blue + magenta + cyan + white) 1.371 + room_palettes = [1, 6, 5, 7] 1.372 + 1.373 + mapper = Mapper(width, height, room_width, room_height, seed, im, images, 1.374 + wall_tile, floor_tiles) 1.375 + 1.376 + for i in range(height): 1.377 + for j in range(width): 1.378 + 1.379 + room_image = mapper.make_room_image(i, j) 1.380 + 1.381 + # Change the palette for this room. 1.382 + room_string = room_image.tostring() 1.383 + 1.384 + # Replace logical colour 1 with 1, 3, 5 or 7. 1.385 + new_colour = room_palettes[(i ^ j) & 3] 1.386 + if new_colour != 1: 1.387 + room_string = room_string.replace("\x01", chr(new_colour)) 1.388 + 1.389 + room_image = Image.fromstring("P", (room_width * tile_size[0], 1.390 + room_height * tile_size[1]), 1.391 + room_string) 1.392 + 1.393 + im.paste(room_image, (j * room_width * tile_size[0] + j, 1.394 + i * room_height * tile_size[1] + i)) 1.395 + 1.396 + start_room = mapper.start_rooms.get(seed) 1.397 + 1.398 + if start_room: 1.399 + 1.400 + mapper.find_map_extent(start_room) 1.401 + 1.402 + mapper.image.paste(player, 1.403 + (int((start_room[0] + 0.5) * mapper.room_width * tile_size[0]) + start_room[0] - tile_size[0]/4, 1.404 + int((start_room[1] + 0.5) * mapper.room_height * tile_size[1]) + start_room[1] - tile_size[1]/2)) 1.405 + 1.406 + for i in range(height): 1.407 + for j in range(width): 1.408 + 1.409 + if (j,i) not in mapper.visited: 1.410 + 1.411 + fade(im, j * room_width * tile_size[0] + j, 1.412 + i * room_height * tile_size[1] + i, 1.413 + room_width * tile_size[0], 1.414 + room_height * tile_size[1]) 1.415 + 1.416 + im.save(name) 1.417 + 1.418 + 1.419 +if __name__ == "__main__": 1.420 + 1.421 + if len(sys.argv) != 5: 1.422 + 1.423 + sys.stderr.write("Usage: %s <width> <height> <seed> <file name>\n\n" % sys.argv[0]) 1.424 + sys.stderr.write("For the release version of Jungle Journey, use a value of 11\n" 1.425 + "for both width and height, and one of 100, 239, 183 or 144\n" 1.426 + "for the seed value.\n") 1.427 + sys.exit(1) 1.428 + 1.429 + width = int(sys.argv[1]) 1.430 + height = int(sys.argv[2]) 1.431 + seed = int(sys.argv[3]) 1.432 + name = sys.argv[4] 1.433 + room_width = 10 1.434 + room_height = 10 1.435 + 1.436 + start_room = (width/2, height/2) 1.437 + stem, suffix = os.path.splitext(name) 1.438 + 1.439 + make_map("%s-%02x%s" % (stem, seed, suffix), 1.440 + width, height, room_width, room_height, seed) 1.441 + 1.442 + print "Created %s-%02x%s" % (stem, seed, suffix) 1.443 + 1.444 + sys.exit()
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/tools/maps/series.py Sun Feb 05 00:28:07 2012 +0100 2.3 @@ -0,0 +1,31 @@ 2.4 +def values(first, second, number): 2.5 + 2.6 + # Add the two values as in the Fibonacci sequence, but take the modulus of 2.7 + # 256 of the result to avoid overflowing into values that require two bytes 2.8 + # or more. 2.9 + 2.10 + while number > 0: 2.11 + 2.12 + new_value = (first + second) & 0xff 2.13 + 2.14 + yield new_value 2.15 + 2.16 + first = second 2.17 + second = new_value 2.18 + 2.19 + number -= 1 2.20 + 2.21 +def unlimited_values(first, second): 2.22 + 2.23 + # Add the two values as in the Fibonacci sequence, but take the modulus of 2.24 + # 256 of the result to avoid overflowing into values that require two bytes 2.25 + # or more. 2.26 + 2.27 + while True: 2.28 + 2.29 + new_value = (first + second) & 0xff 2.30 + 2.31 + yield new_value 2.32 + 2.33 + first = second 2.34 + second = new_value
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/tools/maps/tileimages.py Sun Feb 05 00:28:07 2012 +0100 3.3 @@ -0,0 +1,88 @@ 3.4 +import Image 3.5 + 3.6 +tile_size = (16, 24) 3.7 + 3.8 +blank = Image.new("P", tile_size, 0) 3.9 +visited = Image.new("P", (tile_size[0]/4, tile_size[1]/4), 1) 3.10 + 3.11 +def read_xpm(path, symbols = None): 3.12 + 3.13 + lines = open(path).readlines() 3.14 + char_lines = filter(lambda line: line.startswith('"'), lines) 3.15 + strings = map(lambda line: line.strip()[1:-2], char_lines) 3.16 + strings[-1] = strings[-1][:-1] 3.17 + 3.18 + width, height, colours = map(int, strings[0].split()[:3]) 3.19 + strings = strings[-height:] 3.20 + 3.21 + if not symbols: 3.22 + symbols = [(".", "\x00"), ("+", "\x02"), ("@", "\x03")] 3.23 + 3.24 + # Fix the symbol replacement table if necessary. 3.25 + for i in range(len(symbols)): 3.26 + 3.27 + old, new = symbols[i] 3.28 + if 48 <= ord(new) <= 57: 3.29 + symbols[i] = (old, chr(ord(new) - 48)) 3.30 + 3.31 + data = [] 3.32 + 3.33 + for s in strings: 3.34 + 3.35 + for symbol, value in symbols: 3.36 + s = s.replace(symbol, value) 3.37 + 3.38 + data.append(s) 3.39 + 3.40 + return data 3.41 + 3.42 +flowers = Image.fromstring("P", tile_size, "".join(read_xpm("../../images/flowers.xpm", 3.43 + [(".", "\x00"), ("@", "\x01"), ("+", "\x02")]))) 3.44 +leaf1 = Image.fromstring("P", tile_size, "".join(read_xpm("../../images/leaf1.xpm"))) 3.45 +leaf2 = Image.fromstring("P", tile_size, "".join(read_xpm("../../images/leaf2.xpm"))) 3.46 + 3.47 +flowers2 = Image.fromstring("P", tile_size, "".join(read_xpm("../../images/flowers2.xpm", 3.48 + [(".", "\x00"), ("@", "\x01"), ("+", "\x02")]))) 3.49 +leaf6 = Image.fromstring("P", tile_size, "".join(read_xpm("../../images/leaf6.xpm"))) 3.50 +leaf4 = Image.fromstring("P", tile_size, "".join(read_xpm("../../images/leaf4.xpm"))) 3.51 + 3.52 +flowers3 = Image.fromstring("P", tile_size, "".join(read_xpm("../../images/flowers3.xpm", 3.53 + [(".", "\x00"), ("@", "\x01"), ("+", "\x02"), ("#", "\x03")]))) 3.54 +leaf5 = Image.fromstring("P", tile_size, "".join(read_xpm("../../images/leaf5.xpm"))) 3.55 +leaf3 = Image.fromstring("P", tile_size, "".join(read_xpm("../../images/leaf3.xpm"))) 3.56 + 3.57 +exit = Image.fromstring("P", tile_size, "".join(read_xpm("../../images/exit1.xpm", 3.58 + [("+", "\x00"), ("#", "\x01"), (".", "\x02"), ("@", "\x03")]))) 3.59 + 3.60 +final_exit1 = Image.fromstring("P", tile_size, "".join(read_xpm("../../images/finalexitl.xpm", 3.61 + [("+", "\x00"), ("#", "\x01"), (".", "\x02"), ("@", "\x03")]))) 3.62 +final_exit2 = Image.fromstring("P", tile_size, "".join(read_xpm("../../images/finalexitr.xpm", 3.63 + [(".", "\x00"), ("#", "\x01"), ("+", "\x02"), ("@", "\x03")]))) 3.64 + 3.65 +player_size = (8, 24) 3.66 + 3.67 +player = Image.fromstring("P", player_size, "".join(read_xpm("../../images/down1.xpm"))) 3.68 + 3.69 +item_size = (16, 16) 3.70 + 3.71 +treasure_images = [ 3.72 + Image.fromstring("P", item_size, "".join( 3.73 + read_xpm("../../images/weapon1.xpm", [(".", "\x00"), ("+", "\x01"), ("@", "\x03")]))), 3.74 + Image.fromstring("P", item_size, "".join( 3.75 + read_xpm("../../images/weapon2.xpm", [(".", "\x00"), ("@", "\x01"), ("+", "\x02")]))), 3.76 + Image.fromstring("P", item_size, "".join( 3.77 + read_xpm("../../images/weapon3.xpm", [(".", "\x00"), ("#", "\x01"), ("+", "\x02"), ("@", "\x03")]))), 3.78 + Image.fromstring("P", item_size, "".join( 3.79 + read_xpm("../../images/weapon4.xpm", [(".", "\x00"), ("@", "\x01"), ("+", "\x03")]))), 3.80 + 3.81 + Image.fromstring("P", item_size, "".join( 3.82 + read_xpm("../../images/key.xpm", [(".", "\x00"), ("+", "\x01"), ("@", "\x03")]))), 3.83 + Image.fromstring("P", item_size, "".join( 3.84 + read_xpm("../../images/chest.xpm", [(".", "\x00"), ("+", "\x01"), ("@", "\x03")]))), 3.85 + Image.fromstring("P", item_size, "".join( 3.86 + read_xpm("../../images/statue.xpm", [(".", "\x00"), ("+", "\x02"), ("@", "\x03")]))), 3.87 + Image.fromstring("P", item_size, "".join( 3.88 + read_xpm("../../images/jewel.xpm", [(".", "\x00"), ("@", "\x01"), ("+", "\x02"), ("#", "\x03")]))), 3.89 + Image.fromstring("P", item_size, "".join( 3.90 + read_xpm("../../images/health.xpm", [(".", "\x00"), ("#", "\x01"), ("+", "\x02"), ("@", "\x03")]))) 3.91 + ]
