def import_from_xml(self, xml: Element, tables: Dict[int, Image.Image]): self.entries = [] validate_xml_tag(xml, XML_FONT) for child in xml: validate_xml_tag(child, XML_TABLE) validate_xml_attribs(child, [XML_TABLE__ID]) t = int(child.get(XML_TABLE__ID)) if t in FONT_VALID_TABLES and t in tables: for char in child: validate_xml_tag(char, XML_CHAR) validate_xml_attribs(char, [XML_CHAR__ID, XML_CHAR__WIDTH]) charid = int(char.get(XML_CHAR__ID)) width = int(char.get(XML_CHAR__WIDTH)) cat = int(char.get(XML_CHAR__CAT, default=FONT_DEFAULT_CAT)) padding = int( char.get(XML_CHAR__PADDING, default=FONT_DEFAULT_PADDING)) x = (charid % 16) * FONT_SIR0_SIZE y = (charid // 16) * FONT_SIR0_SIZE self.entries.append( FontSir0Entry.from_pil( tables[t].crop(box=[ x, y, x + FONT_SIR0_SIZE, y + FONT_SIR0_SIZE ]), charid, t, width, cat, padding)) pass
def from_xml(cls, ele: Element) -> 'XmlSerializable': validate_xml_tag(ele, XML_ITEM_LIST) categories = {} items = {} for child in ele: if child.tag == XML_CATEGORY: validate_xml_attribs( child, [XML_CATEGORY__NAME, XML_CATEGORY__WEIGHT]) name = child.get(XML_CATEGORY__NAME) if not hasattr(MappaItemCategory, name): raise XmlValidateError(f"Unknown item category {name}.") weight_str = child.get(XML_CATEGORY__WEIGHT) weight = int( weight_str) if weight_str != 'GUARANTEED' else GUARANTEED categories[getattr(MappaItemCategory, name)] = weight elif child.tag == XML_ITEM: validate_xml_attribs(child, [XML_ITEM__ID, XML_ITEM__WEIGHT]) weight_str = child.get(XML_ITEM__WEIGHT) weight = int( weight_str) if weight_str != 'GUARANTEED' else GUARANTEED items[Pmd2DungeonItem(int(child.get(XML_ITEM__ID)), '???')] = weight else: raise XmlValidateError( f"Unexpected sub-node for {XML_ITEM_LIST}: {child.tag}") return cls(categories, items)
def from_xml(cls, ele: Element) -> 'MappaMonster': validate_xml_tag(ele, XML_MONSTER) validate_xml_attribs(ele, [ XML_MONSTER__LEVEL, XML_MONSTER__WEIGHT, XML_MONSTER__WEIGHT2, XML_MONSTER__MD_INDEX ]) return cls( u8_checked(int(ele.get(XML_MONSTER__LEVEL))), u16_checked(int(ele.get(XML_MONSTER__WEIGHT))), u16_checked(int(ele.get(XML_MONSTER__WEIGHT2))), u16_checked(int(ele.get(XML_MONSTER__MD_INDEX))), )
def from_xml(cls, ele: Element) -> 'XmlSerializable': validate_xml_tag(ele, XML_TRAP_LIST) weights = {} for child in ele: validate_xml_tag(child, XML_TRAP) validate_xml_attribs(child, [XML_TRAP__NAME, XML_TRAP__WEIGHT]) name = child.get(XML_TRAP__NAME) if not hasattr(MappaTrapType, name): raise XmlValidateError(f(_("Unknown trap {name}."))) weights[getattr(MappaTrapType, name)] = int(child.get(XML_TRAP__WEIGHT)) try: return cls(weights) except ValueError as ex: raise XmlValidateError(_("Trap lists need an entry for all of the 25 traps")) from ex
def import_from_xml(self, xml: Element, tables: Dict[int, Image.Image]): self.entries = [] self.unknown = 0 pal_table = 256 validate_xml_tag(xml, XML_FONT) for child in xml: if child.tag == XML_TABLE: validate_xml_attribs(child, [XML_TABLE__ID]) t = int(child.get(XML_TABLE__ID)) if t in FONT_VALID_TABLES and t in tables: if pal_table > t: pal_table = t self.set_palette_raw( memoryview(tables[t].palette.palette)) for char in child: validate_xml_tag(char, XML_CHAR) validate_xml_attribs(char, [XML_CHAR__ID, XML_CHAR__WIDTH]) charid = int(char.get(XML_CHAR__ID)) width = int(char.get(XML_CHAR__WIDTH)) x = (charid % 16) * BANNER_FONT_SIZE y = (charid // 16) * BANNER_FONT_SIZE self.entries.append( BannerFontEntry.from_pil( tables[t].crop(box=[ x, y, x + BANNER_FONT_SIZE, y + BANNER_FONT_SIZE ]), charid, t, width)) elif child.tag == XML_HEADER: validate_xml_attribs(child, [XML_HEADER__UNKNOWN]) self.unknown = int(child.get(XML_HEADER__UNKNOWN)) else: raise XmlValidateError( f(_('Font parsing: Unexpected {child.tag}')))
def from_xml(cls, ele: Element) -> 'MappaFloorLayout': validate_xml_tag(ele, XML_FLOOR_LAYOUT) generator_settings = None chances = None terrain_settings = None misc = None for child in ele: if child.tag == XML_FLOOR_LAYOUT__GENSET: generator_settings = child elif child.tag == XML_FLOOR_LAYOUT__CHANCES: chances = child elif child.tag == XML_FLOOR_LAYOUT__TERRAINSET: terrain_settings = child elif child.tag == XML_FLOOR_LAYOUT__MISCSET: misc = child else: raise XmlValidateError( f( _("Unexpected sub-node for {XML_FLOOR_LAYOUT}: {child.tag}" ))) if generator_settings is None: raise XmlValidateError( f( _("{XML_FLOOR_LAYOUT__GENSET} missing for {XML_FLOOR_LAYOUT}." ))) if chances is None: raise XmlValidateError( f( _("{XML_FLOOR_LAYOUT__CHANCES} missing for {XML_FLOOR_LAYOUT}." ))) if terrain_settings is None: raise XmlValidateError( f( _("{XML_FLOOR_LAYOUT__TERRAINSET} missing for {XML_FLOOR_LAYOUT}." ))) if misc is None: raise XmlValidateError( f( _("{XML_FLOOR_LAYOUT__MISCSET} missing for {XML_FLOOR_LAYOUT}." ))) validate_xml_attribs(ele, [ XML_FLOOR_LAYOUT__STRUCTURE, XML_FLOOR_LAYOUT__TILESET, XML_FLOOR_LAYOUT__BGM, XML_FLOOR_LAYOUT__WEATHER, XML_FLOOR_LAYOUT__NUMBER, XML_FLOOR_LAYOUT__FIXED_FLOOR_ID, XML_FLOOR_LAYOUT__DARKNESS_LEVEL ]) validate_xml_attribs(generator_settings, [ XML_FLOOR_LAYOUT__GENSET__ROOM_DENSITY, XML_FLOOR_LAYOUT__GENSET__FLOOR_CONNECTIVITY, XML_FLOOR_LAYOUT__GENSET__INITIAL_ENEMY_DENSITY, XML_FLOOR_LAYOUT__GENSET__DEAD_ENDS, XML_FLOOR_LAYOUT__GENSET__ITEM_DENSITY, XML_FLOOR_LAYOUT__GENSET__TRAP_DENSITY, XML_FLOOR_LAYOUT__GENSET__EXTRA_HALLWAY_DENSITY, XML_FLOOR_LAYOUT__GENSET__BURIED_ITEM_DENSITY, XML_FLOOR_LAYOUT__GENSET__WATER_DENSITY, XML_FLOOR_LAYOUT__GENSET__MAX_COIN_AMOUNT ]) validate_xml_attribs(chances, [ XML_FLOOR_LAYOUT__CHANCES__SHOP, XML_FLOOR_LAYOUT__CHANCES__MONSTER_HOUSE, XML_FLOOR_LAYOUT__CHANCES__UNUSED, XML_FLOOR_LAYOUT__CHANCES__STICKY_ITEM, XML_FLOOR_LAYOUT__CHANCES__EMPTY_MONSTER_HOUSE, XML_FLOOR_LAYOUT__CHANCES__HIDDEN_STAIRS ]) validate_xml_attribs(terrain_settings, [ XML_FLOOR_LAYOUT__TERRAINSET__SECONDARY_USED, XML_FLOOR_LAYOUT__TERRAINSET__SECONDARY_TYPE, XML_FLOOR_LAYOUT__TERRAINSET__IMPERFECT_ROOMS, XML_FLOOR_LAYOUT__TERRAINSET__UNK1, XML_FLOOR_LAYOUT__TERRAINSET__UNK3, XML_FLOOR_LAYOUT__TERRAINSET__UNK4, XML_FLOOR_LAYOUT__TERRAINSET__UNK5, XML_FLOOR_LAYOUT__TERRAINSET__UNK6, XML_FLOOR_LAYOUT__TERRAINSET__UNK7 ]) validate_xml_attribs(misc, [ XML_FLOOR_LAYOUT__MISCSET__UNKE, XML_FLOOR_LAYOUT__MISCSET__KECLEON_SHOP_ITEM_POSITIONS, XML_FLOOR_LAYOUT__MISCSET__UNK_HIDDEN_STAIRS, XML_FLOOR_LAYOUT__MISCSET__ENEMY_IQ, XML_FLOOR_LAYOUT__MISCSET__IQ_BOOSTER_BOOST ]) if not hasattr(MappaFloorStructureType, ele.get(XML_FLOOR_LAYOUT__STRUCTURE)): raise XmlValidateError( f( _("Invalid structure type {ele.get(XML_FLOOR_LAYOUT__STRUCTURE)}" ))) structure = getattr(MappaFloorStructureType, ele.get(XML_FLOOR_LAYOUT__STRUCTURE)) if not hasattr(MappaFloorWeather, ele.get(XML_FLOOR_LAYOUT__WEATHER)): raise XmlValidateError( f( _("Invalid weather type {ele.get(XML_FLOOR_LAYOUT__WEATHER)}" ))) weather = getattr(MappaFloorWeather, ele.get(XML_FLOOR_LAYOUT__WEATHER)) if not hasattr(MappaFloorDarknessLevel, ele.get(XML_FLOOR_LAYOUT__DARKNESS_LEVEL)): raise XmlValidateError( f( _("Invalid darkness level type {ele.get(XML_FLOOR_LAYOUT__DARKNESS_LEVEL)}" ))) darkness_level = getattr(MappaFloorDarknessLevel, ele.get(XML_FLOOR_LAYOUT__DARKNESS_LEVEL)) return cls( structure=structure, room_density=i8_checked( int( generator_settings.get( XML_FLOOR_LAYOUT__GENSET__ROOM_DENSITY))), tileset_id=u8_checked(int(ele.get(XML_FLOOR_LAYOUT__TILESET))), music_id=u8_checked(int(ele.get(XML_FLOOR_LAYOUT__BGM))), weather=weather, floor_connectivity=u8_checked( int( generator_settings.get( XML_FLOOR_LAYOUT__GENSET__FLOOR_CONNECTIVITY))), initial_enemy_density=i8_checked( int( generator_settings.get( XML_FLOOR_LAYOUT__GENSET__INITIAL_ENEMY_DENSITY))), kecleon_shop_chance=u8_checked( int(chances.get(XML_FLOOR_LAYOUT__CHANCES__SHOP))), monster_house_chance=u8_checked( int(chances.get(XML_FLOOR_LAYOUT__CHANCES__MONSTER_HOUSE))), unusued_chance=u8_checked( int(chances.get(XML_FLOOR_LAYOUT__CHANCES__UNUSED))), sticky_item_chance=u8_checked( int(chances.get(XML_FLOOR_LAYOUT__CHANCES__STICKY_ITEM))), dead_ends=bool( int(generator_settings.get( XML_FLOOR_LAYOUT__GENSET__DEAD_ENDS))), secondary_terrain=u8_checked( int( terrain_settings.get( XML_FLOOR_LAYOUT__TERRAINSET__SECONDARY_TYPE))), terrain_settings=MappaFloorTerrainSettings( has_secondary_terrain=bool( int( terrain_settings.get( XML_FLOOR_LAYOUT__TERRAINSET__SECONDARY_USED))), unk1=bool( int( terrain_settings.get( XML_FLOOR_LAYOUT__TERRAINSET__UNK1))), generate_imperfect_rooms=bool( int( terrain_settings.get( XML_FLOOR_LAYOUT__TERRAINSET__IMPERFECT_ROOMS))), unk3=bool( int( terrain_settings.get( XML_FLOOR_LAYOUT__TERRAINSET__UNK3))), unk4=bool( int( terrain_settings.get( XML_FLOOR_LAYOUT__TERRAINSET__UNK4))), unk5=bool( int( terrain_settings.get( XML_FLOOR_LAYOUT__TERRAINSET__UNK5))), unk6=bool( int( terrain_settings.get( XML_FLOOR_LAYOUT__TERRAINSET__UNK6))), unk7=bool( int( terrain_settings.get( XML_FLOOR_LAYOUT__TERRAINSET__UNK7))), ), unk_e=bool(int(misc.get(XML_FLOOR_LAYOUT__MISCSET__UNKE))), item_density=u8_checked( int( generator_settings.get( XML_FLOOR_LAYOUT__GENSET__ITEM_DENSITY))), trap_density=u8_checked( int( generator_settings.get( XML_FLOOR_LAYOUT__GENSET__TRAP_DENSITY))), floor_number=u8_checked(int(ele.get(XML_FLOOR_LAYOUT__NUMBER))), fixed_floor_id=u8_checked( int(ele.get(XML_FLOOR_LAYOUT__FIXED_FLOOR_ID))), extra_hallway_density=u8_checked( int( generator_settings.get( XML_FLOOR_LAYOUT__GENSET__EXTRA_HALLWAY_DENSITY))), buried_item_density=u8_checked( int( generator_settings.get( XML_FLOOR_LAYOUT__GENSET__BURIED_ITEM_DENSITY))), water_density=u8_checked( int( generator_settings.get( XML_FLOOR_LAYOUT__GENSET__WATER_DENSITY))), darkness_level=darkness_level, max_coin_amount=int( generator_settings.get( XML_FLOOR_LAYOUT__GENSET__MAX_COIN_AMOUNT)), kecleon_shop_item_positions=u8_checked( int( misc.get( XML_FLOOR_LAYOUT__MISCSET__KECLEON_SHOP_ITEM_POSITIONS) )), empty_monster_house_chance=u8_checked( int(chances.get( XML_FLOOR_LAYOUT__CHANCES__EMPTY_MONSTER_HOUSE))), unk_hidden_stairs=u8_checked( int(misc.get(XML_FLOOR_LAYOUT__MISCSET__UNK_HIDDEN_STAIRS))), hidden_stairs_spawn_chance=u8_checked( int(chances.get(XML_FLOOR_LAYOUT__CHANCES__HIDDEN_STAIRS))), enemy_iq=u16_checked( int(misc.get(XML_FLOOR_LAYOUT__MISCSET__ENEMY_IQ))), iq_booster_boost=i16_checked( int(misc.get(XML_FLOOR_LAYOUT__MISCSET__IQ_BOOSTER_BOOST))), )