From 5780ca8a4593d8d0532968b7a532801db0b6a2d4 Mon Sep 17 00:00:00 2001 From: dyceron Date: Wed, 18 Dec 2024 22:59:20 -0500 Subject: [PATCH 01/16] BMSCC Refactor --- .../formats/bmscc.py | 64 +++++++++++++------ tests/formats/test_collision.py | 13 ++++ 2 files changed, 56 insertions(+), 21 deletions(-) diff --git a/src/mercury_engine_data_structures/formats/bmscc.py b/src/mercury_engine_data_structures/formats/bmscc.py index aaee9a3..6f89956 100644 --- a/src/mercury_engine_data_structures/formats/bmscc.py +++ b/src/mercury_engine_data_structures/formats/bmscc.py @@ -1,11 +1,12 @@ from __future__ import annotations +from typing import TYPE_CHECKING + import construct -from construct import ( +from construct.core import ( Const, Construct, - GreedyBytes, - IfThenElse, + Container, Int8ul, Int16ul, Struct, @@ -14,43 +15,52 @@ from mercury_engine_data_structures import game_check from mercury_engine_data_structures.base_resource import BaseResource -from mercury_engine_data_structures.common_types import StrId, VersionAdapter, make_vector +from mercury_engine_data_structures.common_types import ( + StrId, + VersionAdapter, + make_vector, +) from mercury_engine_data_structures.construct_extensions.misc import ErrorWithMessage from mercury_engine_data_structures.formats.collision import collision_formats -from mercury_engine_data_structures.game_check import Game + +if TYPE_CHECKING: + from mercury_engine_data_structures.game_check import Game CollisionEntry = Struct( - name=StrId, - prop1=StrId, - prop2=StrId, - prop3=StrId, - flag=IfThenElse( - game_check.current_game_at_most(Game.SAMUS_RETURNS), + "name" / StrId, + "prop1" / StrId, + "prop2" / StrId, + "prop3" / StrId, + "flag" + / game_check.is_sr_or_else( Int8ul, Int16ul, ), - type=StrId, - data=Switch( + "type" / StrId, + "data" + / Switch( construct.this.type, collision_formats, - ErrorWithMessage(lambda ctx: f"Type {ctx.type} not known, valid types are {list(collision_formats.keys())}."), + ErrorWithMessage( + lambda ctx: f"Type {ctx.type} not known, valid types are {list(collision_formats.keys())}." + ), ), ) CollisionLayer = Struct( - name=StrId, - entries=make_vector(CollisionEntry), + "name" / StrId, + "entries" / make_vector(CollisionEntry), ) BMSCC = Struct( - _magic=Const(b"MSCD"), - _version=IfThenElse( - game_check.current_game_at_most(Game.SAMUS_RETURNS), + "_magic" / Const(b"MSCD"), + "_version" + / game_check.is_sr_or_else( VersionAdapter("1.13.0"), VersionAdapter("1.16.0"), ), - layers=make_vector(CollisionLayer), - eof=GreedyBytes, + "layers" / make_vector(CollisionLayer), + construct.Terminated, ) @@ -58,3 +68,15 @@ class Bmscc(BaseResource): @classmethod def construct_class(cls, target_game: Game) -> Construct: return BMSCC + + def get_data(self) -> Container: + return self.raw.layers[0].entries[0].data + + def get_poly(self, poly_idx: int) -> Container: + return self.get_data().polys[poly_idx] + + def get_point(self, poly_idx: int, point_idx: int) -> Container: + return self.get_poly(poly_idx).points[point_idx] + + def get_total_boundings(self) -> Container: + return self.get_data().total_boundings diff --git a/tests/formats/test_collision.py b/tests/formats/test_collision.py index b135773..3a89d5a 100644 --- a/tests/formats/test_collision.py +++ b/tests/formats/test_collision.py @@ -92,3 +92,16 @@ def test_compare_dread_210(dread_tree_210, file_path): ) def test_compare_collision_msr(samus_returns_tree, file_path): parse_build_compare_editor_parsed(Bmscc, samus_returns_tree, file_path) + +@pytest.fixture() +def surface_bmscc(samus_returns_tree) -> Bmscc: + return samus_returns_tree.get_parsed_asset("maps/levels/c10_samus/s000_surface/s000_surface.bmscc", type_hint=Bmscc) + +def test_get_data(surface_bmscc: Bmscc): + data = surface_bmscc.get_data() + assert data[2] == surface_bmscc.get_total_boundings() + +def test_modifying_collision(surface_bmscc: Bmscc): + point = surface_bmscc.get_point(2, 9) + assert point["x"] == -800.0 + assert point["y"] == -7000.0 From d235b18c053c5e6d4f836363f73179067a74bdb3 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 19 Dec 2024 04:06:47 +0000 Subject: [PATCH 02/16] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/mercury_engine_data_structures/formats/bmscc.py | 4 +--- tests/formats/test_collision.py | 3 +++ 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/mercury_engine_data_structures/formats/bmscc.py b/src/mercury_engine_data_structures/formats/bmscc.py index 6f89956..abe9aa1 100644 --- a/src/mercury_engine_data_structures/formats/bmscc.py +++ b/src/mercury_engine_data_structures/formats/bmscc.py @@ -41,9 +41,7 @@ / Switch( construct.this.type, collision_formats, - ErrorWithMessage( - lambda ctx: f"Type {ctx.type} not known, valid types are {list(collision_formats.keys())}." - ), + ErrorWithMessage(lambda ctx: f"Type {ctx.type} not known, valid types are {list(collision_formats.keys())}."), ), ) diff --git a/tests/formats/test_collision.py b/tests/formats/test_collision.py index 3a89d5a..2d2a2b9 100644 --- a/tests/formats/test_collision.py +++ b/tests/formats/test_collision.py @@ -93,14 +93,17 @@ def test_compare_dread_210(dread_tree_210, file_path): def test_compare_collision_msr(samus_returns_tree, file_path): parse_build_compare_editor_parsed(Bmscc, samus_returns_tree, file_path) + @pytest.fixture() def surface_bmscc(samus_returns_tree) -> Bmscc: return samus_returns_tree.get_parsed_asset("maps/levels/c10_samus/s000_surface/s000_surface.bmscc", type_hint=Bmscc) + def test_get_data(surface_bmscc: Bmscc): data = surface_bmscc.get_data() assert data[2] == surface_bmscc.get_total_boundings() + def test_modifying_collision(surface_bmscc: Bmscc): point = surface_bmscc.get_point(2, 9) assert point["x"] == -800.0 From 69bd148944e18a20d3960015ef76e40a24e40125 Mon Sep 17 00:00:00 2001 From: dyceron Date: Thu, 19 Dec 2024 21:34:34 -0500 Subject: [PATCH 03/16] Attempted fix for `Terminated` --- .../formats/bmscc.py | 14 +++++++++++++- tests/formats/test_collision.py | 4 ++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/mercury_engine_data_structures/formats/bmscc.py b/src/mercury_engine_data_structures/formats/bmscc.py index abe9aa1..ef27d16 100644 --- a/src/mercury_engine_data_structures/formats/bmscc.py +++ b/src/mercury_engine_data_structures/formats/bmscc.py @@ -20,6 +20,7 @@ VersionAdapter, make_vector, ) +from mercury_engine_data_structures.construct_extensions.function_complex import ComplexIf from mercury_engine_data_structures.construct_extensions.misc import ErrorWithMessage from mercury_engine_data_structures.formats.collision import collision_formats @@ -41,7 +42,9 @@ / Switch( construct.this.type, collision_formats, - ErrorWithMessage(lambda ctx: f"Type {ctx.type} not known, valid types are {list(collision_formats.keys())}."), + ErrorWithMessage( + lambda ctx: f"Type {ctx.type} not known, valid types are {list(collision_formats.keys())}." + ), ), ) @@ -50,6 +53,11 @@ "entries" / make_vector(CollisionEntry), ) +PartsComponent = Struct( + "group" / StrId, + "components" / make_vector(Struct("name" / StrId)), +) + BMSCC = Struct( "_magic" / Const(b"MSCD"), "_version" @@ -58,6 +66,10 @@ VersionAdapter("1.16.0"), ), "layers" / make_vector(CollisionLayer), + "parts" / game_check.is_sr_or_else( + construct.Terminated, + make_vector(PartsComponent) + ), construct.Terminated, ) diff --git a/tests/formats/test_collision.py b/tests/formats/test_collision.py index 2d2a2b9..3c592ab 100644 --- a/tests/formats/test_collision.py +++ b/tests/formats/test_collision.py @@ -96,12 +96,12 @@ def test_compare_collision_msr(samus_returns_tree, file_path): @pytest.fixture() def surface_bmscc(samus_returns_tree) -> Bmscc: - return samus_returns_tree.get_parsed_asset("maps/levels/c10_samus/s000_surface/s000_surface.bmscc", type_hint=Bmscc) + return samus_returns_tree.get_parsed_asset("maps/levels/c10_samus/s000_surface/s000_surface.bmscd", type_hint=Bmscc) def test_get_data(surface_bmscc: Bmscc): data = surface_bmscc.get_data() - assert data[2] == surface_bmscc.get_total_boundings() + assert len(data) == 5 def test_modifying_collision(surface_bmscc: Bmscc): From a970c2a9cb53be375156a3edd664fd545f07bea6 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 20 Dec 2024 02:34:42 +0000 Subject: [PATCH 04/16] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/mercury_engine_data_structures/formats/bmscc.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/mercury_engine_data_structures/formats/bmscc.py b/src/mercury_engine_data_structures/formats/bmscc.py index ef27d16..c3fec42 100644 --- a/src/mercury_engine_data_structures/formats/bmscc.py +++ b/src/mercury_engine_data_structures/formats/bmscc.py @@ -20,7 +20,6 @@ VersionAdapter, make_vector, ) -from mercury_engine_data_structures.construct_extensions.function_complex import ComplexIf from mercury_engine_data_structures.construct_extensions.misc import ErrorWithMessage from mercury_engine_data_structures.formats.collision import collision_formats @@ -42,9 +41,7 @@ / Switch( construct.this.type, collision_formats, - ErrorWithMessage( - lambda ctx: f"Type {ctx.type} not known, valid types are {list(collision_formats.keys())}." - ), + ErrorWithMessage(lambda ctx: f"Type {ctx.type} not known, valid types are {list(collision_formats.keys())}."), ), ) @@ -66,10 +63,7 @@ VersionAdapter("1.16.0"), ), "layers" / make_vector(CollisionLayer), - "parts" / game_check.is_sr_or_else( - construct.Terminated, - make_vector(PartsComponent) - ), + "parts" / game_check.is_sr_or_else(construct.Terminated, make_vector(PartsComponent)), construct.Terminated, ) From 8cd48d56d0cb7dabc9ffff963c82bf6d7ad461e0 Mon Sep 17 00:00:00 2001 From: dyceron Date: Thu, 19 Dec 2024 22:30:31 -0500 Subject: [PATCH 05/16] A more proper fix --- src/mercury_engine_data_structures/formats/bmscc.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/mercury_engine_data_structures/formats/bmscc.py b/src/mercury_engine_data_structures/formats/bmscc.py index c3fec42..c78af3b 100644 --- a/src/mercury_engine_data_structures/formats/bmscc.py +++ b/src/mercury_engine_data_structures/formats/bmscc.py @@ -20,6 +20,7 @@ VersionAdapter, make_vector, ) +from mercury_engine_data_structures.construct_extensions.function_complex import ComplexIf from mercury_engine_data_structures.construct_extensions.misc import ErrorWithMessage from mercury_engine_data_structures.formats.collision import collision_formats @@ -63,7 +64,14 @@ VersionAdapter("1.16.0"), ), "layers" / make_vector(CollisionLayer), - "parts" / game_check.is_sr_or_else(construct.Terminated, make_vector(PartsComponent)), + "_remaining" / construct.Peek(construct.GreedyBytes), + "parts" / ComplexIf( + lambda this: ( + (this._parsing and this._remaining) + or (this._building and (this.parts is not None)) + ), + make_vector(PartsComponent) + ), construct.Terminated, ) From 5aea8c460ab516657333435eb60c7c3218da963d Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 20 Dec 2024 03:30:39 +0000 Subject: [PATCH 06/16] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/mercury_engine_data_structures/formats/bmscc.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/mercury_engine_data_structures/formats/bmscc.py b/src/mercury_engine_data_structures/formats/bmscc.py index c78af3b..8e32f39 100644 --- a/src/mercury_engine_data_structures/formats/bmscc.py +++ b/src/mercury_engine_data_structures/formats/bmscc.py @@ -65,12 +65,10 @@ ), "layers" / make_vector(CollisionLayer), "_remaining" / construct.Peek(construct.GreedyBytes), - "parts" / ComplexIf( - lambda this: ( - (this._parsing and this._remaining) - or (this._building and (this.parts is not None)) - ), - make_vector(PartsComponent) + "parts" + / ComplexIf( + lambda this: ((this._parsing and this._remaining) or (this._building and (this.parts is not None))), + make_vector(PartsComponent), ), construct.Terminated, ) From 7e72fc821df261c0f01165a970c2b8e97ae0dad9 Mon Sep 17 00:00:00 2001 From: dyceron Date: Sat, 21 Dec 2024 10:00:03 -0500 Subject: [PATCH 07/16] Address reviews and add comments + function --- .../formats/bmscc.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/mercury_engine_data_structures/formats/bmscc.py b/src/mercury_engine_data_structures/formats/bmscc.py index 8e32f39..840d7b2 100644 --- a/src/mercury_engine_data_structures/formats/bmscc.py +++ b/src/mercury_engine_data_structures/formats/bmscc.py @@ -64,12 +64,7 @@ VersionAdapter("1.16.0"), ), "layers" / make_vector(CollisionLayer), - "_remaining" / construct.Peek(construct.GreedyBytes), - "parts" - / ComplexIf( - lambda this: ((this._parsing and this._remaining) or (this._building and (this.parts is not None))), - make_vector(PartsComponent), - ), + "parts" / construct.Optional(make_vector(PartsComponent)), construct.Terminated, ) @@ -79,14 +74,22 @@ class Bmscc(BaseResource): def construct_class(cls, target_game: Game) -> Construct: return BMSCC - def get_data(self) -> Container: - return self.raw.layers[0].entries[0].data + # Bmscc has an entry per collision_camera, Bmscd has one entry per file + def get_data(self, layer_idx: int = 0, entry_idx: int = 0) -> Container: + return self.raw.layers[layer_idx].entries[entry_idx].data + # Returns all data associated with a poly (points, boundings) def get_poly(self, poly_idx: int) -> Container: return self.get_data().polys[poly_idx] + # Returns a specific point in a poly def get_point(self, poly_idx: int, point_idx: int) -> Container: return self.get_poly(poly_idx).points[point_idx] + # Returns the total boundary of collision/collision_camera def get_total_boundings(self) -> Container: return self.get_data().total_boundings + + # Returns the boundary of a poly + def get_poly_boundings(self, poly_idx: int) -> Container: + return self.get_poly(poly_idx).boundings From 74f2c340c49c9702913b60d0c975e46f08fd8719 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 21 Dec 2024 15:00:12 +0000 Subject: [PATCH 08/16] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/mercury_engine_data_structures/formats/bmscc.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/mercury_engine_data_structures/formats/bmscc.py b/src/mercury_engine_data_structures/formats/bmscc.py index 840d7b2..ba11939 100644 --- a/src/mercury_engine_data_structures/formats/bmscc.py +++ b/src/mercury_engine_data_structures/formats/bmscc.py @@ -20,7 +20,6 @@ VersionAdapter, make_vector, ) -from mercury_engine_data_structures.construct_extensions.function_complex import ComplexIf from mercury_engine_data_structures.construct_extensions.misc import ErrorWithMessage from mercury_engine_data_structures.formats.collision import collision_formats From 1b862f3f2cde383d0a0b20403a0cd590222e94fd Mon Sep 17 00:00:00 2001 From: dyceron Date: Sat, 21 Dec 2024 10:27:06 -0500 Subject: [PATCH 09/16] Add coverage for boundings functions --- tests/formats/test_collision.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/formats/test_collision.py b/tests/formats/test_collision.py index 3c592ab..eb4298c 100644 --- a/tests/formats/test_collision.py +++ b/tests/formats/test_collision.py @@ -108,3 +108,18 @@ def test_modifying_collision(surface_bmscc: Bmscc): point = surface_bmscc.get_point(2, 9) assert point["x"] == -800.0 assert point["y"] == -7000.0 + + +def test_get_boundings(surface_bmscc: Bmscc): + total_boundings = surface_bmscc.get_total_boundings() + polys = surface_bmscc.get_data().polys + for poly in polys: + poly_boundings = surface_bmscc.get_poly_boundings(poly) + # x1 + assert poly_boundings[0] >= total_boundings[0] + # y1 + assert poly_boundings[1] >= total_boundings[1] + # x2 + assert poly_boundings[2] <= total_boundings[2] + # y2 + assert poly_boundings[3] <= total_boundings[3] From 46a1d173d4cf456e64836407218b7486c41e46ba Mon Sep 17 00:00:00 2001 From: dyceron Date: Sat, 21 Dec 2024 19:29:29 -0500 Subject: [PATCH 10/16] Attempted coverage fix --- tests/formats/test_collision.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/formats/test_collision.py b/tests/formats/test_collision.py index eb4298c..67a6c22 100644 --- a/tests/formats/test_collision.py +++ b/tests/formats/test_collision.py @@ -113,13 +113,13 @@ def test_modifying_collision(surface_bmscc: Bmscc): def test_get_boundings(surface_bmscc: Bmscc): total_boundings = surface_bmscc.get_total_boundings() polys = surface_bmscc.get_data().polys - for poly in polys: - poly_boundings = surface_bmscc.get_poly_boundings(poly) + for i, poly in enumerate(polys): + poly_boundings = surface_bmscc.get_poly_boundings(i) # x1 - assert poly_boundings[0] >= total_boundings[0] + assert poly_boundings[i][0] >= total_boundings[i][0] # y1 - assert poly_boundings[1] >= total_boundings[1] + assert poly_boundings[i][1] >= total_boundings[i][1] # x2 - assert poly_boundings[2] <= total_boundings[2] + assert poly_boundings[i][2] <= total_boundings[i][2] # y2 - assert poly_boundings[3] <= total_boundings[3] + assert poly_boundings[i][3] <= total_boundings[i][3] From 71095c4521ffdad0d7ee6ede382e10a2b8248d0b Mon Sep 17 00:00:00 2001 From: dyceron Date: Sat, 21 Dec 2024 19:49:21 -0500 Subject: [PATCH 11/16] Fix again --- tests/formats/test_collision.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/tests/formats/test_collision.py b/tests/formats/test_collision.py index 67a6c22..201426f 100644 --- a/tests/formats/test_collision.py +++ b/tests/formats/test_collision.py @@ -115,11 +115,9 @@ def test_get_boundings(surface_bmscc: Bmscc): polys = surface_bmscc.get_data().polys for i, poly in enumerate(polys): poly_boundings = surface_bmscc.get_poly_boundings(i) - # x1 - assert poly_boundings[i][0] >= total_boundings[i][0] - # y1 - assert poly_boundings[i][1] >= total_boundings[i][1] - # x2 - assert poly_boundings[i][2] <= total_boundings[i][2] - # y2 - assert poly_boundings[i][3] <= total_boundings[i][3] + # Boundings for polygons are in the order: x1, y1, x2, y2 + # Assert that the boundings are confined within the total bounds of the collision_camera + assert poly_boundings[0] >= total_boundings[0] + assert poly_boundings[1] >= total_boundings[1] + assert poly_boundings[2] <= total_boundings[2] + assert poly_boundings[3] <= total_boundings[3] From 1d1068586f4399aac7163916aa73a0c19e6a39ac Mon Sep 17 00:00:00 2001 From: dyceron Date: Sun, 22 Dec 2024 17:43:50 -0500 Subject: [PATCH 12/16] Address reviews --- .../formats/bmscc.py | 28 +++++++++---------- tests/formats/test_collision.py | 4 +-- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/mercury_engine_data_structures/formats/bmscc.py b/src/mercury_engine_data_structures/formats/bmscc.py index ba11939..5321513 100644 --- a/src/mercury_engine_data_structures/formats/bmscc.py +++ b/src/mercury_engine_data_structures/formats/bmscc.py @@ -74,21 +74,21 @@ def construct_class(cls, target_game: Game) -> Construct: return BMSCC # Bmscc has an entry per collision_camera, Bmscd has one entry per file - def get_data(self, layer_idx: int = 0, entry_idx: int = 0) -> Container: - return self.raw.layers[layer_idx].entries[entry_idx].data + def get_data(self, entry_idx: int = 0) -> Container: + return self.raw.layers[0].entries[entry_idx].data - # Returns all data associated with a poly (points, boundings) - def get_poly(self, poly_idx: int) -> Container: - return self.get_data().polys[poly_idx] + """Returns all data associated with a poly (points, boundings)""" + def get_poly(self, entry_idx: int = 0, poly_idx: int = 0) -> Container: + return self.get_data(entry_idx).polys[poly_idx] - # Returns a specific point in a poly - def get_point(self, poly_idx: int, point_idx: int) -> Container: - return self.get_poly(poly_idx).points[point_idx] + """Returns a specific point in a poly""" + def get_point(self, entry_idx: int = 0, poly_idx: int = 0, point_idx: int = 0) -> Container: + return self.get_poly(entry_idx, poly_idx).points[point_idx] - # Returns the total boundary of collision/collision_camera - def get_total_boundings(self) -> Container: - return self.get_data().total_boundings + """Returns the total boundary of collision/collision_camera""" + def get_total_boundings(self, entry_idx: int = 0) -> Container: + return self.get_data(entry_idx).total_boundings - # Returns the boundary of a poly - def get_poly_boundings(self, poly_idx: int) -> Container: - return self.get_poly(poly_idx).boundings + """Returns the boundary of a poly""" + def get_poly_boundings(self, entry_idx: int = 0, poly_idx: int = 0) -> Container: + return self.get_poly(entry_idx, poly_idx).boundings diff --git a/tests/formats/test_collision.py b/tests/formats/test_collision.py index 201426f..23773c1 100644 --- a/tests/formats/test_collision.py +++ b/tests/formats/test_collision.py @@ -105,7 +105,7 @@ def test_get_data(surface_bmscc: Bmscc): def test_modifying_collision(surface_bmscc: Bmscc): - point = surface_bmscc.get_point(2, 9) + point = surface_bmscc.get_point(0, 2, 9) assert point["x"] == -800.0 assert point["y"] == -7000.0 @@ -114,7 +114,7 @@ def test_get_boundings(surface_bmscc: Bmscc): total_boundings = surface_bmscc.get_total_boundings() polys = surface_bmscc.get_data().polys for i, poly in enumerate(polys): - poly_boundings = surface_bmscc.get_poly_boundings(i) + poly_boundings = surface_bmscc.get_poly_boundings(0, i) # Boundings for polygons are in the order: x1, y1, x2, y2 # Assert that the boundings are confined within the total bounds of the collision_camera assert poly_boundings[0] >= total_boundings[0] From 1fc067c1a6d043bf97b18f4a0510d53a2eb39424 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 22 Dec 2024 22:43:57 +0000 Subject: [PATCH 13/16] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/mercury_engine_data_structures/formats/bmscc.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/mercury_engine_data_structures/formats/bmscc.py b/src/mercury_engine_data_structures/formats/bmscc.py index 5321513..25172c6 100644 --- a/src/mercury_engine_data_structures/formats/bmscc.py +++ b/src/mercury_engine_data_structures/formats/bmscc.py @@ -78,17 +78,21 @@ def get_data(self, entry_idx: int = 0) -> Container: return self.raw.layers[0].entries[entry_idx].data """Returns all data associated with a poly (points, boundings)""" + def get_poly(self, entry_idx: int = 0, poly_idx: int = 0) -> Container: return self.get_data(entry_idx).polys[poly_idx] """Returns a specific point in a poly""" + def get_point(self, entry_idx: int = 0, poly_idx: int = 0, point_idx: int = 0) -> Container: return self.get_poly(entry_idx, poly_idx).points[point_idx] """Returns the total boundary of collision/collision_camera""" + def get_total_boundings(self, entry_idx: int = 0) -> Container: return self.get_data(entry_idx).total_boundings """Returns the boundary of a poly""" + def get_poly_boundings(self, entry_idx: int = 0, poly_idx: int = 0) -> Container: return self.get_poly(entry_idx, poly_idx).boundings From b50390a8af0e4624bfba4f3aad2d188c3b7741fe Mon Sep 17 00:00:00 2001 From: dyceron Date: Sun, 22 Dec 2024 23:18:09 -0500 Subject: [PATCH 14/16] Move functions to new class --- .../formats/bmscc.py | 50 +++++++++++-------- tests/formats/test_collision.py | 10 ++-- 2 files changed, 35 insertions(+), 25 deletions(-) diff --git a/src/mercury_engine_data_structures/formats/bmscc.py b/src/mercury_engine_data_structures/formats/bmscc.py index 25172c6..75f03a6 100644 --- a/src/mercury_engine_data_structures/formats/bmscc.py +++ b/src/mercury_engine_data_structures/formats/bmscc.py @@ -26,7 +26,7 @@ if TYPE_CHECKING: from mercury_engine_data_structures.game_check import Game -CollisionEntry = Struct( +CollisionEntryData = Struct( "name" / StrId, "prop1" / StrId, "prop2" / StrId, @@ -47,7 +47,7 @@ CollisionLayer = Struct( "name" / StrId, - "entries" / make_vector(CollisionEntry), + "entries" / make_vector(CollisionEntryData), ) PartsComponent = Struct( @@ -68,31 +68,41 @@ ) -class Bmscc(BaseResource): - @classmethod - def construct_class(cls, target_game: Game) -> Construct: - return BMSCC +class CollisionEntry: + def __init__(self, raw: Container): + self._raw = raw + # Bmscc has an entry per collision_camera, Bmscd has one entry per file - def get_data(self, entry_idx: int = 0) -> Container: - return self.raw.layers[0].entries[entry_idx].data + def get_data(self) -> Container: + """Returns all data of collision/collision_camera""" + return self._raw.data + - """Returns all data associated with a poly (points, boundings)""" + def get_poly(self, poly_idx: int): + """Returns all data associated with a poly (points, boundings)""" + return self.get_data().polys[poly_idx] - def get_poly(self, entry_idx: int = 0, poly_idx: int = 0) -> Container: - return self.get_data(entry_idx).polys[poly_idx] - """Returns a specific point in a poly""" + def get_point(self, poly_idx: int, point_idx: int) -> Container: + """Returns a specific point in a poly""" + return self.get_poly(poly_idx).points[point_idx] - def get_point(self, entry_idx: int = 0, poly_idx: int = 0, point_idx: int = 0) -> Container: - return self.get_poly(entry_idx, poly_idx).points[point_idx] - """Returns the total boundary of collision/collision_camera""" + def get_total_boundings(self) -> Container: + """Returns the total boundary of collision/collision_camera""" + return self.get_data().total_boundings - def get_total_boundings(self, entry_idx: int = 0) -> Container: - return self.get_data(entry_idx).total_boundings - """Returns the boundary of a poly""" + def get_poly_boundings(self, poly_idx: int) -> Container: + """Returns the boundary of a poly""" + return self.get_poly(poly_idx).boundings + + +class Bmscc(BaseResource): + @classmethod + def construct_class(cls, target_game: Game) -> Construct: + return BMSCC - def get_poly_boundings(self, entry_idx: int = 0, poly_idx: int = 0) -> Container: - return self.get_poly(entry_idx, poly_idx).boundings + def get_entry(self, entry_idx: int = 0) -> CollisionEntry: + return CollisionEntry(self.raw.layers[0].entries[entry_idx]) diff --git a/tests/formats/test_collision.py b/tests/formats/test_collision.py index 23773c1..34e9e66 100644 --- a/tests/formats/test_collision.py +++ b/tests/formats/test_collision.py @@ -100,21 +100,21 @@ def surface_bmscc(samus_returns_tree) -> Bmscc: def test_get_data(surface_bmscc: Bmscc): - data = surface_bmscc.get_data() + data = surface_bmscc.get_entry().get_data() assert len(data) == 5 def test_modifying_collision(surface_bmscc: Bmscc): - point = surface_bmscc.get_point(0, 2, 9) + point = surface_bmscc.get_entry().get_point(2, 9) assert point["x"] == -800.0 assert point["y"] == -7000.0 def test_get_boundings(surface_bmscc: Bmscc): - total_boundings = surface_bmscc.get_total_boundings() - polys = surface_bmscc.get_data().polys + total_boundings = surface_bmscc.get_entry().get_total_boundings() + polys = surface_bmscc.get_entry().get_data().polys for i, poly in enumerate(polys): - poly_boundings = surface_bmscc.get_poly_boundings(0, i) + poly_boundings = surface_bmscc.get_entry().get_poly_boundings(i) # Boundings for polygons are in the order: x1, y1, x2, y2 # Assert that the boundings are confined within the total bounds of the collision_camera assert poly_boundings[0] >= total_boundings[0] From ce26f98c123b3134132f24a10afee47d9eb06c7e Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 23 Dec 2024 04:18:16 +0000 Subject: [PATCH 15/16] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/mercury_engine_data_structures/formats/bmscc.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/mercury_engine_data_structures/formats/bmscc.py b/src/mercury_engine_data_structures/formats/bmscc.py index 75f03a6..9c9fd3b 100644 --- a/src/mercury_engine_data_structures/formats/bmscc.py +++ b/src/mercury_engine_data_structures/formats/bmscc.py @@ -72,28 +72,23 @@ class CollisionEntry: def __init__(self, raw: Container): self._raw = raw - # Bmscc has an entry per collision_camera, Bmscd has one entry per file def get_data(self) -> Container: """Returns all data of collision/collision_camera""" return self._raw.data - def get_poly(self, poly_idx: int): """Returns all data associated with a poly (points, boundings)""" return self.get_data().polys[poly_idx] - def get_point(self, poly_idx: int, point_idx: int) -> Container: """Returns a specific point in a poly""" return self.get_poly(poly_idx).points[point_idx] - def get_total_boundings(self) -> Container: """Returns the total boundary of collision/collision_camera""" return self.get_data().total_boundings - def get_poly_boundings(self, poly_idx: int) -> Container: """Returns the boundary of a poly""" return self.get_poly(poly_idx).boundings From a58f6414119e7b4a77890557ceaccfc0e4c8d9ad Mon Sep 17 00:00:00 2001 From: dyceron Date: Sun, 22 Dec 2024 23:19:10 -0500 Subject: [PATCH 16/16] Move comment --- src/mercury_engine_data_structures/formats/bmscc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mercury_engine_data_structures/formats/bmscc.py b/src/mercury_engine_data_structures/formats/bmscc.py index 9c9fd3b..31a4d11 100644 --- a/src/mercury_engine_data_structures/formats/bmscc.py +++ b/src/mercury_engine_data_structures/formats/bmscc.py @@ -72,7 +72,6 @@ class CollisionEntry: def __init__(self, raw: Container): self._raw = raw - # Bmscc has an entry per collision_camera, Bmscd has one entry per file def get_data(self) -> Container: """Returns all data of collision/collision_camera""" return self._raw.data @@ -99,5 +98,6 @@ class Bmscc(BaseResource): def construct_class(cls, target_game: Game) -> Construct: return BMSCC + # Bmscc has an entry per collision_camera, Bmscd has one entry per file def get_entry(self, entry_idx: int = 0) -> CollisionEntry: return CollisionEntry(self.raw.layers[0].entries[entry_idx])