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, xml: Element, value_to_update: List[Optional[KaoImage]]): if len(value_to_update) != len(xml): raise XmlValidateError( f"Incompatible XML. The number of portraits don't match with the expected value of {len(value_to_update)}" ) for i, xml_portrait in enumerate(xml): validate_xml_tag(xml_portrait, XML_PORTRAITS_PORTRAIT) if len(xml_portrait) > 0: image = None palette = None for xml_image_or_pal in xml_portrait: if xml_image_or_pal.tag == XML_PORTRAITS_PORTRAIT__IMAGE: image = xml_image_or_pal.text elif xml_image_or_pal.tag == XML_PORTRAITS_PORTRAIT__PALETTE: palette = xml_image_or_pal.text if image is None: raise XmlValidateError( f"Invalid XML. '{XML_PORTRAITS_PORTRAIT__IMAGE}' missing for a portrait." ) if palette is None: raise XmlValidateError( f"Invalid XML. '{XML_PORTRAITS_PORTRAIT__PALETTE}' missing for a portrait." ) try: value_to_update[i] = KaoImage( b64decode(palette.encode('ascii')) + b64decode(image.encode('ascii')), 0) except Exception as err: raise XmlValidateError( f"Invalid XML. The portrait data of one of the portraits is invalid: {err}" ) from err else: value_to_update[i] = None
def from_xml(cls, xml: Element, value_to_update: MoveLearnset): for xml_type in xml: if xml_type.tag == XML_MOVESET_LEVEL_UP: new_level_up = [] for xml_learn in xml_type: validate_xml_tag(xml_learn, XML_MOVESET_LEVEL_UP__LEARN) level = None move_id = None for xml_level_or_move in xml_learn: if xml_level_or_move.tag == XML_MOVESET_LEVEL_UP__LEVEL: level = int(xml_level_or_move.text) elif xml_level_or_move.tag == XML_MOVESET__MOVE_ID: move_id = int(xml_level_or_move.text) if level is None: raise XmlValidateError( f"Invalid XML. '{XML_MOVESET_LEVEL_UP__LEVEL}' missing for a level up moveset entry." ) if move_id is None: raise XmlValidateError( f"Invalid XML. '{XML_MOVESET__MOVE_ID}' missing for a level up moveset entry." ) new_level_up.append(LevelUpMove(move_id, level)) value_to_update.level_up_moves = new_level_up elif xml_type.tag == XML_MOVESET_EGG: new_eggs = [] for xml_move_id in xml_type: validate_xml_tag(xml_move_id, XML_MOVESET__MOVE_ID) new_eggs.append(int(xml_move_id.text)) value_to_update.egg_moves = new_eggs elif xml_type.tag == XML_MOVESET_HM_TM: new_hm_tm = [] for xml_move_id in xml_type: validate_xml_tag(xml_move_id, XML_MOVESET__MOVE_ID) new_hm_tm.append(int(xml_move_id.text)) value_to_update.tm_hm_moves = new_hm_tm
def from_xml(cls, ele: Element) -> 'MappaFloor': data = { 'layout': None, 'monsters': None, 'traps': None, 'floor_items': None, 'shop_items': None, 'monster_house_items': None, 'buried_items': None, 'unk_items1': None, 'unk_items2': None } for child in ele: if child.tag == XML_FLOOR_LAYOUT and data['layout'] is None: data['layout'] = MappaFloorLayout.from_xml(child) elif child.tag == XML_MONSTER_LIST and data['monsters'] is None: monsters = [] for monster in child: monsters.append(MappaMonster.from_xml(monster)) data['monsters'] = monsters elif child.tag == XML_TRAP_LIST and data['traps'] is None: data['traps'] = MappaTrapList.from_xml(child) elif child.tag == XML_ITEM_LIST and child.get( XML_ITEM_LIST__TYPE ) == XML_ITEM_LIST__TYPE__FLOOR and data['floor_items'] is None: data['floor_items'] = MappaItemList.from_xml(child) elif child.tag == XML_ITEM_LIST and child.get( XML_ITEM_LIST__TYPE ) == XML_ITEM_LIST__TYPE__SHOP and data['shop_items'] is None: data['shop_items'] = MappaItemList.from_xml(child) elif child.tag == XML_ITEM_LIST and child.get( XML_ITEM_LIST__TYPE ) == XML_ITEM_LIST__TYPE__MONSTER_HOUSE and data[ 'monster_house_items'] is None: data['monster_house_items'] = MappaItemList.from_xml(child) elif child.tag == XML_ITEM_LIST and child.get( XML_ITEM_LIST__TYPE ) == XML_ITEM_LIST__TYPE__BURIED and data['buried_items'] is None: data['buried_items'] = MappaItemList.from_xml(child) elif child.tag == XML_ITEM_LIST and child.get( XML_ITEM_LIST__TYPE ) == XML_ITEM_LIST__TYPE__UNK1 and data['unk_items1'] is None: data['unk_items1'] = MappaItemList.from_xml(child) elif child.tag == XML_ITEM_LIST and child.get( XML_ITEM_LIST__TYPE ) == XML_ITEM_LIST__TYPE__UNK2 and data['unk_items2'] is None: data['unk_items2'] = MappaItemList.from_xml(child) else: raise XmlValidateError( f'Floor parsing: Unexpected {child.tag}') for k, v in data.items(): if v is None: raise XmlValidateError(f'Missing {k} for Floor data.') return cls(**data)
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 from_xml(cls, xml: Element, value_to_update: Dict[str, Tuple[str, str]]): for xml_lang in xml: if xml_lang.tag in value_to_update.keys(): name = None category = None for xml_sub in xml_lang: if xml_sub.tag == XML_STRINGS__NAME: name = xml_sub.text if xml_sub.tag == XML_STRINGS__CATEGORY: category = xml_sub.text if name is None: raise XmlValidateError(f"Invalid XML. '{XML_STRINGS__NAME}' missing for language {xml_lang.tag}.") if category is None: raise XmlValidateError(f"Invalid XML. '{XML_STRINGS__CATEGORY}' missing for language {xml_lang.tag}.") value_to_update[xml_lang.tag] = (name, category)
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 mappa_floor_xml_import(xml: Element, floor: MappaFloor): """Imports all data available in the mappa floor XML into the given model.""" for child in xml: if child.tag == XML_FLOOR_LAYOUT: floor_number_before = floor.layout.floor_number floor.layout = MappaFloorLayout.from_xml(child) floor.layout.floor_number = floor_number_before elif child.tag == XML_MONSTER_LIST: monsters = [] for monster in child: monsters.append(MappaMonster.from_xml(monster)) floor.monsters = monsters elif child.tag == XML_TRAP_LIST: floor.traps = MappaTrapList.from_xml(child) elif child.tag == XML_ITEM_LIST and child.get( XML_ITEM_LIST__TYPE) == XML_ITEM_LIST__TYPE__FLOOR: floor.floor_items = MappaItemList.from_xml(child) elif child.tag == XML_ITEM_LIST and child.get( XML_ITEM_LIST__TYPE) == XML_ITEM_LIST__TYPE__SHOP: floor.shop_items = MappaItemList.from_xml(child) elif child.tag == XML_ITEM_LIST and child.get( XML_ITEM_LIST__TYPE) == XML_ITEM_LIST__TYPE__MONSTER_HOUSE: floor.monster_house_items = MappaItemList.from_xml(child) elif child.tag == XML_ITEM_LIST and child.get( XML_ITEM_LIST__TYPE) == XML_ITEM_LIST__TYPE__BURIED: floor.buried_items = MappaItemList.from_xml(child) elif child.tag == XML_ITEM_LIST and child.get( XML_ITEM_LIST__TYPE) == XML_ITEM_LIST__TYPE__UNK1: floor.unk_items1 = MappaItemList.from_xml(child) elif child.tag == XML_ITEM_LIST and child.get( XML_ITEM_LIST__TYPE) == XML_ITEM_LIST__TYPE__UNK2: floor.unk_items2 = MappaItemList.from_xml(child) else: raise XmlValidateError( f(_('Floor parsing: Unexpected {child.tag}')))
def from_xml(cls, xml: Element, value_to_update: LevelBinEntry): if len(xml) != 100: raise XmlValidateError( "Invalid XML. StatsGrowth must have exactly 100 levels.") for i, xml_level in enumerate(xml): validate_xml_tag(xml_level, XML_STATS_GROWTH_LEVEL) required_exp = None hp = None attack = None sp_attack = None defense = None sp_defense = None for xml_stat in xml_level: if xml_stat.tag == XML_STATS_GROWTH_LEVEL__REQUIRED_EXP: required_exp = int(xml_stat.text) elif xml_stat.tag == XML_STATS_GROWTH_LEVEL__HP: hp = int(xml_stat.text) elif xml_stat.tag == XML_STATS_GROWTH_LEVEL__ATTACK: attack = int(xml_stat.text) elif xml_stat.tag == XML_STATS_GROWTH_LEVEL__SP_ATTACK: sp_attack = int(xml_stat.text) elif xml_stat.tag == XML_STATS_GROWTH_LEVEL__DEFENSE: defense = int(xml_stat.text) elif xml_stat.tag == XML_STATS_GROWTH_LEVEL__SP_DEFENSE: sp_defense = int(xml_stat.text) if required_exp is None: raise XmlValidateError( f"Invalid XML. '{XML_STATS_GROWTH_LEVEL__REQUIRED_EXP}' missing for a stats growth level entry." ) if hp is None: raise XmlValidateError( f"Invalid XML. '{XML_STATS_GROWTH_LEVEL__HP}' missing for a stats growth level entry." ) if attack is None: raise XmlValidateError( f"Invalid XML. '{XML_STATS_GROWTH_LEVEL__ATTACK}' missing for a stats growth level entry." ) if sp_attack is None: raise XmlValidateError( f"Invalid XML. '{XML_STATS_GROWTH_LEVEL__SP_ATTACK}' missing for a stats growth level entry." ) if defense is None: raise XmlValidateError( f"Invalid XML. '{XML_STATS_GROWTH_LEVEL__DEFENSE}' missing for a stats growth level entry." ) if sp_defense is None: raise XmlValidateError( f"Invalid XML. '{XML_STATS_GROWTH_LEVEL__SP_DEFENSE}' missing for a stats growth level entry." ) value_to_update.levels[i] = LevelEntry(required_exp, hp, attack, sp_attack, defense, sp_defense, 0)
def from_xml(cls, xml: Element, value_to_update: MdEntry): for sub_xml in xml: if sub_xml.tag in XML_GENENT__MAP__SIMPLE.keys(): attr_name = XML_GENENT__MAP__SIMPLE[sub_xml.tag] if attr_name in XML_GENENT__MAP__ENUMS.keys(): # Enum setattr( value_to_update, attr_name, XML_GENENT__MAP__ENUMS[attr_name](int(sub_xml.text))) else: # Simple value setattr(value_to_update, attr_name, int(sub_xml.text)) if sub_xml.tag == XML_GENENT_EVOLUTION_REQ: pre_evo_index = None method = None param1 = None param2 = None for value_xml in sub_xml: if value_xml.tag == XML_GENENT_EVOLUTION_REQ__PRE_EVO_INDEX: pre_evo_index = int(value_xml.text) elif value_xml.tag == XML_GENENT_EVOLUTION_REQ__EVO_METHOD: method = EvolutionMethod(int(value_xml.text)) elif value_xml.tag == XML_GENENT_EVOLUTION_REQ__EVO_PRAM1: param1 = int(value_xml.text) elif value_xml.tag == XML_GENENT_EVOLUTION_REQ__EVO_PRAM2: param2 = int(value_xml.text) if pre_evo_index is None: raise XmlValidateError( f"Invalid XML. '{XML_GENENT_EVOLUTION_REQ__PRE_EVO_INDEX}' missing for a {XML_GENENT_EVOLUTION_REQ}." ) if method is None: raise XmlValidateError( f"Invalid XML. '{XML_GENENT_EVOLUTION_REQ__EVO_METHOD}' missing for a {XML_GENENT_EVOLUTION_REQ}." ) if param1 is None: raise XmlValidateError( f"Invalid XML. '{XML_GENENT_EVOLUTION_REQ__EVO_PRAM1}' missing for a {XML_GENENT_EVOLUTION_REQ}." ) if param2 is None: raise XmlValidateError( f"Invalid XML. '{XML_GENENT_EVOLUTION_REQ__EVO_PRAM2}' missing for a {XML_GENENT_EVOLUTION_REQ}." ) value_to_update.pre_evo_index = pre_evo_index value_to_update.evo_method = method value_to_update.evo_param1 = param1 value_to_update.evo_param2 = param2 if sub_xml.tag == XML_GENENT_BASE_STATS: hp = None attack = None sp_attack = None defense = None sp_defense = None for value_xml in sub_xml: if value_xml.tag == XML_GENENT_BASE_STATS__HP: hp = int(value_xml.text) elif value_xml.tag == XML_GENENT_BASE_STATS__ATTACK: attack = int(value_xml.text) elif value_xml.tag == XML_GENENT_BASE_STATS__SP_ATTACK: sp_attack = int(value_xml.text) elif value_xml.tag == XML_GENENT_BASE_STATS__DEFENSE: defense = int(value_xml.text) elif value_xml.tag == XML_GENENT_BASE_STATS__SP_DEFENSE: sp_defense = int(value_xml.text) if hp is None: raise XmlValidateError( f"Invalid XML. '{XML_GENENT_BASE_STATS__HP}' missing for a {XML_GENENT_BASE_STATS}." ) if attack is None: raise XmlValidateError( f"Invalid XML. '{XML_GENENT_BASE_STATS__ATTACK}' missing for a {XML_GENENT_BASE_STATS}." ) if sp_attack is None: raise XmlValidateError( f"Invalid XML. '{XML_GENENT_BASE_STATS__SP_ATTACK}' missing for a {XML_GENENT_BASE_STATS}." ) if defense is None: raise XmlValidateError( f"Invalid XML. '{XML_GENENT_BASE_STATS__DEFENSE}' missing for a {XML_GENENT_BASE_STATS}." ) if sp_defense is None: raise XmlValidateError( f"Invalid XML. '{XML_STATS_GROWTH_LEVEL__SP_DEFENSE}' missing for a {XML_GENENT_BASE_STATS}." ) value_to_update.base_hp = hp value_to_update.base_atk = attack value_to_update.base_sp_atk = sp_attack value_to_update.base_def = defense value_to_update.base_sp_def = sp_defense if sub_xml.tag == XML_GENENT_EXCLUSIVE_ITEMS: if len(sub_xml) != 4: raise XmlValidateError( f"Invalid XML. '{XML_GENENT_EXCLUSIVE_ITEMS}' needs four item IDs." ) update = ('exclusive_item1', 'exclusive_item2', 'exclusive_item3', 'exclusive_item4') for item_xml, attr_name in zip(sub_xml, update): validate_xml_tag(item_xml, XML_GENENT_EXCLUSIVE_ITEMS__ITEM_ID) setattr(value_to_update, attr_name, int(item_xml.text)) if sub_xml.tag == XML_GENENT_BITFLAG1: unk0 = None unk1 = None unk2 = None unk3 = None unk4 = None unk5 = None unk6 = None unk7 = None for value_xml in sub_xml: if value_xml.tag == XML_GENENT_BITFLAG1__UNK0: unk0 = bool(int(value_xml.text)) elif value_xml.tag == XML_GENENT_BITFLAG1__UNK1: unk1 = bool(int(value_xml.text)) elif value_xml.tag == XML_GENENT_BITFLAG1__UNK2: unk2 = bool(int(value_xml.text)) elif value_xml.tag == XML_GENENT_BITFLAG1__UNK3: unk3 = bool(int(value_xml.text)) elif value_xml.tag == XML_GENENT_BITFLAG1__UNK4: unk4 = bool(int(value_xml.text)) elif value_xml.tag == XML_GENENT_BITFLAG1__UNK5: unk5 = bool(int(value_xml.text)) elif value_xml.tag == XML_GENENT_BITFLAG1__UNK6: unk6 = bool(int(value_xml.text)) elif value_xml.tag == XML_GENENT_BITFLAG1__UNK7: unk7 = bool(int(value_xml.text)) if unk0 is None: raise XmlValidateError( f"Invalid XML. '{XML_GENENT_BITFLAG1__UNK0}' missing for a {XML_GENENT_BASE_STATS}." ) if unk1 is None: raise XmlValidateError( f"Invalid XML. '{XML_GENENT_BITFLAG1__UNK1}' missing for a {XML_GENENT_BASE_STATS}." ) if unk2 is None: raise XmlValidateError( f"Invalid XML. '{XML_GENENT_BITFLAG1__UNK2}' missing for a {XML_GENENT_BASE_STATS}." ) if unk3 is None: raise XmlValidateError( f"Invalid XML. '{XML_GENENT_BITFLAG1__UNK3}' missing for a {XML_GENENT_BASE_STATS}." ) if unk4 is None: raise XmlValidateError( f"Invalid XML. '{XML_GENENT_BITFLAG1__UNK4}' missing for a {XML_GENENT_BASE_STATS}." ) if unk5 is None: raise XmlValidateError( f"Invalid XML. '{XML_GENENT_BITFLAG1__UNK5}' missing for a {XML_GENENT_BASE_STATS}." ) if unk6 is None: raise XmlValidateError( f"Invalid XML. '{XML_GENENT_BITFLAG1__UNK6}' missing for a {XML_GENENT_BASE_STATS}." ) if unk7 is None: raise XmlValidateError( f"Invalid XML. '{XML_GENENT_BITFLAG1__UNK7}' missing for a {XML_GENENT_BASE_STATS}." ) value_to_update.bitfield1_0 = unk0 value_to_update.bitfield1_1 = unk1 value_to_update.bitfield1_2 = unk2 value_to_update.bitfield1_3 = unk3 value_to_update.can_move = unk4 value_to_update.bitfield1_5 = unk5 value_to_update.can_evolve = unk6 value_to_update.item_required_for_spawning = unk7
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))), )