Esempio n. 1
0
    def pack(self):
        """Pack to bytes, presumably as part of a full `MSB` pack."""

        # Validate draw/display groups before doing any real work.
        draw_groups = bit_set_to_int_group(self._draw_groups, group_size=4)
        display_groups = bit_set_to_int_group(self._display_groups, group_size=4)

        name_offset = self.PART_HEADER_STRUCT.size
        packed_name = self.get_name_to_pack().encode(self.NAME_ENCODING) + b"\0"  # Name not padded on its own.
        sib_path_offset = name_offset + len(packed_name)
        packed_sib_path = self.sib_path.encode(self.NAME_ENCODING) + b"\0" if self.sib_path else b"\0" * 6
        while len(packed_name + packed_sib_path) % 4 != 0:
            packed_sib_path += b"\0"
        base_data_offset = sib_path_offset + len(packed_sib_path)
        packed_base_data = self.PART_BASE_DATA_STRUCT.pack(self)
        type_data_offset = base_data_offset + len(packed_base_data)
        packed_type_data = self.pack_type_data()
        try:
            packed_header = self.PART_HEADER_STRUCT.pack(
                __name_offset=name_offset,
                __part_type=self.ENTRY_SUBTYPE,
                _part_type_index=self._part_type_index,
                _model_index=self._model_index,
                __sib_path_offset=sib_path_offset,
                translate=list(self.translate),
                rotate=list(self.rotate),
                scale=list(self.scale),
                __draw_groups=draw_groups,
                __display_groups=display_groups,
                __base_data_offset=base_data_offset,
                __type_data_offset=type_data_offset,
            )
        except struct.error:
            raise MapError(f"Could not pack header data of `{self.__class__.__name__}` '{self.name}'. See traceback.")
        return packed_header + packed_name + packed_sib_path + packed_base_data + packed_type_data
Esempio n. 2
0
    def pack(self) -> bytes:
        """Pack to bytes, presumably as part of a full `MSB` pack."""

        # Validate draw/display/backread groups before doing any real work.
        draw_groups = bit_set_to_int_group(self._draw_groups, group_size=8)
        display_groups = bit_set_to_int_group(self._display_groups, group_size=8)
        backread_groups = bit_set_to_int_group(self._backread_groups, group_size=8)

        description_offset = self.PART_HEADER_STRUCT.size
        packed_description = self.description.encode("utf-16-le") + b"\0\0"
        name_offset = description_offset + len(packed_description)
        packed_name = self.get_name_to_pack().encode("utf-16-le") + b"\0\0"
        sib_path_offset = name_offset + len(packed_name)
        packed_sib_path = self.sib_path.encode("utf-16-le") + b"\0\0" if self.sib_path else b"\0\0"
        strings_size = len(packed_description + packed_name + packed_sib_path)
        if strings_size <= 0x38:
            packed_sib_path += b"\0" * (0x3c - strings_size)
        else:
            packed_sib_path += b"\0" * 8
        while len(packed_description + packed_name + packed_sib_path) % 4 != 0:
            packed_sib_path += b"\0"  # Not done in SoulsFormats, but makes sense to me.

        base_data_offset = sib_path_offset + len(packed_sib_path)
        packed_base_data = self.PART_BASE_DATA_STRUCT.pack(self)
        type_data_offset = base_data_offset + len(packed_base_data)
        packed_type_data = self.pack_type_data()
        gparam_data_offset = type_data_offset + len(packed_type_data)
        packed_gparam_data = self._pack_gparam_data()
        scene_gparam_data_offset = gparam_data_offset + len(packed_gparam_data)
        packed_scene_gparam_data = self._pack_scene_gparam_data()
        try:
            packed_header = self.PART_HEADER_STRUCT.pack(
                __description_offset=description_offset,
                __name_offset=name_offset,
                _instance_index=self._instance_index,
                __part_type=self.ENTRY_SUBTYPE,
                _part_type_index=self._part_type_index,
                _model_index=self._model_index,
                __sib_path_offset=sib_path_offset,
                translate=list(self.translate),
                rotate=list(self.rotate),
                scale=list(self.scale),
                __draw_groups=draw_groups,
                __display_groups=display_groups,
                __backread_groups=backread_groups,
                __base_data_offset=base_data_offset,
                __type_data_offset=type_data_offset,
                __gparam_data_offset=gparam_data_offset,
                __scene_gparam_data_offset=scene_gparam_data_offset,
            )
        except struct.error:
            raise MapError(f"Could not pack header data of MSB part '{self.name}'. See traceback.")
        return (
            packed_header + packed_description + packed_name + packed_sib_path
            + packed_base_data + packed_type_data + packed_gparam_data + packed_scene_gparam_data
        )
Esempio n. 3
0
    def pack_type_data(self):
        """Pack to bytes, presumably as part of a full `MSB` pack."""

        # Validate navmesh groups before doing any real work.
        navmesh_groups = bit_set_to_int_group(self._navmesh_groups,
                                              group_size=4)

        if self.area_name_id == -1 and not self._force_area_banner:
            raise InvalidFieldValueError(
                "`force_area_banner` must be enabled if `area_name_id == -1` (default)."
            )
        signed_area_name_id = self.area_name_id * (
            -1 if self.area_name_id >= 0 and self._force_area_banner else 1)
        if self._stable_footing_flag != 0:
            play_region_id = -self._stable_footing_flag - 10
        else:
            play_region_id = self._play_region_id
        return self.PART_TYPE_DATA_STRUCT.pack(
            hit_filter_id=self.hit_filter_id,
            sound_space_type=self.sound_space_type,
            _environment_event_index=self._environment_event_index,
            reflect_plane_height=self.reflect_plane_height,
            __navmesh_groups=navmesh_groups,
            vagrant_entity_ids=self.vagrant_entity_ids,
            __area_name_id=signed_area_name_id,
            starts_disabled=self.starts_disabled,
            unk_x27_x28=self.unk_x27_x28,
            attached_bonfire=self.attached_bonfire,
            __play_region_id=play_region_id,
            camera_1_id=self.camera_1_id,
            camera_2_id=self.camera_2_id,
        )
Esempio n. 4
0
 def pack_type_data(self):
     return self.PART_TYPE_DATA_STRUCT.pack(
         __navmesh_groups=bit_set_to_int_group(self._navmesh_groups,
                                               group_size=4), )