diff --git a/src/mercury_engine_data_structures/formats/__init__.py b/src/mercury_engine_data_structures/formats/__init__.py index 37ba59b..db620df 100644 --- a/src/mercury_engine_data_structures/formats/__init__.py +++ b/src/mercury_engine_data_structures/formats/__init__.py @@ -28,6 +28,7 @@ from mercury_engine_data_structures.formats.bmsmd import Bmsmd from mercury_engine_data_structures.formats.bmsmsd import Bmsmsd from mercury_engine_data_structures.formats.bmsnav import Bmsnav +from mercury_engine_data_structures.formats.bmssa import Bmssa from mercury_engine_data_structures.formats.bmssd import Bmssd from mercury_engine_data_structures.formats.bmtre import Bmtre from mercury_engine_data_structures.formats.bmtun import Bmtun @@ -68,6 +69,7 @@ "BMMDEF": Bmmdef, "BMSBK": Bmsbk, "BMSCP": Bmscp, + "BMSSA": Bmssa, "BMSSD": Bmssd, "BMSSH": Bmssh, "BMSSK": Bmssk, diff --git a/src/mercury_engine_data_structures/formats/bmssa.py b/src/mercury_engine_data_structures/formats/bmssa.py new file mode 100644 index 0000000..41369fe --- /dev/null +++ b/src/mercury_engine_data_structures/formats/bmssa.py @@ -0,0 +1,49 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + +from construct.core import ( + Const, + Flag, + Struct, + Terminated, +) + +from mercury_engine_data_structures.base_resource import BaseResource +from mercury_engine_data_structures.common_types import StrId, VersionAdapter, make_dict, make_vector + +if TYPE_CHECKING: + from construct import Construct + + from mercury_engine_data_structures.game_check import Game + +Camera_Subarea_Setup = Struct( + "environment_preset" / StrId, # bmsev + "sound" / StrId, # bmses + + # the following 3 are almost always none, possibly extra groups? + "unk2" / StrId, # lg or eg, only used in cockpit/credits scenarios + "entity_group" / StrId, + "block_group" / StrId, + + "cc_names" / make_vector(StrId), + "actors_in_scenario" / make_vector(StrId), + "cutscenes" / make_vector(StrId), # bmscu files + "collision_layer" / StrId, # bmscd: entry in collision_layer + "unk9" / Flag, +) # fmt: skip + +CollisionCamera = Struct("setups" / make_dict(Camera_Subarea_Setup)) + +BMSSA = Struct( + "_magic" / Const(b"MSSA"), + "version" / VersionAdapter("1.22.0"), + "cameras" / make_dict(CollisionCamera), + Terminated, +) + + +class Bmssa(BaseResource): + @classmethod + def construct_class(cls, target_game: Game) -> Construct: + return BMSSA diff --git a/tests/formats/test_bmssa.py b/tests/formats/test_bmssa.py new file mode 100644 index 0000000..dce0046 --- /dev/null +++ b/tests/formats/test_bmssa.py @@ -0,0 +1,12 @@ +from __future__ import annotations + +import pytest +from tests.test_lib import parse_build_compare_editor_parsed + +from mercury_engine_data_structures import samus_returns_data +from mercury_engine_data_structures.formats.bmssa import Bmssa + + +@pytest.mark.parametrize("bmssa_path", samus_returns_data.all_files_ending_with(".bmssa")) +def test_compare_bmssa_msr(samus_returns_tree, bmssa_path): + parse_build_compare_editor_parsed(Bmssa, samus_returns_tree, bmssa_path)