Exemple #1
0
    def remove_entry_from_voice_set(self, voice_set_label: str, index: int):
        reader, set_count = self._get_reader_at_voice_set_table(voice_set_label)
        if index < 0 or index >= set_count:
            raise Exception
        target_address = reader.tell() + index * 8
        self.archive.deallocate(target_address, 8, False)

        writer = BinArchiveWriter(self.archive, reader.tell() - 8)
        writer.write_u32(set_count - 1)
        writer.write_u32(set_count - 1)
Exemple #2
0
    def _set_support_type_helper(self, owner, other, new_support_type):
        reader = self._open_reader_at_table(owner["Support ID"].value)
        reader.seek(reader.tell() + 2)
        count = reader.read_u16()
        supports_start = reader.tell()
        target_index = self._find_index_of_support_with_character(
            reader, other, count)
        target_address = supports_start + target_index * 0xC + 0x4

        writer = BinArchiveWriter(self.archive, target_address)
        writer.write_u32(new_support_type)
Exemple #3
0
 def write_count(self, archive, count: int):
     count_address = self.location_strategy.read_base_address(archive)
     writer = BinArchiveWriter(archive, count_address)
     if self.width == 1:
         writer.write_u8(count)
     elif self.width == 2:
         writer.write_u16(count)
     else:
         writer.write_u32(count)
Exemple #4
0
 def save_entry(self, voice_set_label: str, entry: PropertyContainer, index: int):
     reader, set_count = self._get_reader_at_voice_set_table(voice_set_label)
     if index < 0 or index >= set_count:
         raise Exception
     reader.seek(reader.tell() + index * 8)
     writer = BinArchiveWriter(self.archive, reader.tell())
     for prop in entry.values():
         prop.write(writer)
Exemple #5
0
    def create_voice_set(self, voice_set_label: str):
        if voice_set_label in self.voice_set_labels:
            raise NameError

        # Write the new entry to the end of the set table.
        address = self._get_set_table_end()
        self.archive.allocate(address, 0x10, False)
        writer = BinArchiveWriter(self.archive, address)
        writer.write_mapped(voice_set_label)
        writer.write_u32(0xFFFF0002)
        writer.write_string(voice_set_label)
        writer.write_u32(0)
        writer.write_u32(0)

        # Update the count.
        self.voice_set_labels.append(voice_set_label)
        self._count_strategy.write_count(self.archive, len(self.voice_set_labels))
Exemple #6
0
 def to_bin(self):
     archive = fefeditor2.create_bin_archive()
     archive.allocate_at_end(self._calculate_binary_size())
     writer = BinArchiveWriter(archive)
     writer.write_pointer(_HEADER_SIZE)
     writer.write_u32(len(self.tiles))
     self.map_model.write(writer)
     writer.write_pointer(self._grid_address())
     for tile in self.tiles:
         for prop in tile.values():
             prop.write(writer)
     self.map_size_x.write(writer)
     self.map_size_y.write(writer)
     self.border_size_x.write(writer)
     self.border_size_y.write(writer)
     self.trimmed_size_x.write(writer)
     self.trimmed_size_y.write(writer)
     for row in self.grid:
         writer.write_bytes(row)
     return archive
Exemple #7
0
    def append_entry_to_voice_set(self, voice_set_label: str) -> PropertyContainer:
        reader, set_count = self._get_reader_at_voice_set_table(voice_set_label)
        reader.seek(reader.tell() - 8)
        writer = BinArchiveWriter(self.archive, reader.tell())
        writer.write_u32(set_count + 1)
        writer.write_u32(set_count + 1)

        entry = PropertyContainer()
        entry["Name"] = StringProperty("Name", value="Placeholder")
        entry["Tag"] = BufferProperty("Tag", value=[1, 0, 0, 0])
        writer.seek(writer.tell() + set_count * 8)
        self.archive.allocate(writer.tell(), 8, False)
        for prop in entry.values():
            prop.write(writer)
        return entry
Exemple #8
0
    def _create_support_table(self, character):
        # First, increment master support table count.
        master_support_table_address = self._get_master_support_table_address()
        writer = BinArchiveWriter(self.archive, master_support_table_address)
        reader = BinArchiveReader(self.archive, master_support_table_address)
        old_count = reader.read_u32()
        writer.write_u32(old_count + 1)

        # Next, create a pointer to the new table.
        pointer_address = master_support_table_address + old_count * 4 + 4
        self.archive.allocate(pointer_address, 4, False)
        destination = self.archive.size()
        self.archive.set_internal_pointer(pointer_address, destination)

        # Generate and assign a support ID for the character
        support_id = self._find_next_support_id()
        character["Support ID"].value = support_id

        # Allocate and format the new table.
        writer.seek(destination)
        self.archive.allocate_at_end(4)
        writer.write_u16(support_id)
Exemple #9
0
    def _remove_support_from_table(self, owner, other):
        # Update count.
        reader = self._open_reader_at_table(owner["Support ID"].value)
        reader.seek(reader.tell() + 2)
        writer = BinArchiveWriter(self.archive, reader.tell())
        old_count = reader.read_u16()
        writer.write_u16(old_count - 1)

        # Deallocate the support.
        target_index = self._find_index_of_support_with_character(
            reader, other, old_count)
        target_address = writer.tell() + target_index * 0xC
        self.archive.deallocate(target_address, 0xC, False)

        # Shift supports numbers back.
        writer.seek(target_address + 2)
        for i in range(target_index, old_count - 1):
            writer.write_u16(i)
            writer.seek(writer.tell() + 0xA)
Exemple #10
0
    def _add_support_to_table(self, character1, character2, support_type):
        # Jump to the target support table.
        master_support_table_address = self._get_master_support_table_address()
        reader = BinArchiveReader(self.archive, master_support_table_address)
        target_support_id = character1["Support ID"].value
        reader.seek(reader.tell() + target_support_id * 4 + 4)
        reader.seek(reader.read_internal_pointer() + 2)  # Skip the owner id.

        # Update the support count.
        writer = BinArchiveWriter(self.archive, reader.tell())
        old_count = reader.read_u16()
        writer.write_u16(old_count + 1)

        # Create the new support.
        new_support_address = writer.tell() + old_count * 0xC
        self.archive.allocate(new_support_address, 0xC, False)
        writer.seek(new_support_address)
        writer.write_u16(character2["ID"].value)
        writer.write_u16(old_count)
        writer.write_u32(support_type)
        writer.write_u32(0x1)  # Support tag. Still figuring this part out.
Exemple #11
0
 def _write_factions(self, archive):
     writer = BinArchiveWriter(archive)
     next_spawn_address = self._calculate_header_size()
     for faction in self.factions:
         faction.write(writer, next_spawn_address)
         next_spawn_address += len(faction.spawns) * 0x8C
Exemple #12
0
 def write(self, writer: BinArchiveWriter, spawn_address):
     writer.write_string(self.name)
     writer.write_pointer(spawn_address)
     writer.write_u32(len(self.spawns))
     end_address = writer.tell()
     writer.seek(spawn_address)
     for spawn in self.spawns:
         for prop in spawn.values():
             prop.write(writer)
     writer.seek(end_address)
Exemple #13
0
 def commit_changes(self):
     location = self.location_strategy.read_base_address(self.archive)
     writer = BinArchiveWriter(self.archive, location)
     for prop in self.element.values():
         prop.write(writer)
Exemple #14
0
 def commit_changes(self):
     base_location = self.location_strategy.read_base_address(self.archive)
     writer = BinArchiveWriter(self.archive, base_location)
     for elem in self.entries:
         for (_, prop) in elem.items():
             prop.write(writer)