Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions src/mercury_engine_data_structures/formats/bmmdef.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from construct import Construct, Container

from mercury_engine_data_structures.base_resource import BaseResource
from mercury_engine_data_structures.common_types import Vec2
from mercury_engine_data_structures.formats import standard_format

if TYPE_CHECKING:
Expand All @@ -29,16 +30,19 @@ def add_icon(
uSpriteCol: int,
sInspectorLabel: str,
sDisabledIconId: str = "",
vAnchorOffset: tuple[int, int] = (0, 0),
vAnchorOffset: Vec2 | None = None,
bAutoScale: bool = True,
**kwargs,
):
if vAnchorOffset is None:
vAnchorOffset = Vec2(0.0, 0.0)

icon = Container()
icon.uSpriteRow = uSpriteRow
icon.uSpriteCol = uSpriteCol
icon.sDisabledIconId = sDisabledIconId
icon.sInspectorLabel = sInspectorLabel
icon.vAnchorOffset = list(vAnchorOffset)
icon.vAnchorOffset = vAnchorOffset
icon.bAutoScale = bAutoScale
for k, v in kwargs.items():
icon[k] = v
Expand Down
7 changes: 1 addition & 6 deletions src/mercury_engine_data_structures/formats/bmsad.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
CVector3D,
Float,
StrId,
Vec3,
VersionAdapter,
make_dict,
make_vector,
Expand Down Expand Up @@ -500,7 +501,6 @@ def __set__(self, inst: ActorDefFunc, value: T):
inst.set_param(self.index, value)


Vec3 = list
FieldType = bool | str | float | int | Vec3


Expand All @@ -523,11 +523,6 @@ def _set_extra_field(self, fields: Container, name: str, value: FieldType) -> No
elif isinstance(value, float):
type_ = "float"
elif isinstance(value, Vec3):
err = f"Invalid Vec3 {name}: {value}"
if len(value) != 3:
raise ValueError(err)
if not all(isinstance(v, float) for v in value):
raise TypeError(err)
type_ = "vec3"

fields[name].type = type_
Expand Down
23 changes: 10 additions & 13 deletions src/mercury_engine_data_structures/type_lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

import construct

from mercury_engine_data_structures.common_types import Vec2, Vec3, Vec4

if TYPE_CHECKING:
from mercury_engine_data_structures.game_check import Game
from mercury_engine_data_structures.pointer_set import PointerSet
Expand Down Expand Up @@ -118,9 +120,9 @@ class PrimitiveKind(Enum):
PrimitiveKind.UINT_16: int,
PrimitiveKind.UINT_64: int,
PrimitiveKind.FLOAT: float,
PrimitiveKind.VECTOR_2: typing.Sequence,
PrimitiveKind.VECTOR_3: typing.Sequence,
PrimitiveKind.VECTOR_4: typing.Sequence,
PrimitiveKind.VECTOR_2: Vec2,
PrimitiveKind.VECTOR_3: Vec3,
PrimitiveKind.VECTOR_4: Vec4,
PrimitiveKind.BYTES: bytes,
PrimitiveKind.PROPERTY: str | int,
}
Expand All @@ -133,12 +135,6 @@ class PrimitiveKind(Enum):
PrimitiveKind.PROPERTY: (0, 2**64 - 1),
}

primitive_vector_lengths = {
PrimitiveKind.VECTOR_2: 2,
PrimitiveKind.VECTOR_3: 3,
PrimitiveKind.VECTOR_4: 4,
}


@dataclasses.dataclass(frozen=True)
class PrimitiveType(BaseType):
Expand Down Expand Up @@ -171,11 +167,12 @@ def _find_type_errors(self, __value: typing.Any) -> BaseException | None:
return None
return ValueError(f"{__value} is out of range of [{hex(low)}, {hex(high)}]")

if self.primitive_kind in primitive_vector_lengths:
length = primitive_vector_lengths[self.primitive_kind]
if len(__value) == length and all(isinstance(v, float) for v in __value):
if isinstance(__value, Vec2):
if type(__value) is primitive_to_type[self.primitive_kind] and all(
isinstance(v, float) for v in __value.raw
):
return None
return ValueError(f"Invalid CVector{length}D: {__value}")
return ValueError(f"Invalid CVector{self.primitive_kind.name[-1]}D: {__value}")

return None
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you should keep this length check, since isinstance(Vec4(0.0, 0.0, 0.0, 0.0), Vec2) is true. the float check isn't strictly necessary but doesn't hurt

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want that to explicitly fail? Shouldn't you be using type(Vec4(0.0, 0.0, 0.0, 0.0)) is Vec2 if you want to exclude subclasses?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you could you use that instead of this length check if you prefer. still needs to be a special case tho


Expand Down
29 changes: 18 additions & 11 deletions tests/test_type_lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import pytest

from mercury_engine_data_structures.common_types import Vec2, Vec3, Vec4
from mercury_engine_data_structures.formats import dread_types
from mercury_engine_data_structures.game_check import Game
from mercury_engine_data_structures.type_lib import TypeLib, get_type_lib_for_game
Expand Down Expand Up @@ -31,9 +32,9 @@ def _dread_type_lib():
("unsigned_int", 2**32 - 1, None),
("unsigned_long", 2**64 - 1, None),
("float", 0.0, None),
("base::math::CVector2D", [0.0, 0.0], None),
("base::math::CVector3D", [0.0, 0.0, 0.0], None),
("base::math::CVector4D", [0.0, 0.0, 0.0, 0.0], None),
("base::math::CVector2D", Vec2(0.0, 0.0), None),
("base::math::CVector3D", Vec3(0.0, 0.0, 0.0), None),
("base::math::CVector4D", Vec4(0.0, 0.0, 0.0, 0.0), None),
("base::global::CRntFile", b"\x24\x03", None),
("base::global::CName", "", None),
("base::global::CName", 2**64 - 1, None),
Expand All @@ -44,9 +45,9 @@ def _dread_type_lib():
("unsigned_int", None, TypeError("Expected int; got NoneType")),
("unsigned_long", None, TypeError("Expected int; got NoneType")),
("float", None, TypeError("Expected float; got NoneType")),
("base::math::CVector2D", None, TypeError("Expected typing.Sequence; got NoneType")),
("base::math::CVector3D", None, TypeError("Expected typing.Sequence; got NoneType")),
("base::math::CVector4D", None, TypeError("Expected typing.Sequence; got NoneType")),
("base::math::CVector2D", None, TypeError("Expected Vec2; got NoneType")),
("base::math::CVector3D", None, TypeError("Expected Vec3; got NoneType")),
("base::math::CVector4D", None, TypeError("Expected Vec4; got NoneType")),
("base::global::CRntFile", None, TypeError("Expected bytes; got NoneType")),
("base::global::CName", None, TypeError("Expected str | int; got NoneType")),
("base::global::CName", None, TypeError("Expected str | int; got NoneType")),
Expand All @@ -56,10 +57,16 @@ def _dread_type_lib():
("unsigned_int", 2**32, ValueError("4294967296 is out of range of [0x0, 0xffffffff]")),
("unsigned_long", 2**64, ValueError("18446744073709551616 is out of range of [0x0, 0xffffffffffffffff]")),
("base::global::CName", -1, ValueError("-1 is out of range of [0x0, 0xffffffffffffffff]")),
("base::math::CVector2D", ["foo", "bar"], ValueError("Invalid CVector2D: ['foo', 'bar']")),
("base::math::CVector2D", [0.0], ValueError("Invalid CVector2D: [0.0]")),
("base::math::CVector3D", [0.0], ValueError("Invalid CVector3D: [0.0]")),
("base::math::CVector4D", [0.0], ValueError("Invalid CVector4D: [0.0]")),
("base::math::CVector2D", Vec2("foo", "bar"), ValueError("Invalid CVector2D: Vec2('foo', 'bar')")),
(
"base::math::CVector3D",
Vec3("foo", "bar", "baz"),
ValueError("Invalid CVector3D: Vec3('foo', 'bar', 'baz')"),
),
("base::math::CVector2D", Vec3(0.0, 0.0, 0.0), ValueError("Invalid CVector2D: Vec3(0.0, 0.0, 0.0)")),
("base::math::CVector2D", Vec4(0.0, 0.0, 0.0, 0.0), ValueError("Invalid CVector2D: Vec4(0.0, 0.0, 0.0, 0.0)")),
("base::math::CVector3D", Vec2(0.0, 0.0), TypeError("Expected Vec3; got Vec2")),
("base::math::CVector4D", Vec2(0.0, 0.0), TypeError("Expected Vec4; got Vec2")),
# struct
(
"base::reflection::CType",
Expand Down Expand Up @@ -156,7 +163,7 @@ def _dread_type_lib():
{
"@type": "game::logic::collision::CCircleShape2D",
"@value": {
"vPos": [0.0, 0.0, 0.0],
"vPos": Vec3(0.0, 0.0, 0.0),
"bIsSolid": False,
"fRadius": 1.0,
},
Expand Down
Loading