예제 #1
0
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}')))
예제 #2
0
 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)
예제 #3
0
 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
예제 #4
0
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)
예제 #5
0
 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())
예제 #6
0
    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])