Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
3 changes: 2 additions & 1 deletion 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 Down Expand Up @@ -38,7 +39,7 @@ def add_icon(
icon.uSpriteCol = uSpriteCol
icon.sDisabledIconId = sDisabledIconId
icon.sInspectorLabel = sInspectorLabel
icon.vAnchorOffset = list(vAnchorOffset)
icon.vAnchorOffset = Vec2(*vAnchorOffset)
Copy link
Contributor

Choose a reason for hiding this comment

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

should probably just make this take a Vec2 as the argument

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
20 changes: 5 additions & 15 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,12 +167,6 @@ 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):
return None
return ValueError(f"Invalid CVector{length}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
23 changes: 12 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,10 @@ 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", ["foo", "bar"], TypeError("Expected Vec2; got list")),
("base::math::CVector2D", [0.0], TypeError("Expected Vec2; got list")),
("base::math::CVector3D", [0.0], TypeError("Expected Vec3; got list")),
("base::math::CVector4D", [0.0], TypeError("Expected Vec4; got list")),
Copy link
Contributor

Choose a reason for hiding this comment

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

likewise, add test cases where you pass a Vec3 and a Vec4 to a Vec2 field and ensure they error

# struct
(
"base::reflection::CType",
Expand Down Expand Up @@ -156,7 +157,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