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)
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)
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)
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)
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))
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
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
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)
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)
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.
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
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)
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)
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)