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, ele: Element) -> 'MappaBin': validate_xml_tag(ele, XML_MAPPA) floor_lists = [] for x_floor_list in ele: floor_list = [] validate_xml_tag(x_floor_list, XML_FLOOR_LIST) for x_floor in x_floor_list: floor_list.append(MappaFloor.from_xml(x_floor)) floor_lists.append(floor_list) return cls(floor_lists)
def _read_floors(cls, read: MappaBinReadContainer, pointer: int): # The zeroth floor is just nulls, we omit it. empty = bytes(FLOOR_IDX_ENTRY_LEN) assert read.data[pointer:pointer + FLOOR_IDX_ENTRY_LEN] == empty, \ "The first floor of a dungeon must be a null floor." floors = [] pointer += FLOOR_IDX_ENTRY_LEN floor_data = read.data[pointer:pointer + FLOOR_IDX_ENTRY_LEN] while floor_data != empty: floors.append(MappaFloor.from_mappa(read, floor_data)) pointer += FLOOR_IDX_ENTRY_LEN floor_data = read.data[pointer:pointer + FLOOR_IDX_ENTRY_LEN] if pointer > read.dungeon_list_index_start - FLOOR_IDX_ENTRY_LEN: break return floors
def mappa_floor_xml_export(floor: MappaFloor, export_layout=True, export_monsters=True, export_traps=True, export_floor_items=True, export_shop_items=True, export_monster_house_items=True, export_buried_items=True, export_unk1_items=True, export_unk2_items=True) -> Element: """Exports the requested data of the mappa floor as XML.""" return floor.to_xml(export_layout=export_layout, export_monsters=export_monsters, export_traps=export_traps, export_floor_items=export_floor_items, export_shop_items=export_shop_items, export_monster_house_items=export_monster_house_items, export_buried_items=export_buried_items, export_unk1_items=export_unk1_items, export_unk2_items=export_unk2_items)
def mappa_generate_new_floor(self) -> MappaFloor: """Copies the first floor of test dungeon and returns it""" return MappaFloor.from_xml(self.get_mappa().floor_lists[0][0].to_xml())
def change_floor_count(self, dungeon_id, number_floors_new): #TODO: Unchanged """ This will update the floor count for the given dungeon: - Will add or remove floors from the dungeon's mappa entry, starting at the end of this dungeon's floor based on the current floor count for this dungeon - Update the dungeon's data entry (floor count + total floor count in group) - For all other dungeons in the same group: Update data entries (total floor count + start offset) - Regenerate the UI in SkyTemple (dungeon tree) """ dungeon_definitions = self.get_dungeon_list() is_group: Union[False, DungeonGroup] = False for dungeon_or_group in self.load_dungeons(): if dungeon_or_group == dungeon_id: break elif isinstance(dungeon_or_group, DungeonGroup): if dungeon_id in dungeon_or_group.dungeon_ids: is_group = dungeon_or_group break mappa_index = dungeon_definitions[dungeon_id].mappa_index floor_offset = dungeon_definitions[dungeon_id].start_after number_floors_old = dungeon_definitions[dungeon_id].number_floors floor_list = self.get_mappa().floor_lists[mappa_index] floors_added = number_floors_new - number_floors_old # Update Mappa if floors_added == 0: return # nothing to do if floors_added < 0: # We removed floors for _ in range(0, -floors_added): del floor_list[floor_offset + number_floors_new] else: # We added floors last_floor_xml = floor_list[floor_offset + number_floors_old - 1].to_xml() for i in range(0, floors_added): floor_list.insert(floor_offset + number_floors_old + i, MappaFloor.from_xml(last_floor_xml)) # Update floor ranks self.extend_nb_floors_ranks( dungeon_id, floor_offset + number_floors_old, floors_added, self.get_floor_rank(dungeon_id, floor_offset + number_floors_old - 1)) if self.has_floor_ranks(): self.project.mark_as_modified(FLOOR_RANKS) # Update mission forbidden self.extend_nb_floors_mf( dungeon_id, floor_offset + number_floors_old, floors_added, self.get_floor_mf(dungeon_id, floor_offset + number_floors_old - 1)) if self.has_mission_forbidden(): self.project.mark_as_modified(FLOOR_MISSION_FORBIDDEN) # Update dungeon data dungeon_definitions[dungeon_id].number_floors = number_floors_new if is_group: new_total_floor_count = sum([ dungeon_definitions[x].number_floors for x in is_group.dungeon_ids ]) dungeon_definitions[ dungeon_id].number_floors_in_group = new_total_floor_count for dungeon_in_group in (x for x in is_group.dungeon_ids if x != dungeon_id): # Update dungeon data of group floors if dungeon_definitions[ dungeon_in_group].start_after > dungeon_definitions[ dungeon_id].start_after: dungeon_definitions[ dungeon_in_group].start_after += floors_added dungeon_definitions[ dungeon_in_group].number_floors_in_group = new_total_floor_count else: dungeon_definitions[ dungeon_id].number_floors_in_group = number_floors_new # Re-count floors for i, floor in enumerate(floor_list): floor.layout.floor_number = i + 1 # Mark as changed self.mark_dungeon_as_modified(dungeon_id, True) self.save_dungeon_list(dungeon_definitions) if is_group: for dungeon_in_group in is_group.dungeon_ids: self._regenerate_dungeon_floors( dungeon_in_group, dungeon_definitions[dungeon_in_group].start_after) else: self._regenerate_dungeon_floors(dungeon_id, floor_offset) recursive_generate_item_store_row_label( self._tree_model[self._root_iter])