Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from PIL import Image, ImageDraw
- def bitsToInt(file, num_bits):
- return sum([ord(file.read(1)) * 256 ** i for i in range(num_bits)])
- class Level:
- def __init__(self, file):
- self.bytes_in_level = bitsToInt(file, 2)
- self.level_num = bitsToInt(file, 2)
- self.time_limit = bitsToInt(file, 2)
- self.chips_left = bitsToInt(file, 2)
- file.seek(2, 1) # Skip map detail
- self.top_layer = self.parseLayer(file)
- self.bottom_layer = self.parseLayer(file)
- self.title, self.password, self.hint, self.traps, self.cloners, self.monsters = self.parseExtra(file)
- def parseLayer(_, file):
- layer = [0] * 1024
- layer_byte_count = bitsToInt(file, 2)
- tile_counter = 0
- while layer_byte_count != 0:
- next_tile = bitsToInt(file, 1)
- if next_tile == 255:
- repeat = bitsToInt(file, 1)
- repeat_tile = bitsToInt(file, 1)
- layer_byte_count -= 3
- else:
- repeat = 1
- repeat_tile = next_tile
- layer_byte_count -= 1
- while repeat > 0:
- repeat -= 1
- layer[tile_counter] = repeat_tile
- tile_counter += 1
- if tile_counter != 1024:
- print("Map error")
- return layer
- def parseExtra(self, file):
- extra_bytes = bitsToInt(file, 2)
- title, password, hint = None, None, None
- traps, cloners, monsters = [], [], []
- while extra_bytes != 0:
- c = bitsToInt(file, 1)
- if c == 3:
- title_length = bitsToInt(file, 1)
- title = file.read(title_length)[:-1]
- extra_bytes -= (2 + title_length)
- if c == 4:
- trap_length = bitsToInt(file, 1)
- extra_bytes -= (2 + trap_length)
- while trap_length != 0:
- x1, y1 = bitsToInt(file, 2), bitsToInt(file, 2)
- x2, y2 = bitsToInt(file, 2), bitsToInt(file, 2)
- traps += [(x1, y1, x2, y2)]
- file.seek(2, 1)
- trap_length -= 10
- if c == 5:
- clone_length = bitsToInt(file, 1)
- extra_bytes -= (2 + clone_length)
- while clone_length != 0:
- x1, y1 = bitsToInt(file, 2), bitsToInt(file, 2)
- x2, y2 = bitsToInt(file, 2), bitsToInt(file, 2)
- cloners += [(x1, y1, x2, y2)]
- clone_length -= 8
- if c == 6:
- password_length = bitsToInt(file, 1)
- password = "".join(
- [chr(bitsToInt(file, 1)^0x99) for i in range(password_length - 1)]
- )
- file.seek(1, 1)
- extra_bytes -= (2 + password_length)
- if c == 7:
- hint_length = bitsToInt(file, 1)
- hint = file.read(hint_length)[:-1]
- extra_bytes -= (2 + hint_length)
- if c == 10:
- monster_length = bitsToInt(file, 1)
- extra_bytes -= (2 + monster_length)
- while monster_length != 0:
- x, y = bitsToInt(file, 1), bitsToInt(file, 1)
- monsters += [(x, y)]
- monster_length -= 2
- if c == 1 or c == 2:
- file.seek(3, 1) # Ignore useless fixed length fields
- extra_bytes -= 4
- if c == 8 or c == 9:
- unused_length = bitsToInt(file, 1)
- file.seek(unused_length, 1) # Ignore useless variable length fields
- extra_bytes -= (2 + unused_length)
- return title, password, hint, traps, cloners, monsters
- class Drawer:
- T_D = 32
- def __init__(self, tileset):
- T_D = self.T_D
- tileset = Image.open(tileset)
- self.tile_list = [tileset.crop(((x // 16) * T_D, (x % 16) * T_D,
- (x // 16 + 1) * T_D, (x % 16 + 1) * T_D)) for x in range(112)]
- def drawBase(self, level, draw_hidden):
- T_D = self.T_D
- FLOOR_TILE = self.tile_list[0]
- top_level = level.top_layer
- bottom_level = level.bottom_layer
- export_map = Image.new("RGBA", (T_D * 32, T_D * 32), "black")
- for x in range(1024):
- top_index = level.top_layer[x]
- bottom_index = level.bottom_layer[x]
- top_tile = self.tile_list[top_index]
- bottom_tile = self.tile_list[bottom_index]
- x1, y1 = (x % 32) * T_D, (x // 32) * T_D
- x2, y2 = (x % 32 + 1) * T_D, (x // 32 + 1) * T_D
- if top_index // 16 >= 3:
- if bottom_index // 16 >= 3:
- export_map.paste(FLOOR_TILE, (x1, y1, x2, y2), FLOOR_TILE)
- export_map.paste(bottom_tile, (x1, y1, x2, y2), bottom_tile)
- export_map.paste(top_tile, (x1, y1, x2, y2), top_tile)
- else:
- export_map.paste(top_tile, (x1, y1, x2, y2), top_tile)
- if bottom_index != 0 and draw_hidden:
- c_off = T_D / 4
- if bottom_index // 16 >= 3:
- crop_region = FLOOR_TILE.crop((c_off, c_off, T_D - c_off, T_D - c_off))
- export_map.paste(crop_region, (x1 + c_off, y1 + c_off, x2 - c_off, y2 - c_off), crop_region)
- crop_region = bottom_tile.crop((c_off, c_off, T_D - c_off, T_D - c_off))
- export_map.paste(crop_region, (x1 + c_off, y1 + c_off, x2 - c_off, y2 - c_off), crop_region)
- return export_map
- def drawConnections(self, level, connections, canvas):
- line_drawer = ImageDraw.Draw(canvas)
- T_D = self.T_D
- for connection in connections:
- x1, y1, x2, y2 = tuple(x * T_D + T_D / 2 for x in connection)
- line_drawer.line(
- [(x1, y1), (x2, y2)],
- fill=(255, 0, 0, 255),
- width=1,
- joint="curve"
- )
- return
- def readFile(fileName):
- f = open(fileName, "rb")
- c = f.read(4)
- if bytearray(c) != b'\xAC\xAA\x02\x00':
- print("File exists, but is not a valid CC data file.")
- return
- num_levels = bitsToInt(f, 2)
- levels = []
- level_counter = 1
- while level_counter <= num_levels:
- levels.append(Level(f))
- level_counter += 1
- print(fileName + " processed successfully.")
- f.close()
- return levels
- levels = readFile("CHIPS.dat")
- drawer = Drawer("cc_tiles.png")
- for i in range(len(levels)):
- export_map = drawer.drawBase(levels[i], True)
- drawer.drawConnections(levels[i], levels[i].traps, export_map)
- drawer.drawConnections(levels[i], levels[i].cloners, export_map)
- export_map.save("./levels/" + str(i + 1) + ".png")
- print("Saved level {0}".format(i + 1))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement