diff --git a/.codeclimate.yml b/.codeclimate.yml index 6b2a2d79..ae90f11d 100644 --- a/.codeclimate.yml +++ b/.codeclimate.yml @@ -31,6 +31,11 @@ checks: return-statements: enabled: false + + exclude_patterns: - "tests/**" - ".github/**" + # The scripts directory is only there to provide quick scripts to generate things that are in the actual code + # They don't need testing as they are not meant to be used outside the developpment process + - "scripts/**" diff --git a/changes/285.internal.2.md b/changes/285.internal.2.md index 7969f33c..e1798d49 100644 --- a/changes/285.internal.2.md +++ b/changes/285.internal.2.md @@ -6,7 +6,7 @@ - `serialize_to(buf: Buffer)`: Abstract method to write the object to a `Buffer`. - `validate()`: Validates the object's attributes; can be overridden for custom validation. - `deserialize(cls, buf: Buffer) -> Self`: Abstract method to construct the object from a `Buffer`. - - **Note**: Use the `dataclass` decorator when adding parameters to subclasses. + - **Note**: Use the :func:`attrs.define` decorator when adding parameters to subclasses. - Exemple: diff --git a/changes/297.feature.md b/changes/297.feature.md new file mode 100644 index 00000000..a464425a --- /dev/null +++ b/changes/297.feature.md @@ -0,0 +1,17 @@ +- Added more types to the implementation: + + - `Angle`: Represents an angle. + - `BitSet`: Represents a set of bits of variable length. + - `FixedBitSet`: Represents a set of bits of fixed length. + - `TextComponent`: Represents a Minecraft text component. + - Renamed `ChatMessage` to `JSONTextComponent`. + - `Identifier`: Represents a Minecraft identifier. + - `Quaternion`: Represents a quaternion. + - `Slot`: Represents an item slot. + - `Vec3`: Represents a 3D vector. + - `Position`: Represents a position with packed integers. + - `EntityMetadata`: Represents metadata for an entity. + > There are **A LOT** of different entity metadata types, so I'm not going to list them all here. + +- Removed the `validate` method from most `Serializable` classes. + - Make use of validators and convertors from the `attrs` library instead. diff --git a/docs/api/types/entity_metadata.rst b/docs/api/types/entity_metadata.rst new file mode 100644 index 00000000..9c337ee6 --- /dev/null +++ b/docs/api/types/entity_metadata.rst @@ -0,0 +1,10 @@ +Entity Metadata +====================== + +This is the documentation for the Entity Metadata types used in Minecraft's network protocol. + + + + +.. automodule:: mcproto.types.entity + :no-undoc-members: diff --git a/docs/api/types/general.rst b/docs/api/types/general.rst new file mode 100644 index 00000000..7d8c3bde --- /dev/null +++ b/docs/api/types/general.rst @@ -0,0 +1,11 @@ +General Types +====================== + +Here are documented the general types used throughout the Minecraft protocol. + +.. automodule:: mcproto.types + :no-undoc-members: + :exclude-members: NBTag, StringNBT, CompoundNBT, EndNBT, EntityMetadata, UUID + + .. autoclass:: mcproto.types.UUID + :class-doc-from: class diff --git a/docs/api/types/index.rst b/docs/api/types/index.rst index f17972a8..ec9a8d54 100644 --- a/docs/api/types/index.rst +++ b/docs/api/types/index.rst @@ -1,12 +1,13 @@ -.. api/types documentation master file +.. Types Documentation -======================= -API Types Documentation -======================= +Types Documentation +================================== -Welcome to the API Types documentation! This documentation provides information about the various types used in the API. +This folder contains the documentation for various types used in the project. .. toctree:: :maxdepth: 2 + general.rst nbt.rst + entity_metadata.rst diff --git a/docs/api/types/nbt.rst b/docs/api/types/nbt.rst index e2a4398b..748d536f 100644 --- a/docs/api/types/nbt.rst +++ b/docs/api/types/nbt.rst @@ -1,6 +1,9 @@ NBT Format ========== +This is the documentation for the NBT type used in Minecraft's network protocol. + + .. automodule:: mcproto.types.nbt :members: :show-inheritance: diff --git a/docs/conf.py b/docs/conf.py index 297169d3..7898caeb 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -12,10 +12,13 @@ import datetime import sys from pathlib import Path +from typing import Any from packaging.version import parse as parse_version from typing_extensions import override +from mcproto.types.entity.metadata import DefaultEntityMetadataEntryDeclaration, ProxyEntityMetadataEntryDeclaration + if sys.version_info >= (3, 11): from tomllib import load as toml_parse else: @@ -117,6 +120,19 @@ "exclude-members": "__dict__,__weakref__", } + +def autodoc_skip_member(app: Any, what: str, name: str, obj: Any, skip: bool, options: Any) -> bool: + """Skip EntityMetadataEntry class fields as they are already documented in the docstring.""" + if isinstance(obj, (DefaultEntityMetadataEntryDeclaration, ProxyEntityMetadataEntryDeclaration)): + return True + return skip + + +def setup(app: Any) -> None: + """Set up the Sphinx app.""" + app.connect("autodoc-skip-member", autodoc_skip_member) + + # -- sphinx.ext.autosectionlabel --------------- # Automatically generate section labels: diff --git a/docs/pages/installation.rst b/docs/pages/installation.rst index 3515936b..677482ae 100644 --- a/docs/pages/installation.rst +++ b/docs/pages/installation.rst @@ -17,7 +17,7 @@ Latest (git) version Alternatively, you may want to install the latest available version, which is what you currently see in the ``main`` git branch. Although this method will actually work for any branch with a pretty straightforward change. This kind of -installation should only be done when testing new feautes, and it's likely you'll encounter bugs. +installation should only be done when testing new features, and it's likely you'll encounter bugs. That said, since mcproto is still in development, changes can often be made pretty quickly, and it can sometimes take a while for these changes to carry over to PyPI. So if you really want to try out that latest feature, this is the method diff --git a/mcproto/multiplayer.py b/mcproto/multiplayer.py index 752f7d14..08688938 100644 --- a/mcproto/multiplayer.py +++ b/mcproto/multiplayer.py @@ -140,7 +140,7 @@ def compute_server_hash(server_id: str, shared_secret: bytes, server_public_key: need to know the encryption key (``shared_secret``). A proxy can capture this key, as the client sends it over to the server in :class:`~mcproto.packets.login.login.LoginEncryptionResponse` packet, however it is sent encrypted. The client performs this encryption with a public key, which it got - from the server, in :class:`mcproto.packets.login.login.LoginEncryptionRequest` packet. + from the server, in :class:`~mcproto.packets.login.login.LoginEncryptionRequest` packet. That mans that for a proxy to be able to actually obtain this shared secret value, it would need to be able to capture the encryption response, and decrypt the shared secret value. That means it would diff --git a/mcproto/packets/handshaking/handshake.py b/mcproto/packets/handshaking/handshake.py index 7d96958d..01fbb52b 100644 --- a/mcproto/packets/handshaking/handshake.py +++ b/mcproto/packets/handshaking/handshake.py @@ -1,7 +1,7 @@ from __future__ import annotations from enum import IntEnum -from typing import ClassVar, cast, final +from typing import ClassVar, final from attrs import define from typing_extensions import Self, override @@ -42,19 +42,11 @@ class Handshake(ServerBoundPacket): protocol_version: int server_address: str server_port: int - next_state: NextState | int - - @override - def __attrs_post_init__(self) -> None: - if not isinstance(self.next_state, NextState): - self.next_state = NextState(self.next_state) - - super().__attrs_post_init__() + next_state: NextState @override def serialize_to(self, buf: Buffer) -> None: """Serialize the packet.""" - self.next_state = cast(NextState, self.next_state) # Handled by the __attrs_post_init__ method buf.write_varint(self.protocol_version) buf.write_utf(self.server_address) buf.write_value(StructFormat.USHORT, self.server_port) @@ -67,12 +59,5 @@ def _deserialize(cls, buf: Buffer, /) -> Self: protocol_version=buf.read_varint(), server_address=buf.read_utf(), server_port=buf.read_value(StructFormat.USHORT), - next_state=buf.read_varint(), + next_state=NextState(buf.read_varint()), ) - - @override - def validate(self) -> None: - if not isinstance(self.next_state, NextState): - rev_lookup = {x.value: x for x in NextState.__members__.values()} - if self.next_state not in rev_lookup: - raise ValueError("No such next_state.") diff --git a/mcproto/packets/login/login.py b/mcproto/packets/login/login.py index 63557fc4..22cd7e6f 100644 --- a/mcproto/packets/login/login.py +++ b/mcproto/packets/login/login.py @@ -2,7 +2,7 @@ from typing import ClassVar, cast, final -from attrs import define +from attrs import define, field from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives.asymmetric.rsa import RSAPublicKey from cryptography.hazmat.primitives.serialization import Encoding, PublicFormat, load_der_public_key @@ -10,7 +10,7 @@ from mcproto.buffer import Buffer from mcproto.packets.packet import ClientBoundPacket, GameState, ServerBoundPacket -from mcproto.types.chat import ChatMessage +from mcproto.types.chat import JSONTextComponent from mcproto.types.uuid import UUID __all__ = [ @@ -33,7 +33,8 @@ class LoginStart(ServerBoundPacket): Initialize the LoginStart packet. :param username: Username of the client who sent the request. - :param uuid: UUID of the player logging in (if the player doesn't have a UUID, this can be ``None``) + :param uuid: UUID of the player logging in (unused by the server) + :type uuid: :class:`~mcproto.types.UUID` """ PACKET_ID: ClassVar[int] = 0x00 @@ -70,16 +71,9 @@ class LoginEncryptionRequest(ClientBoundPacket): PACKET_ID: ClassVar[int] = 0x01 GAME_STATE: ClassVar[GameState] = GameState.LOGIN - public_key: RSAPublicKey - verify_token: bytes - server_id: str | None = None - - @override - def __attrs_post_init__(self) -> None: - if self.server_id is None: - self.server_id = " " * 20 - - super().__attrs_post_init__() + public_key: RSAPublicKey = field() + verify_token: bytes = field() + server_id: str | None = field(default=" " * 20) @override def serialize_to(self, buf: Buffer) -> None: @@ -143,7 +137,9 @@ class LoginSuccess(ClientBoundPacket): Initialize the LoginSuccess packet. :param uuid: The UUID of the connecting player/client. + :type uuid: :class:`~mcproto.types.UUID` :param username: The username of the connecting player/client. + :type username: str """ PACKET_ID: ClassVar[int] = 0x02 @@ -178,7 +174,7 @@ class LoginDisconnect(ClientBoundPacket): PACKET_ID: ClassVar[int] = 0x00 GAME_STATE: ClassVar[GameState] = GameState.LOGIN - reason: ChatMessage + reason: JSONTextComponent @override def serialize_to(self, buf: Buffer) -> None: @@ -187,7 +183,7 @@ def serialize_to(self, buf: Buffer) -> None: @override @classmethod def _deserialize(cls, buf: Buffer, /) -> Self: - reason = ChatMessage.deserialize(buf) + reason = JSONTextComponent.deserialize(buf) return cls(reason) @@ -240,7 +236,7 @@ class LoginPluginResponse(ServerBoundPacket): GAME_STATE: ClassVar[GameState] = GameState.LOGIN message_id: int - data: bytes | None + data: bytes | None = None @override def serialize_to(self, buf: Buffer) -> None: diff --git a/mcproto/packets/status/status.py b/mcproto/packets/status/status.py index 2bebe15b..a3dabd07 100644 --- a/mcproto/packets/status/status.py +++ b/mcproto/packets/status/status.py @@ -3,7 +3,7 @@ import json from typing import Any, ClassVar, final -from attrs import define +from attrs import Attribute, define, field from typing_extensions import Self, override from mcproto.buffer import Buffer @@ -43,7 +43,12 @@ class StatusResponse(ClientBoundPacket): PACKET_ID: ClassVar[int] = 0x00 GAME_STATE: ClassVar[GameState] = GameState.STATUS - data: dict[str, Any] # JSON response data sent back to the client. + data: dict[str, Any] = field() + + @data.validator # pyright: ignore + def _validate_data(self, _: Attribute[dict[str, Any]], value: dict[str, Any]) -> None: + """Dump the data as json to check if it's valid.""" + json.dumps(value) @override def serialize_to(self, buf: Buffer) -> None: @@ -56,11 +61,3 @@ def _deserialize(cls, buf: Buffer, /) -> Self: s = buf.read_utf() data_ = json.loads(s) return cls(data_) - - @override - def validate(self) -> None: - # Ensure the data is serializable to JSON - try: - json.dumps(self.data) - except TypeError as exc: - raise ValueError("Data is not serializable to JSON.") from exc diff --git a/mcproto/types/__init__.py b/mcproto/types/__init__.py index 9d48db4f..48d76b3f 100644 --- a/mcproto/types/__init__.py +++ b/mcproto/types/__init__.py @@ -1 +1,111 @@ from __future__ import annotations + +from mcproto.types.abc import MCType, Serializable +from mcproto.types.advancement import ( + Advancement, + AdvancementCriterion, + AdvancementDisplay, + AdvancementFrame, + AdvancementProgress, +) +from mcproto.types.angle import Angle +from mcproto.types.bitset import Bitset, FixedBitset +from mcproto.types.block_entity import BlockEntity +from mcproto.types.chat import JSONTextComponent, TextComponent +from mcproto.types.entity import EntityMetadata +from mcproto.types.identifier import Identifier +from mcproto.types.map_icon import IconType, MapIcon +from mcproto.types.modifier import ModifierData, ModifierOperation +from mcproto.types.nbt import CompoundNBT, NBTag +from mcproto.types.particle_data import ParticleData +from mcproto.types.quaternion import Quaternion +from mcproto.types.recipe import ( + ArmorDyeRecipe, + BannerDuplicateRecipe, + BlastingRecipe, + BookCloningRecipe, + CampfireRecipe, + DecoratedPotRecipe, + FireworkRocketRecipe, + FireworkStarFadeRecipe, + FireworkStarRecipe, + Ingredient, + MapCloningRecipe, + MapExtendingRecipe, + Recipe, + RepairItemRecipe, + ShapedRecipe, + ShapelessRecipe, + ShieldDecorationRecipe, + ShulkerBoxColoringRecipe, + SmeltingRecipe, + SmithingTransformRecipe, + SmithingTrimRecipe, + SmokingRecipe, + StoneCuttingRecipe, + SuspiciousStewRecipe, + TippedArrowRecipe, +) +from mcproto.types.registry_tag import RegistryTag +from mcproto.types.slot import Slot, SlotData +from mcproto.types.trade import Trade +from mcproto.types.uuid import UUID +from mcproto.types.vec3 import Position, Vec3 + +__all__ = [ + "MCType", + "Serializable", + "Angle", + "Bitset", + "FixedBitset", + "JSONTextComponent", + "TextComponent", + "Identifier", + "NBTag", + "CompoundNBT", + "Quaternion", + "Slot", + "SlotData", + "RegistryTag", + "UUID", + "Position", + "Vec3", + "ParticleData", + "BlockEntity", + "MapIcon", + "IconType", + "Trade", + "EntityMetadata", + "Advancement", + "AdvancementProgress", + "AdvancementDisplay", + "AdvancementCriterion", + "AdvancementFrame", + "ModifierData", + "ModifierOperation", + "Recipe", + "ArmorDyeRecipe", + "BannerDuplicateRecipe", + "BlastingRecipe", + "BookCloningRecipe", + "ShulkerBoxColoringRecipe", + "CampfireRecipe", + "ShapedRecipe", + "DecoratedPotRecipe", + "FireworkRocketRecipe", + "MapCloningRecipe", + "MapExtendingRecipe", + "RepairItemRecipe", + "ShapelessRecipe", + "ShieldDecorationRecipe", + "SmokingRecipe", + "FireworkStarRecipe", + "FireworkStarFadeRecipe", + "Ingredient", + "SmeltingRecipe", + "SmithingTransformRecipe", + "SmithingTrimRecipe", + "TippedArrowRecipe", + "StoneCuttingRecipe", + "SuspiciousStewRecipe", +] diff --git a/mcproto/types/advancement.py b/mcproto/types/advancement.py new file mode 100644 index 00000000..0603c627 --- /dev/null +++ b/mcproto/types/advancement.py @@ -0,0 +1,194 @@ +from __future__ import annotations + +from enum import IntEnum +from typing import final + +from attrs import define +from typing_extensions import override + +from mcproto.buffer import Buffer +from mcproto.protocol import StructFormat +from mcproto.types.abc import MCType +from mcproto.types.chat import TextComponent +from mcproto.types.identifier import Identifier +from mcproto.types.slot import Slot + + +@final +@define +class Advancement(MCType): + """Represents an advancement in the game. + + Non-standard type, see: `` + + :param parent: The parent advancement. + :type parent: :class:`~mcproto.types.identifier.Identifier`, optional + :param display: The display information. + :type display: :class:`AdvancementDisplay`, optional + :param requirements: The criteria for this advancement. + :type requirements: list[list[str]] + :param telemetry: Whether to send telemetry data. + :type telemetry: bool + """ + + parent: Identifier | None + display: AdvancementDisplay | None + requirements: list[list[str]] + telemetry: bool + + @override + def serialize_to(self, buf: Buffer) -> None: + buf.write_optional(self.parent, lambda x: x.serialize_to(buf)) + buf.write_optional(self.display, lambda x: x.serialize_to(buf)) + buf.write_varint(len(self.requirements)) + for requirement in self.requirements: + buf.write_varint(len(requirement)) + for criterion in requirement: + buf.write_utf(criterion) + buf.write_value(StructFormat.BOOL, self.telemetry) + + @override + @classmethod + def deserialize(cls, buf: Buffer) -> Advancement: + parent = buf.read_optional(lambda: Identifier.deserialize(buf)) + display = buf.read_optional(lambda: AdvancementDisplay.deserialize(buf)) + requirements = [[buf.read_utf() for _ in range(buf.read_varint())] for _ in range(buf.read_varint())] + telemetry = buf.read_value(StructFormat.BOOL) + return cls(parent=parent, display=display, requirements=requirements, telemetry=telemetry) + + +class AdvancementFrame(IntEnum): + """Represents the shape of the frame of an advancement in the GUI.""" + + TASK = 0 + CHALLENGE = 1 + GOAL = 2 + + +@final +@define +class AdvancementDisplay(MCType): + """Describes how an advancement should look. + + :param title: The title of the advancement. + :type title: :class:`~mcproto.types.chat.TextComponent` + :param description: The description of the advancement. + :type description: :class:`~mcproto.types.chat.TextComponent` + :param icon: The icon of the advancement. + :type icon: :class:`~mcproto.types.slot.Slot` + :param frame: The frame of the advancement. + :type frame: :class:`AdvancementFrame` + :param background: The background texture of the advancement. + :type background: :class:`~mcproto.types.identifier.Identifier`, optional + :param show_toast: Whether to show a toast notification. + :type show_toast: bool + :param hidden: Whether the advancement is hidden. + :type hidden: bool + :param x: The x-coordinate of the advancement (in the GUI). + :type x: float + :param y: The y-coordinate of the advancement (in the GUI). + :type y: float + """ + + title: TextComponent + description: TextComponent + icon: Slot + frame: AdvancementFrame + background: Identifier | None + show_toast: bool + hidden: bool + x: float + y: float + + @override + def serialize_to(self, buf: Buffer) -> None: + self.title.serialize_to(buf) + self.description.serialize_to(buf) + self.icon.serialize_to(buf) + buf.write_varint(self.frame.value) + + flags = (self.background is not None) << 0 | self.show_toast << 1 | self.hidden << 2 + buf.write_value(StructFormat.BYTE, flags) + if self.background is not None: + self.background.serialize_to(buf) + buf.write_value(StructFormat.FLOAT, self.x) + buf.write_value(StructFormat.FLOAT, self.y) + + @override + @classmethod + def deserialize(cls, buf: Buffer) -> AdvancementDisplay: + title = TextComponent.deserialize(buf) + description = TextComponent.deserialize(buf) + icon = Slot.deserialize(buf) + frame = AdvancementFrame(buf.read_varint()) + flags = buf.read_value(StructFormat.BYTE) + background = Identifier.deserialize(buf) if flags & 0x1 else None + show_toast = bool(flags & 0x2) + hidden = bool(flags & 0x4) + x = buf.read_value(StructFormat.FLOAT) + y = buf.read_value(StructFormat.FLOAT) + return cls( + title=title, + description=description, + icon=icon, + frame=frame, + background=background, + show_toast=show_toast, + hidden=hidden, + x=x, + y=y, + ) + + +@final +@define +class AdvancementProgress(MCType): + """Represents the progress of an advancement. + + :param criteria: The criteria for this advancement. + :type criteria: dict[:class:`~mcproto.types.identifier.Identifier`, :class:`AdvancementCriterion`] + """ + + criteria: dict[Identifier, AdvancementCriterion] + + @override + def serialize_to(self, buf: Buffer) -> None: + buf.write_varint(len(self.criteria)) + for identifier, criterion in self.criteria.items(): + identifier.serialize_to(buf) + criterion.serialize_to(buf) + + @override + @classmethod + def deserialize(cls, buf: Buffer) -> AdvancementProgress: + criteria = { + Identifier.deserialize(buf): AdvancementCriterion.deserialize(buf) for _ in range(buf.read_varint()) + } + return cls(criteria=criteria) + + +@final +@define +class AdvancementCriterion(MCType): + """Represents a criterion for an advancement. + + :param date: The date the criterion was achieved. (As returned by Date.getTime() in Java), None if not achieved. + :type date: int, optional + """ + + date: int | None = None + + @override + def serialize_to(self, buf: Buffer) -> None: + buf.write_optional(self.date, lambda x: buf.write_value(StructFormat.LONGLONG, x)) + + @override + @classmethod + def deserialize(cls, buf: Buffer) -> AdvancementCriterion: + date = buf.read_optional(lambda: buf.read_value(StructFormat.LONGLONG)) + return cls(date=date) + + @property + def achieved(self) -> bool: + """Whether the criterion was achieved.""" + return self.date is not None diff --git a/mcproto/types/angle.py b/mcproto/types/angle.py new file mode 100644 index 00000000..8e542650 --- /dev/null +++ b/mcproto/types/angle.py @@ -0,0 +1,74 @@ +from __future__ import annotations + +import math +from typing import final + +from attrs import define, field +from typing_extensions import override + +from mcproto.buffer import Buffer +from mcproto.protocol import StructFormat +from mcproto.types.abc import MCType +from mcproto.types.vec3 import Vec3 + + +@final +@define +class Angle(MCType): + """Represents a rotation angle for an entity. + + :param value: The angle value in 1/256th of a full rotation. + :type value: int + + .. note:: The angle is stored as a byte, so the value is in the range [0, 255]. + """ + + angle: int = field(converter=lambda x: int(x) % 256) + + @override + def serialize_to(self, buf: Buffer) -> None: + payload = int(self.angle) & 0xFF + # Convert to a signed byte. + if payload & 0x80: + payload -= 1 << 8 + buf.write_value(StructFormat.BYTE, payload) + + @override + @classmethod + def deserialize(cls, buf: Buffer) -> Angle: + payload = buf.read_value(StructFormat.BYTE) + return cls(angle=int(payload * 360 / 256)) + + def in_direction(self, base: Vec3, distance: float) -> Vec3: + """Calculate the position in the direction of the angle in the xz-plane. + + 0/256: Positive z-axis + 64/-192: Negative x-axis + 128/-128: Negative z-axis + 192/-64: Positive x-axis + + :param base: The base position. + :param distance: The distance to move. + :return: The new position. + """ + x = base.x - distance * math.sin(self.to_radians()) + z = base.z + distance * math.cos(self.to_radians()) + return Vec3(x=x, y=base.y, z=z) + + @classmethod + def from_degrees(cls, degrees: float) -> Angle: + """Create an angle from degrees.""" + return cls(angle=int(degrees * 256 / 360)) + + def to_degrees(self) -> float: + """Return the angle in degrees.""" + return self.angle * 360 / 256 + + @classmethod + def from_radians(cls, radians: float) -> Angle: + """Create an angle from radians.""" + return cls(angle=int(math.degrees(radians) * 256 / 360)) + + def to_radians(self) -> float: + """Return the angle in radians.""" + return math.radians(self.angle * 360 / 256) diff --git a/mcproto/types/bitset.py b/mcproto/types/bitset.py new file mode 100644 index 00000000..e51fb65e --- /dev/null +++ b/mcproto/types/bitset.py @@ -0,0 +1,206 @@ +from __future__ import annotations + +import math +from functools import lru_cache +from typing import ClassVar + +from attrs import Attribute, define, field, validators +from typing_extensions import override + +from mcproto.buffer import Buffer +from mcproto.protocol import StructFormat +from mcproto.protocol.utils import to_twos_complement +from mcproto.types.abc import MCType + + +@define +class FixedBitset(MCType): + """Represents a fixed-size bitset. + + The size of the bitset must be defined using the :meth:`of_size` method. + Each :class:`FixedBitset` class is unique to its size, and the size must be defined before using the class. + + :param data: The bits of the bitset. + """ + + __BIT_COUNT: ClassVar[int] = -1 + + data: bytearray = field() + + @data.validator # pyright: ignore + def _data_length_check(self: FixedBitset, attribute: Attribute[bytearray], value: bytearray) -> None: + """Check that the data length matches the bitset size. + + :raises ValueError: If the data length doesn't match the bitset size. + """ + if self.__BIT_COUNT == -1: + raise ValueError("Bitset size is not defined.") + if len(value) != math.ceil(self.__BIT_COUNT / 8): + raise ValueError(f"Bitset size is {self.__BIT_COUNT}, but data length is {len(value)}.") + + @override + def serialize_to(self, buf: Buffer) -> None: + buf.write(bytes(self.data)) + + @override + @classmethod + def deserialize(cls, buf: Buffer) -> FixedBitset: + if cls.__BIT_COUNT == -1: + raise ValueError("Bitset size is not defined.") + data = buf.read(math.ceil(cls.__BIT_COUNT / 8)) + return cls(data=data) + + @staticmethod + @lru_cache(maxsize=None) + def of_size(n: int) -> type[FixedBitset]: + """Return a new FixedBitset class with the given size. + + The result of this method is cached, so calling it multiple times with the same value will return the same + class. + + :param n: The size of the bitset. + """ + new_class = type(f"FixedBitset{n}", (FixedBitset,), {}) + new_class.__BIT_COUNT = n + return new_class + + @classmethod + def from_int(cls, n: int) -> FixedBitset: + """Return a new FixedBitset with the given integer value. + + :param n: The integer value. + """ + if cls.__BIT_COUNT == -1: + raise ValueError("Bitset size is not defined.") + data = bytearray(to_twos_complement(n, cls.__BIT_COUNT).to_bytes(math.ceil(cls.__BIT_COUNT / 8), "big")) + return cls(data=data) + + def __setitem__(self, index: int, value: bool) -> None: + byte_index = index // 8 + bit_index = index % 8 + if value: + self.data[byte_index] |= 1 << bit_index + else: + self.data[byte_index] &= ~(1 << bit_index) + + def __getitem__(self, index: int) -> bool: + byte_index = index // 8 + bit_index = index % 8 + return bool(self.data[byte_index] & (1 << bit_index)) + + def __len__(self) -> int: + return self.__BIT_COUNT + + def __and__(self, other: FixedBitset) -> FixedBitset: + if self.__BIT_COUNT != other.__BIT_COUNT: + raise ValueError("Bitsets must have the same size.") + return type(self)(data=bytearray(a & b for a, b in zip(self.data, other.data))) + + def __or__(self, other: FixedBitset) -> FixedBitset: + if self.__BIT_COUNT != other.__BIT_COUNT: + raise ValueError("Bitsets must have the same size.") + return type(self)(data=bytearray(a | b for a, b in zip(self.data, other.data))) + + def __xor__(self, other: FixedBitset) -> FixedBitset: + if self.__BIT_COUNT != other.__BIT_COUNT: + raise ValueError("Bitsets must have the same size.") + return type(self)(data=bytearray(a ^ b for a, b in zip(self.data, other.data))) + + def __invert__(self) -> FixedBitset: + return type(self)(data=bytearray(~a & 0xFF for a in self.data)) + + def __bytes__(self) -> bytes: + return bytes(self.data) + + @override + def __eq__(self, value: object) -> bool: + if not isinstance(value, FixedBitset): + return NotImplemented + return self.data == value.data and self.__BIT_COUNT == value.__BIT_COUNT + + +@define +class Bitset(MCType): + """Represents a length-prefixed bitset with a variable size. + + :param size: The number of longs in the array representing the bitset. + :param data: The bits of the bitset. + """ + + size: int = field(validator=validators.gt(0)) + data: list[int] = field() + + @data.validator # pyright: ignore + def _data_length_check(self: Bitset, attribute: Attribute[list[int]], value: list[int]) -> None: + """Check that the data length matches the bitset size. + + :raises ValueError: If the data length doesn't match the bitset size. + """ + if len(value) != self.size: + raise ValueError(f"Bitset size is {self.size}, but data length is {len(value)}.") + + @override + def serialize_to(self, buf: Buffer) -> None: + buf.write_varint(self.size) + for i in range(self.size): + buf.write_value(StructFormat.LONGLONG, self.data[i]) + + @override + @classmethod + def deserialize(cls, buf: Buffer) -> Bitset: + size = buf.read_varint() + data = [buf.read_value(StructFormat.LONGLONG) for _ in range(size)] + return cls(size=size, data=data) + + @classmethod + def from_int(cls, n: int, size: int | None = None) -> Bitset: + """Return a new Bitset with the given integer value. + + :param n: The integer value. + :param size: The number of longs in the array representing the bitset. + """ + if size is None: + size = math.ceil(n.bit_length() / 64.0) + + # Split the integer into 64-bit chunks (longlong array) + data = [n >> (i * 64) & 0xFFFFFFFFFFFFFFFF for i in range(size)] + return cls(size=size, data=data) + + def __getitem__(self, index: int) -> bool: + byte_index = index // 64 + bit_index = index % 64 + + return bool(self.data[byte_index] & (1 << bit_index)) + + def __setitem__(self, index: int, value: bool) -> None: + byte_index = index // 64 + bit_index = index % 64 + + if value: + self.data[byte_index] |= 1 << bit_index + else: + self.data[byte_index] &= ~(1 << bit_index) + + def __len__(self) -> int: + return self.size * 64 + + def __and__(self, other: Bitset) -> Bitset: + if self.size != other.size: + raise ValueError("Bitsets must have the same size.") + return Bitset(size=self.size, data=[a & b for a, b in zip(self.data, other.data)]) + + def __or__(self, other: Bitset) -> Bitset: + if self.size != other.size: + raise ValueError("Bitsets must have the same size.") + return Bitset(size=self.size, data=[a | b for a, b in zip(self.data, other.data)]) + + def __xor__(self, other: Bitset) -> Bitset: + if self.size != other.size: + raise ValueError("Bitsets must have the same size.") + return Bitset(size=self.size, data=[a ^ b for a, b in zip(self.data, other.data)]) + + def __invert__(self) -> Bitset: + return Bitset(size=self.size, data=[~a for a in self.data]) + + def __bytes__(self) -> bytes: + return b"".join(a.to_bytes(8, "big") for a in self.data) diff --git a/mcproto/types/block_entity.py b/mcproto/types/block_entity.py new file mode 100644 index 00000000..ebf2805e --- /dev/null +++ b/mcproto/types/block_entity.py @@ -0,0 +1,65 @@ +from __future__ import annotations + +from typing import final + +from attrs import Attribute, define, field +from typing_extensions import Self, override + +from mcproto.buffer import Buffer +from mcproto.protocol.base_io import StructFormat +from mcproto.types.abc import MCType +from mcproto.types.nbt import CompoundNBT +from mcproto.types.vec3 import Position + + +@final +@define +class BlockEntity(MCType): + """Represents a block entity (e.g. a chest, furnace, banner, etc.). + + :param position: The position of the block entity relative to its chunk. + :type position: Position + :param block_type: The type of the block entity. + :type block_type: int + :param nbt: The NBT data of the block entity. + :type nbt: CompoundNBT + + .. warning:: The position must be within the chunk. + .. note:: This class is used in the :class:`~mcproto.packets.play.ChunkData` packet. + """ + + position: Position = field() + block_type: int = field() + nbt: CompoundNBT = field() + + @position.validator # pyright: ignore + def _check_position(self: BlockEntity, attribute: Attribute[Position], value: Position) -> None: + """Check that the position is within the chunk. + + :raises ValueError: If the position is not within the chunk. + """ + if not (0 <= value.x < 16 and 0 <= value.z < 16): + raise ValueError("Position must be within the chunk") + + @override + def serialize_to(self, buf: Buffer) -> None: + x, y, z = int(self.position.x), int(self.position.y), int(self.position.z) + + # Write x and z packed together in a single byte + buf.write_value(StructFormat.UBYTE, ((x & 15) << 4) | (z & 15)) + buf.write_value(StructFormat.SHORT, y) + buf.write_varint(self.block_type) + self.nbt.serialize_to(buf, with_type=False, with_name=False) + + @override + @classmethod + def deserialize(cls, buf: Buffer) -> Self: + packed_xz = buf.read_value(StructFormat.UBYTE) + x = packed_xz >> 4 + z = packed_xz & 15 + y = buf.read_value(StructFormat.SHORT) + block_type = buf.read_varint() + nbt = CompoundNBT.deserialize( # TODO: Check if with_name=False is correct + buf, with_name=False, with_type=False + ) + return cls(Position(x, y, z), block_type, nbt) diff --git a/mcproto/types/chat.py b/mcproto/types/chat.py index 2c722fc3..b395f047 100644 --- a/mcproto/types/chat.py +++ b/mcproto/types/chat.py @@ -1,27 +1,30 @@ from __future__ import annotations import json -from typing import TypedDict, Union, final +from copy import deepcopy +from typing import TypedDict, Union, cast, final -from attrs import define +from attrs import Attribute, define, field, validators from typing_extensions import Self, TypeAlias, override from mcproto.buffer import Buffer from mcproto.types.abc import MCType +from mcproto.types.nbt import ByteNBT, FromObjectSchema, FromObjectType, NBTag, StringNBT __all__ = [ - "ChatMessage", - "RawChatMessage", - "RawChatMessageDict", + "TextComponent", + "RawTextComponentDict", + "RawTextComponent", + "JSONTextComponent", ] -class RawChatMessageDict(TypedDict, total=False): +class RawTextComponentDict(TypedDict, total=False): """Dictionary structure of JSON chat messages when serialized.""" text: str translation: str - extra: list[RawChatMessageDict] + extra: list[RawTextComponentDict] color: str bold: bool @@ -31,24 +34,42 @@ class RawChatMessageDict(TypedDict, total=False): obfuscated: bool -RawChatMessage: TypeAlias = Union[RawChatMessageDict, "list[RawChatMessageDict]", str] +RawTextComponent: TypeAlias = Union[RawTextComponentDict, "list[RawTextComponentDict]", str] -@final @define -class ChatMessage(MCType): +class JSONTextComponent(MCType): """Minecraft chat message representation.""" - raw: RawChatMessage + @staticmethod + def check_raw(_self: JSONTextComponent, _: Attribute[RawTextComponent], value: RawTextComponent) -> None: + """Check that the `raw` attribute is a valid JSON chat message. - __slots__ = ("raw",) + :raises AttributeError: If the `raw` attribute is not a valid JSON chat message (missing fields). + :raises TypeError: If the `raw` attribute is not a valid JSON chat message (wrong type). - def as_dict(self) -> RawChatMessageDict: + .. note:: This is a separate method to be able to use the isinstance check for the type. + """ + if isinstance(value, dict): # We want to keep it this way for readability + if "text" not in value and "extra" not in value: + raise AttributeError("Expected `raw` to have either 'text' or 'extra' key, got neither") + if isinstance(value, list): + for elem in value: + if not isinstance(elem, dict): # type: ignore[unreachable] + raise TypeError(f"Expected `raw` to be a list of dicts, got {elem!r} instead") + if "text" not in elem and "extra" not in elem: + raise AttributeError( + "Expected each element in `raw` to have either 'text' or 'extra' key, got neither" + ) + + raw: RawTextComponent = field(validator=[validators.instance_of((dict, list, str)), check_raw.__get__(object)]) + + def as_dict(self) -> RawTextComponentDict: """Convert received ``raw`` into a stadard :class:`dict` form.""" if isinstance(self.raw, list): - return RawChatMessageDict(extra=self.raw) + return RawTextComponentDict(extra=self.raw) if isinstance(self.raw, str): - return RawChatMessageDict(text=self.raw) + return RawTextComponentDict(text=self.raw) if isinstance(self.raw, dict): # pyright: ignore[reportUnnecessaryIsInstance] return self.raw @@ -61,10 +82,10 @@ def __eq__(self, other: object) -> bool: """Check equality between two chat messages. ..warning: This is purely using the `raw` field, which means it's possible that - a chat message that appears the same, but was representing in a different way + a chat message that appears the same, but was represented in a different way will fail this equality check. """ - if not isinstance(other, ChatMessage): + if not isinstance(other, JSONTextComponent): return NotImplemented return self.raw == other.raw @@ -81,18 +102,98 @@ def deserialize(cls, buf: Buffer, /) -> Self: dct = json.loads(txt) return cls(dct) + +@final +class TextComponent(JSONTextComponent): + """Minecraft chat message representation. + + This class provides the new chat message format using NBT data instead of JSON. + """ + + __slots__ = () + @override - def validate(self) -> None: - if not isinstance(self.raw, (dict, list, str)): # type: ignore[unreachable] - raise TypeError(f"Expected `raw` to be a dict, list or str, got {self.raw!r} instead") - if isinstance(self.raw, dict): # We want to keep it this way for readability - if "text" not in self.raw and "extra" not in self.raw: - raise AttributeError("Expected `raw` to have either 'text' or 'extra' key, got neither") - if isinstance(self.raw, list): - for elem in self.raw: - if not isinstance(elem, dict): # type: ignore[unreachable] - raise TypeError(f"Expected `raw` to be a list of dicts, got {elem!r} instead") - if "text" not in elem and "extra" not in elem: - raise AttributeError( - "Expected each element in `raw` to have either 'text' or 'extra' key, got neither" - ) + def serialize_to(self, buf: Buffer) -> None: + payload = self._convert_to_dict(self.raw) + payload = cast(FromObjectType, payload) # We just ensured that the data is converted to the correct format + nbt = NBTag.from_object(data=payload, schema=self._build_schema()) # This will validate the data + nbt.serialize_to(buf) + + @override + @classmethod + def deserialize(cls, buf: Buffer, /) -> Self: + nbt = NBTag.deserialize(buf, with_name=False) + # Ensure the schema is compatible with the one defined in the class + data, schema = cast("tuple[FromObjectType, FromObjectSchema]", nbt.to_object(include_schema=True)) + + TextComponent._recursive_validate(schema, cls._build_schema()) + data = cast(RawTextComponentDict, data) # We just ensured that the data is compatible with the schema + return cls(data) + + @staticmethod + def _build_schema() -> FromObjectSchema: + """Build the schema for the NBT data representing the chat message.""" + schema: FromObjectSchema = { + "text": StringNBT, + "color": StringNBT, + "bold": ByteNBT, + "italic": ByteNBT, + "underlined": ByteNBT, + "strikethrough": ByteNBT, + "obfuscated": ByteNBT, + } + # Allow the schema to be recursive + schema["extra"] = [schema] # type: ignore + return schema + + @staticmethod + def _recursive_validate(received: FromObjectSchema, expected: FromObjectSchema) -> None: + """Recursively validate the NBT data representing the chat message. + + .. note:: The expected schema is recursive so we don't want to iterate over it. + """ + if isinstance(received, dict): + if not isinstance(expected, dict): + raise TypeError(f"Expected {expected!r}, got dict") + received = cast("dict[str, FromObjectSchema]", received) + for key, value in received.items(): + if key not in expected: + raise KeyError(f"Unexpected key {key!r}") + expected_value = cast(FromObjectSchema, expected[key]) + TextComponent._recursive_validate(value, expected_value) + elif isinstance(received, list): + if not isinstance(expected, list): + raise TypeError(f"Expected {expected!r}, got list") + received = cast("list[FromObjectSchema]", received) + for rec in received: + expected_value = cast(FromObjectSchema, expected[0]) + TextComponent._recursive_validate(rec, expected_value) + elif received != expected: + raise TypeError(f"Expected {expected!r}, got {received!r}") + + @staticmethod + def _convert_to_dict(msg: RawTextComponent) -> RawTextComponentDict: + """Convert a chat message into a dictionary representation.""" + if isinstance(msg, str): + return {"text": msg} + + if isinstance(msg, list): + main = TextComponent._convert_to_dict(msg[0]) + if "extra" not in main: + main["extra"] = [] + for elem in msg[1:]: + main["extra"].append(TextComponent._convert_to_dict(elem)) + return main + + if isinstance(msg, dict): # pyright: ignore[reportUnnecessaryIsInstance] + return deepcopy(msg) + + raise TypeError(f"Unexpected type {msg!r} ({msg.__class__.__name__})") # pragma: no cover + + @override + def __eq__(self, other: object) -> bool: + if not isinstance(other, TextComponent): + return NotImplemented + self_dict = self._convert_to_dict(self.raw) + other_dict = self._convert_to_dict(other.raw) + return self_dict == other_dict diff --git a/mcproto/types/entity/__init__.py b/mcproto/types/entity/__init__.py new file mode 100644 index 00000000..04bde380 --- /dev/null +++ b/mcproto/types/entity/__init__.py @@ -0,0 +1,302 @@ +###################################################################### +# This file is automatically generated by the entity generator script. +# You can modify it by changing what you want in the script. +###################################################################### + +from mcproto.types.entity.enums import Direction, DragonPhase, Pose, SnifferState + +__all__ = [ + "AbstractArrowEM", + "AbstractFishEM", + "AbstractGolemEM", + "AbstractHorseEM", + "AbstractIllagerEM", + "AbstractMinecartContainerEM", + "AbstractMinecartEM", + "AbstractSkeletonEM", + "AbstractVehicleEM", + "AbstractVillagerEM", + "AgeableMobEM", + "AmbientCreatureEM", + "AnimalEM", + "AreaEffectCloudEM", + "ArmorStandEM", + "ArrowEM", + "AxolotlEM", + "BasePiglinEM", + "BatEM", + "BeeEM", + "BlazeEM", + "BlockDisplayEM", + "BoatEM", + "CamelEM", + "CatEM", + "ChestBoatEM", + "ChestedHorseEM", + "ChickenEM", + "CodEM", + "CowEM", + "CreeperEM", + "Direction", + "DisplayEM", + "DolphinEM", + "DonkeyEM", + "DragonFireballEM", + "DragonPhase", + "DrownedEM", + "ElderGuardianEM", + "EndCrystalEM", + "EnderDragonEM", + "EndermanEM", + "EndermiteEM", + "EntityEM", + "EntityMetadata", + "EvokerEM", + "EvokerFangsEM", + "EyeOfEnderEM", + "FallingBlockEM", + "FireballEM", + "FireworkRocketEM", + "FishingHookEM", + "FlyingEM", + "FoxEM", + "FrogEM", + "GhastEM", + "GiantEM", + "GlowingItemFrameEM", + "GoatEM", + "GuardianEM", + "HoglinEM", + "HorseEM", + "HuskEM", + "IllusionerEM", + "InteractionEM", + "IronGolemEM", + "ItemDisplayEM", + "ItemEntityEM", + "ItemFrameEM", + "LivingEntityEM", + "LlamaEM", + "LlamaSpitEM", + "MinecartChestEM", + "MinecartCommandBlockEM", + "MinecartEM", + "MinecartFurnaceEM", + "MinecartHopperEM", + "MinecartSpawnerEM", + "MinecartTNTEM", + "MobEM", + "MonsterEM", + "MooshroomEM", + "MuleEM", + "OcelotEM", + "PaintingEM", + "PandaEM", + "ParrotEM", + "PathfinderMobEM", + "PhantomEM", + "PigEM", + "PiglinBruteEM", + "PiglinEM", + "PillagerEM", + "PlayerEM", + "PolarBearEM", + "Pose", + "PrimedTntEM", + "PufferFishEM", + "RabbitEM", + "RaiderEM", + "RavagerEM", + "SalmonEM", + "SheepEM", + "ShulkerEM", + "SilverfishEM", + "SkeletonEM", + "SkeletonHorseEM", + "SlimeEM", + "SmallFireballEM", + "SnifferEM", + "SnifferState", + "SnowGolemEM", + "SpectralArrowEM", + "SpellcasterIllagerEM", + "SpiderEM", + "SquidEM", + "StrayEM", + "StriderEM", + "TadpoleEM", + "TameableAnimalEM", + "TextDisplayEM", + "ThrownEggEM", + "ThrownEnderPearlEM", + "ThrownExperienceBottleEM", + "ThrownItemProjectileEM", + "ThrownPotionEM", + "ThrownSnowballEM", + "ThrownTridentEM", + "TraderLlamaEM", + "TropicalFishEM", + "TurtleEM", + "VexEM", + "VillagerEM", + "VindicatorEM", + "WanderingTraderEM", + "WardenEM", + "WaterAnimalEM", + "WitchEM", + "WitherEM", + "WitherSkeletonEM", + "WitherSkullEM", + "WolfEM", + "ZoglinEM", + "ZombieEM", + "ZombieHorseEM", + "ZombieVillagerEM", + "ZombifiedPiglinEM", +] + +from mcproto.types.entity.generated import ( + AbstractArrowEM, + AbstractFishEM, + AbstractGolemEM, + AbstractHorseEM, + AbstractIllagerEM, + AbstractMinecartContainerEM, + AbstractMinecartEM, + AbstractSkeletonEM, + AbstractVehicleEM, + AbstractVillagerEM, + AgeableMobEM, + AmbientCreatureEM, + AnimalEM, + AreaEffectCloudEM, + ArmorStandEM, + ArrowEM, + AxolotlEM, + BasePiglinEM, + BatEM, + BeeEM, + BlazeEM, + BlockDisplayEM, + BoatEM, + CamelEM, + CatEM, + ChestBoatEM, + ChestedHorseEM, + ChickenEM, + CodEM, + CowEM, + CreeperEM, + DisplayEM, + DolphinEM, + DonkeyEM, + DragonFireballEM, + DrownedEM, + ElderGuardianEM, + EndCrystalEM, + EnderDragonEM, + EndermanEM, + EndermiteEM, + EntityEM, + EvokerEM, + EvokerFangsEM, + EyeOfEnderEM, + FallingBlockEM, + FireballEM, + FireworkRocketEM, + FishingHookEM, + FlyingEM, + FoxEM, + FrogEM, + GhastEM, + GiantEM, + GlowingItemFrameEM, + GoatEM, + GuardianEM, + HoglinEM, + HorseEM, + HuskEM, + IllusionerEM, + InteractionEM, + IronGolemEM, + ItemDisplayEM, + ItemEntityEM, + ItemFrameEM, + LivingEntityEM, + LlamaEM, + LlamaSpitEM, + MinecartChestEM, + MinecartCommandBlockEM, + MinecartEM, + MinecartFurnaceEM, + MinecartHopperEM, + MinecartSpawnerEM, + MinecartTNTEM, + MobEM, + MonsterEM, + MooshroomEM, + MuleEM, + OcelotEM, + PaintingEM, + PandaEM, + ParrotEM, + PathfinderMobEM, + PhantomEM, + PigEM, + PiglinBruteEM, + PiglinEM, + PillagerEM, + PlayerEM, + PolarBearEM, + PrimedTntEM, + PufferFishEM, + RabbitEM, + RaiderEM, + RavagerEM, + SalmonEM, + SheepEM, + ShulkerEM, + SilverfishEM, + SkeletonEM, + SkeletonHorseEM, + SlimeEM, + SmallFireballEM, + SnifferEM, + SnowGolemEM, + SpectralArrowEM, + SpellcasterIllagerEM, + SpiderEM, + SquidEM, + StrayEM, + StriderEM, + TadpoleEM, + TameableAnimalEM, + TextDisplayEM, + ThrownEggEM, + ThrownEnderPearlEM, + ThrownExperienceBottleEM, + ThrownItemProjectileEM, + ThrownPotionEM, + ThrownSnowballEM, + ThrownTridentEM, + TraderLlamaEM, + TropicalFishEM, + TurtleEM, + VexEM, + VillagerEM, + VindicatorEM, + WanderingTraderEM, + WardenEM, + WaterAnimalEM, + WitchEM, + WitherEM, + WitherSkeletonEM, + WitherSkullEM, + WolfEM, + ZoglinEM, + ZombieEM, + ZombieHorseEM, + ZombieVillagerEM, + ZombifiedPiglinEM, +) +from mcproto.types.entity.metadata import EntityMetadata diff --git a/mcproto/types/entity/enums.py b/mcproto/types/entity/enums.py new file mode 100644 index 00000000..4d1f5500 --- /dev/null +++ b/mcproto/types/entity/enums.py @@ -0,0 +1,92 @@ +from enum import IntEnum + + +class Direction(IntEnum): + """Represents a direction in the world.""" + + DOWN = 0 + """Towards the negative y-axis. (-y)""" + UP = 1 + """Towards the positive y-axis. (+y)""" + NORTH = 2 + """Towards the negative z-axis. (-z)""" + SOUTH = 3 + """Towards the positive z-axis. (+z)""" + WEST = 4 + """Towards the negative x-axis. (-x)""" + EAST = 5 + """Towards the positive x-axis. (+x)""" + + +class Pose(IntEnum): + """Represents a pose of an entity.""" + + STANDING = 0 + """The entity is standing. (default)""" + FALL_FLYING = 1 + """The entity is falling or flying.""" + SLEEPING = 2 + """The entity is sleeping. (e.g. in a bed)""" + SWIMMING = 3 + """The entity is swimming.""" + SPIN_ATTACK = 4 + """The entity is performing a spin attack (with a riptide trident).""" + SNEAKING = 5 + """The entity is sneaking.""" + LONG_JUMPING = 6 + """The entity is long jumping.""" + DYING = 7 + """The entity is dying""" + CROAKING = 8 + """The entity is croaking. (a frog)""" + USING_TONGUE = 9 + """The entity is using its tongue. (a frog)""" + SITTING = 10 + """The entity is sitting. (e.g. a pet)""" + ROARING = 11 + """The entity is roaring. (a warden)""" + SNIFFING = 12 + """The entity is sniffing.""" + EMERGING = 13 + """The entity is emerging from the ground. (a warden)""" + DIGGING = 14 + """The entity is digging.""" + + +class SnifferState(IntEnum): + """Represents the state of a sniffer.""" + + IDLING = 0 + FEELING_HAPPY = 1 + SCENTING = 2 + SNIFFING = 3 + SEARCHING = 4 + DIGGING = 5 + RISING = 6 + + +class DragonPhase(IntEnum): + """Represents the state the ender dragon is in.""" + + CIRCLING = 0 + """The dragon is circling around the portal.""" + STRAFING = 1 + """The dragon is strafing the player.""" + FLYING_TO_PORTAL = 2 + """The dragon is flying to the portal.""" + LANDING_ON_PORTAL = 3 + """The dragon is landing on the portal. (perching)""" + TAKING_OFF_FROM_PORTAL = 4 + """The dragon is taking off from the portal.""" + LANDED_BREATH_ATTACK = 5 + """The dragon has landed and is performing a breath attack.""" + LANDED_LOOKING_FOR_PLAYER = 6 + """The dragon has landed and is looking for the player.""" + LANDED_ROAR = 7 + """The dragon has landed and is roaring.""" + CHARGING_PLAYER = 8 + """The dragon is charging at the player.""" + FLYING_TO_PORTAL_TO_DIE = 9 + """The dragon is flying to the portal to die.""" + HOVERING_NO_AI = 10 + """The dragon is hovering in place with no AI. (default)""" diff --git a/mcproto/types/entity/generated.py b/mcproto/types/entity/generated.py new file mode 100644 index 00000000..2d4fb2f1 --- /dev/null +++ b/mcproto/types/entity/generated.py @@ -0,0 +1,11381 @@ +from __future__ import annotations + +###################################################################### +# This file is automatically generated by the entity generator script. +# You can modify it by changing what you want in the script. +###################################################################### +from mcproto.types.entity.enums import Direction, DragonPhase, Pose, SnifferState + +__all__ = [ + "AbstractArrowEM", + "AbstractFishEM", + "AbstractGolemEM", + "AbstractHorseEM", + "AbstractIllagerEM", + "AbstractMinecartContainerEM", + "AbstractMinecartEM", + "AbstractSkeletonEM", + "AbstractVehicleEM", + "AbstractVillagerEM", + "AgeableMobEM", + "AmbientCreatureEM", + "AnimalEM", + "AreaEffectCloudEM", + "ArmorStandEM", + "ArrowEM", + "AxolotlEM", + "BasePiglinEM", + "BatEM", + "BeeEM", + "BlazeEM", + "BlockDisplayEM", + "BoatEM", + "CamelEM", + "CatEM", + "ChestBoatEM", + "ChestedHorseEM", + "ChickenEM", + "CodEM", + "CowEM", + "CreeperEM", + "Direction", + "DisplayEM", + "DolphinEM", + "DonkeyEM", + "DragonFireballEM", + "DragonPhase", + "DrownedEM", + "ElderGuardianEM", + "EndCrystalEM", + "EnderDragonEM", + "EndermanEM", + "EndermiteEM", + "EntityEM", + "EntityMetadata", + "EvokerEM", + "EvokerFangsEM", + "EyeOfEnderEM", + "FallingBlockEM", + "FireballEM", + "FireworkRocketEM", + "FishingHookEM", + "FlyingEM", + "FoxEM", + "FrogEM", + "GhastEM", + "GiantEM", + "GlowingItemFrameEM", + "GoatEM", + "GuardianEM", + "HoglinEM", + "HorseEM", + "HuskEM", + "IllusionerEM", + "InteractionEM", + "IronGolemEM", + "ItemDisplayEM", + "ItemEntityEM", + "ItemFrameEM", + "LivingEntityEM", + "LlamaEM", + "LlamaSpitEM", + "MinecartChestEM", + "MinecartCommandBlockEM", + "MinecartEM", + "MinecartFurnaceEM", + "MinecartHopperEM", + "MinecartSpawnerEM", + "MinecartTNTEM", + "MobEM", + "MonsterEM", + "MooshroomEM", + "MuleEM", + "OcelotEM", + "PaintingEM", + "PandaEM", + "ParrotEM", + "PathfinderMobEM", + "PhantomEM", + "PigEM", + "PiglinBruteEM", + "PiglinEM", + "PillagerEM", + "PlayerEM", + "PolarBearEM", + "Pose", + "PrimedTntEM", + "PufferFishEM", + "RabbitEM", + "RaiderEM", + "RavagerEM", + "SalmonEM", + "SheepEM", + "ShulkerEM", + "SilverfishEM", + "SkeletonEM", + "SkeletonHorseEM", + "SlimeEM", + "SmallFireballEM", + "SnifferEM", + "SnifferState", + "SnowGolemEM", + "SpectralArrowEM", + "SpellcasterIllagerEM", + "SpiderEM", + "SquidEM", + "StrayEM", + "StriderEM", + "TadpoleEM", + "TameableAnimalEM", + "TextDisplayEM", + "ThrownEggEM", + "ThrownEnderPearlEM", + "ThrownExperienceBottleEM", + "ThrownItemProjectileEM", + "ThrownPotionEM", + "ThrownSnowballEM", + "ThrownTridentEM", + "TraderLlamaEM", + "TropicalFishEM", + "TurtleEM", + "VexEM", + "VillagerEM", + "VindicatorEM", + "WanderingTraderEM", + "WardenEM", + "WaterAnimalEM", + "WitchEM", + "WitherEM", + "WitherSkeletonEM", + "WitherSkullEM", + "WolfEM", + "ZoglinEM", + "ZombieEM", + "ZombieHorseEM", + "ZombieVillagerEM", + "ZombifiedPiglinEM", +] + +from typing import ClassVar + +from mcproto.types.chat import TextComponent +from mcproto.types.entity.metadata import EntityMetadata, entry, proxy +from mcproto.types.entity.metadata_types import ( + BlockStateEME, + BoolMasked, + BooleanEME, + ByteEME, + CatVariantEME, + DirectionEME, + DragonPhaseEME, + FloatEME, + FrogVariantEME, + NBTagEME, + OptBlockStateEME, + OptPositionEME, + OptUUIDEME, + OptVarIntEME, + PaintingVariantEME, + ParticleEME, + PoseEME, + PositionEME, + QuaternionEME, + RotationEME, + SlotEME, + SnifferStateEME, + StringEME, + TextComponentEME, + VarIntEME, + VarLongEME, + Vector3EME, + VillagerDataEME, +) +from mcproto.types.nbt import EndNBT, NBTag +from mcproto.types.particle_data import ParticleData +from mcproto.types.quaternion import Quaternion +from mcproto.types.slot import Slot, SlotData +from mcproto.types.uuid import UUID +from mcproto.types.vec3 import Position, Vec3 + + +class EntityEM(EntityMetadata): + """Base for all Entity classes. + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + _entity_flags: ClassVar[int] = entry(ByteEME, 0) + is_on_fire: bool = proxy(_entity_flags, BoolMasked, mask=0x1) + is_crouching: bool = proxy(_entity_flags, BoolMasked, mask=0x2) + is_riding: bool = proxy(_entity_flags, BoolMasked, mask=0x4) + is_sprinting: bool = proxy(_entity_flags, BoolMasked, mask=0x8) + is_swimming: bool = proxy(_entity_flags, BoolMasked, mask=0x10) + is_invisible: bool = proxy(_entity_flags, BoolMasked, mask=0x20) + is_glowing: bool = proxy(_entity_flags, BoolMasked, mask=0x40) + is_flying: bool = proxy(_entity_flags, BoolMasked, mask=0x80) + air: int = entry(VarIntEME, 300) + custom_name: str = entry(StringEME, "") + is_custom_name_visible: bool = entry(BooleanEME, False) + is_silent: bool = entry(BooleanEME, False) + no_gravity: bool = entry(BooleanEME, False) + pose: Pose = entry(PoseEME, Pose.STANDING) + ticks_frozen: int = entry(VarIntEME, 0) + + __slots__ = () + + +class InteractionEM(EntityEM): + """Entity that can be interacted with. + + :param width: The width of the entity. + :type width: float, optional, default: 1.0 + :param height: The height of the entity. + :type height: float, optional, default: 1.0 + :param responsive: Whether the entity can be interacted with/attached + :type responsive: bool, optional, default: False + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + width: float = entry(FloatEME, 1.0) + height: float = entry(FloatEME, 1.0) + responsive: bool = entry(BooleanEME, False) + + __slots__ = () + + +class DisplayEM(EntityEM): + """Entity that are used to render something on the client. + + https://minecraft.wiki/w/Display + + :param interpolation_delay: Delay before starting interpolation. + If 0, interpolation starts immediately.(doesn't exist in newest snapshot) + :type interpolation_delay: int, optional, default: 0 + :param interpolation_translation_duration: Transformation interpolation duration. + :type interpolation_translation_duration: int, optional, default: 0 + :param interpolation_rotation_duration: Rotation interpolation duration. + :type interpolation_rotation_duration: int, optional, default: 0 + :param translation: Translation vector + :type translation: :class:`Vec3`, optional, default: :attr:`Vec3(0.0, 0.0, 0.0)` + :param scale: Scaling vector + :type scale: :class:`Vec3`, optional, default: :attr:`Vec3(1.0, 1.0, 1.0)` + :param rotation_left: See :attr:`rotation_right` + :type rotation_left: :class:`Quaternion`, optional, default: :attr:`Quaternion(0.0, 0.0, 0.0, 1.0)` + :param rotation_right: Initial rotation. This tag corresponds to the right-singular vector matrix after the + matrix singular value decomposition. + :type rotation_right: :class:`Quaternion`, optional, default: :attr:`Quaternion(0.0, 0.0, 0.0, 1.0)` + :param billboard_constraint: Billboard Constraints (0 = FIXED, 1 = VERTICAL, 2 = HORIZONTAL, 3 = CENTER) + Controls if this entity should pivot to face player when rendered. + :type billboard_constraint: int, optional, default: 0 + :param brightness_override: Brightness override (blockLight << 4 | skyLight << 20). By default the brightness + value is calculated from the light level of the block the entity is in. + :type brightness_override: int, optional, default: -1 + :param view_range: View range + :type view_range: float, optional, default: 1.0 + :param shadow_radius: Shadow radius. Value is treated as 64 when higher than 64. + If less than or equal to 0, the entity has no shadow. Interpolated + :type shadow_radius: float, optional, default: 0.0 + :param shadow_strength: Shadow strength. Interpolated + :type shadow_strength: float, optional, default: 0.0 + :param width: The maximum width of the entity. Rendering culling bounding box spans horizontally + `width/2` from entity position, and the part beyond will be culled. If set to 0, no culling on + both vertical and horizontal directions. + :type width: float, optional, default: 0.0 + :param height: The maximum height of the entity. Rendering culling bounding box spans vertically + `y` to `y+height`, and the part beyond will be culled. If set to 0, no culling on both + vertical and horizontal directions. + :type height: float, optional, default: 0.0 + :param glow_color_override: Overrides the glow border color. If 0, uses the color of the team that the display + entity is in. + :type glow_color_override: int, optional, default: 0 + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + interpolation_delay: int = entry(VarIntEME, 0) + interpolation_translation_duration: int = entry(VarIntEME, 0) + interpolation_rotation_duration: int = entry(VarIntEME, 0) + translation: Vec3 = entry(Vector3EME, Vec3(0.0, 0.0, 0.0)) + scale: Vec3 = entry(Vector3EME, Vec3(1.0, 1.0, 1.0)) + rotation_left: Quaternion = entry(QuaternionEME, Quaternion(0.0, 0.0, 0.0, 1.0)) + rotation_right: Quaternion = entry(QuaternionEME, Quaternion(0.0, 0.0, 0.0, 1.0)) + billboard_constraint: int = entry(ByteEME, 0) + brightness_override: int = entry(VarIntEME, -1) + view_range: float = entry(FloatEME, 1.0) + shadow_radius: float = entry(FloatEME, 0.0) + shadow_strength: float = entry(FloatEME, 0.0) + width: float = entry(FloatEME, 0.0) + height: float = entry(FloatEME, 0.0) + glow_color_override: int = entry(VarIntEME, 0) + + __slots__ = () + + +class BlockDisplayEM(DisplayEM): + """Entity that are used to render a block on the client as a Display entity. + + https://minecraft.wiki/w/Display#Block_Displays + + :param block: The block state to display. Default is air. + :type block: int, optional, default: 0 + + Inherited from :class:`DisplayEM`: + + :param interpolation_delay: Delay before starting interpolation. + If 0, interpolation starts immediately.(doesn't exist in newest snapshot) + :type interpolation_delay: int, optional, default: 0 + :param interpolation_translation_duration: Transformation interpolation duration. + :type interpolation_translation_duration: int, optional, default: 0 + :param interpolation_rotation_duration: Rotation interpolation duration. + :type interpolation_rotation_duration: int, optional, default: 0 + :param translation: Translation vector + :type translation: :class:`Vec3`, optional, default: :attr:`Vec3(0.0, 0.0, 0.0)` + :param scale: Scaling vector + :type scale: :class:`Vec3`, optional, default: :attr:`Vec3(1.0, 1.0, 1.0)` + :param rotation_left: See :attr:`rotation_right` + :type rotation_left: :class:`Quaternion`, optional, default: :attr:`Quaternion(0.0, 0.0, 0.0, 1.0)` + :param rotation_right: Initial rotation. This tag corresponds to the right-singular vector matrix after the + matrix singular value decomposition. + :type rotation_right: :class:`Quaternion`, optional, default: :attr:`Quaternion(0.0, 0.0, 0.0, 1.0)` + :param billboard_constraint: Billboard Constraints (0 = FIXED, 1 = VERTICAL, 2 = HORIZONTAL, 3 = CENTER) + Controls if this entity should pivot to face player when rendered. + :type billboard_constraint: int, optional, default: 0 + :param brightness_override: Brightness override (blockLight << 4 | skyLight << 20). By default the brightness + value is calculated from the light level of the block the entity is in. + :type brightness_override: int, optional, default: -1 + :param view_range: View range + :type view_range: float, optional, default: 1.0 + :param shadow_radius: Shadow radius. Value is treated as 64 when higher than 64. + If less than or equal to 0, the entity has no shadow. Interpolated + :type shadow_radius: float, optional, default: 0.0 + :param shadow_strength: Shadow strength. Interpolated + :type shadow_strength: float, optional, default: 0.0 + :param width: The maximum width of the entity. Rendering culling bounding box spans horizontally + `width/2` from entity position, and the part beyond will be culled. If set to 0, no culling on + both vertical and horizontal directions. + :type width: float, optional, default: 0.0 + :param height: The maximum height of the entity. Rendering culling bounding box spans vertically + `y` to `y+height`, and the part beyond will be culled. If set to 0, no culling on both + vertical and horizontal directions. + :type height: float, optional, default: 0.0 + :param glow_color_override: Overrides the glow border color. If 0, uses the color of the team that the display + entity is in. + :type glow_color_override: int, optional, default: 0 + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + block: int = entry(BlockStateEME, 0) + + __slots__ = () + + +class ItemDisplayEM(DisplayEM): + """Entity that are used to render an item on the client as a Display entity. + + https://minecraft.wiki/w/Display#Item_Displays + + :param item: The item to display. Default is an empty slot. + :type item: :class:`Slot`, optional, default: :attr:`Slot(None)` + :param display_type: Display type: (NONE, THIRD_PERSON_LEFT_HAND, THIRD_PERSON_RIGHT_HAND, + FIRST_PERSON_LEFT_HAND, FIRST_PERSON_RIGHT_HAND, HEAD, GUI, GROUND, FIXED). + :type display_type: int, optional, default: 0 + + Inherited from :class:`DisplayEM`: + + :param interpolation_delay: Delay before starting interpolation. + If 0, interpolation starts immediately.(doesn't exist in newest snapshot) + :type interpolation_delay: int, optional, default: 0 + :param interpolation_translation_duration: Transformation interpolation duration. + :type interpolation_translation_duration: int, optional, default: 0 + :param interpolation_rotation_duration: Rotation interpolation duration. + :type interpolation_rotation_duration: int, optional, default: 0 + :param translation: Translation vector + :type translation: :class:`Vec3`, optional, default: :attr:`Vec3(0.0, 0.0, 0.0)` + :param scale: Scaling vector + :type scale: :class:`Vec3`, optional, default: :attr:`Vec3(1.0, 1.0, 1.0)` + :param rotation_left: See :attr:`rotation_right` + :type rotation_left: :class:`Quaternion`, optional, default: :attr:`Quaternion(0.0, 0.0, 0.0, 1.0)` + :param rotation_right: Initial rotation. This tag corresponds to the right-singular vector matrix after the + matrix singular value decomposition. + :type rotation_right: :class:`Quaternion`, optional, default: :attr:`Quaternion(0.0, 0.0, 0.0, 1.0)` + :param billboard_constraint: Billboard Constraints (0 = FIXED, 1 = VERTICAL, 2 = HORIZONTAL, 3 = CENTER) + Controls if this entity should pivot to face player when rendered. + :type billboard_constraint: int, optional, default: 0 + :param brightness_override: Brightness override (blockLight << 4 | skyLight << 20). By default the brightness + value is calculated from the light level of the block the entity is in. + :type brightness_override: int, optional, default: -1 + :param view_range: View range + :type view_range: float, optional, default: 1.0 + :param shadow_radius: Shadow radius. Value is treated as 64 when higher than 64. + If less than or equal to 0, the entity has no shadow. Interpolated + :type shadow_radius: float, optional, default: 0.0 + :param shadow_strength: Shadow strength. Interpolated + :type shadow_strength: float, optional, default: 0.0 + :param width: The maximum width of the entity. Rendering culling bounding box spans horizontally + `width/2` from entity position, and the part beyond will be culled. If set to 0, no culling on + both vertical and horizontal directions. + :type width: float, optional, default: 0.0 + :param height: The maximum height of the entity. Rendering culling bounding box spans vertically + `y` to `y+height`, and the part beyond will be culled. If set to 0, no culling on both + vertical and horizontal directions. + :type height: float, optional, default: 0.0 + :param glow_color_override: Overrides the glow border color. If 0, uses the color of the team that the display + entity is in. + :type glow_color_override: int, optional, default: 0 + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + item: Slot = entry(SlotEME, Slot(None)) + display_type: int = entry(ByteEME, 0) + + __slots__ = () + + +class TextDisplayEM(DisplayEM): + """Entity that are used to render text on the client as a Display entity. + + https://minecraft.wiki/w/Display#Text_Displays + + :param text: The text to display. Default is an empty text component. + :type text: :class:`TextComponent`, optional, default: :attr:`TextComponent("")` + :param line_width: : Maximum line width used to split lines (note: new line can also + be added with \\n characters). + :type line_width: int, optional, default: 200 + :param background_color: Background color of the text. Default is 0x40000000. + :type background_color: int, optional, default: 1073741824 + :param has_shadow: Whether the text is displayed with shadow. (this affects :attr:`_display_flags`) + :type has_shadow: bool, optional + :param is_see_through: Whether the text is displayed as see-through. (this affects :attr:`_display_flags`) + :type is_see_through: bool, optional + :param use_default_background: Whether to use the default background color for the text + display. (this affects :attr:`_display_flags`) + :type use_default_background: bool, optional + :param align_left: Whether the text is aligned to the left. + Has priority over right (see also :attr:`align_right`) (this affects :attr:`_display_flags`) + :type align_left: bool, optional + :param align_right: Whether the text is aligned to the right. + Set both to false for center alignment. (this affects :attr:`_display_flags`) + :type align_right: bool, optional + + Inherited from :class:`DisplayEM`: + + :param interpolation_delay: Delay before starting interpolation. + If 0, interpolation starts immediately.(doesn't exist in newest snapshot) + :type interpolation_delay: int, optional, default: 0 + :param interpolation_translation_duration: Transformation interpolation duration. + :type interpolation_translation_duration: int, optional, default: 0 + :param interpolation_rotation_duration: Rotation interpolation duration. + :type interpolation_rotation_duration: int, optional, default: 0 + :param translation: Translation vector + :type translation: :class:`Vec3`, optional, default: :attr:`Vec3(0.0, 0.0, 0.0)` + :param scale: Scaling vector + :type scale: :class:`Vec3`, optional, default: :attr:`Vec3(1.0, 1.0, 1.0)` + :param rotation_left: See :attr:`rotation_right` + :type rotation_left: :class:`Quaternion`, optional, default: :attr:`Quaternion(0.0, 0.0, 0.0, 1.0)` + :param rotation_right: Initial rotation. This tag corresponds to the right-singular vector matrix after the + matrix singular value decomposition. + :type rotation_right: :class:`Quaternion`, optional, default: :attr:`Quaternion(0.0, 0.0, 0.0, 1.0)` + :param billboard_constraint: Billboard Constraints (0 = FIXED, 1 = VERTICAL, 2 = HORIZONTAL, 3 = CENTER) + Controls if this entity should pivot to face player when rendered. + :type billboard_constraint: int, optional, default: 0 + :param brightness_override: Brightness override (blockLight << 4 | skyLight << 20). By default the brightness + value is calculated from the light level of the block the entity is in. + :type brightness_override: int, optional, default: -1 + :param view_range: View range + :type view_range: float, optional, default: 1.0 + :param shadow_radius: Shadow radius. Value is treated as 64 when higher than 64. + If less than or equal to 0, the entity has no shadow. Interpolated + :type shadow_radius: float, optional, default: 0.0 + :param shadow_strength: Shadow strength. Interpolated + :type shadow_strength: float, optional, default: 0.0 + :param width: The maximum width of the entity. Rendering culling bounding box spans horizontally + `width/2` from entity position, and the part beyond will be culled. If set to 0, no culling on + both vertical and horizontal directions. + :type width: float, optional, default: 0.0 + :param height: The maximum height of the entity. Rendering culling bounding box spans vertically + `y` to `y+height`, and the part beyond will be culled. If set to 0, no culling on both + vertical and horizontal directions. + :type height: float, optional, default: 0.0 + :param glow_color_override: Overrides the glow border color. If 0, uses the color of the team that the display + entity is in. + :type glow_color_override: int, optional, default: 0 + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + text: TextComponent = entry(TextComponentEME, TextComponent("")) + line_width: int = entry(VarIntEME, 200) + background_color: int = entry(VarIntEME, 1073741824) + _display_flags: ClassVar[int] = entry(ByteEME, 0) + has_shadow: bool = proxy(_display_flags, BoolMasked, mask=0x1) + is_see_through: bool = proxy(_display_flags, BoolMasked, mask=0x2) + use_default_background: bool = proxy(_display_flags, BoolMasked, mask=0x4) + align_left: bool = proxy(_display_flags, BoolMasked, mask=0x8) + align_right: bool = proxy(_display_flags, BoolMasked, mask=0x10) + + __slots__ = () + + +class ThrownItemProjectileEM(EntityEM): + """Entity that represents a thrown item projectile. + + :param item: The item that the projectile represents + :type item: :class:`Slot`, optional, default: :attr:`Slot(None)` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + item: Slot = entry(SlotEME, Slot(None)) + + __slots__ = () + + +class ThrownEggEM(ThrownItemProjectileEM): + """Entity that represents a thrown egg projectile. + + Inherited from :class:`ThrownItemProjectileEM`: + + :param item: The item that the projectile represents + :type item: :class:`Slot`, optional, default: :attr:`Slot(None)` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + item: Slot = entry(SlotEME, Slot(SlotData(NotImplemented, 1))) + + __slots__ = () + + +class ThrownEnderPearlEM(ThrownItemProjectileEM): + """Entity that represents a thrown ender pearl projectile. + + Inherited from :class:`ThrownItemProjectileEM`: + + :param item: The item that the projectile represents + :type item: :class:`Slot`, optional, default: :attr:`Slot(None)` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + item: Slot = entry(SlotEME, Slot(SlotData(NotImplemented, 1))) + + __slots__ = () + + +class ThrownExperienceBottleEM(ThrownItemProjectileEM): + """Entity that represents a thrown experience bottle projectile. + + Inherited from :class:`ThrownItemProjectileEM`: + + :param item: The item that the projectile represents + :type item: :class:`Slot`, optional, default: :attr:`Slot(None)` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + item: Slot = entry(SlotEME, Slot(SlotData(NotImplemented, 1))) + + __slots__ = () + + +class ThrownPotionEM(ThrownItemProjectileEM): + """Entity that represents a thrown potion projectile. + + Inherited from :class:`ThrownItemProjectileEM`: + + :param item: The item that the projectile represents + :type item: :class:`Slot`, optional, default: :attr:`Slot(None)` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + item: Slot = entry(SlotEME, Slot(SlotData(NotImplemented, 1))) + + __slots__ = () + + +class ThrownSnowballEM(ThrownItemProjectileEM): + """Entity that represents a thrown snowball projectile. + + Inherited from :class:`ThrownItemProjectileEM`: + + :param item: The item that the projectile represents + :type item: :class:`Slot`, optional, default: :attr:`Slot(None)` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + item: Slot = entry(SlotEME, Slot(SlotData(NotImplemented, 1))) + + __slots__ = () + + +class EyeOfEnderEM(EntityEM): + """Entity that represents an eye of ender. + + :param item: The item that the entity represents (usually an ender eye) + :type item: :class:`Slot`, optional, default: :attr:`Slot(None)` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + item: Slot = entry(SlotEME, Slot(None)) + + __slots__ = () + + +class FallingBlockEM(EntityEM): + """Entity that represents a falling block. + + :param position: The spawn position of the falling block + :type position: :class:`Position`, optional, default: :attr:`Position(0, 0, 0)` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + position: Position = entry(PositionEME, Position(0, 0, 0)) + + __slots__ = () + + +class AreaEffectCloudEM(EntityEM): + """Entity that represents an area effect cloud. + + :param radius: The radius of the area effect cloud. + :type radius: float, optional, default: 0.5 + :param color: Color of the cloud's particle effect. Only applicable for mob spell particles. + :type color: int, optional, default: 0 + :param single_point_effect: Whether to ignore the radius and show the effect as a single point, not an area. + :type single_point_effect: bool, optional, default: False + :param effect: The particle effect of the area effect cloud (default: `minecraft:effect`). + :type effect: :class:`ParticleData`, optional, default: :attr:`ParticleData(15)` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + radius: float = entry(FloatEME, 0.5) + color: int = entry(VarIntEME, 0) + single_point_effect: bool = entry(BooleanEME, False) + effect: ParticleData = entry(ParticleEME, ParticleData(15)) + + __slots__ = () + + +class FishingHookEM(EntityEM): + """Entity that represents a fishing hook. + + :param hooked_entity_id: The ID of the hooked entity plus one, or 0 if there is no hooked entity. + :type hooked_entity_id: int, optional, default: 0 + :param is_catchable: Whether the fishing hook is catchable. + :type is_catchable: bool, optional, default: False + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + hooked_entity_id: int = entry(VarIntEME, 0) + is_catchable: bool = entry(BooleanEME, False) + + __slots__ = () + + +class AbstractArrowEM(EntityEM): + """Entity that represents an abstract arrow. + + :param is_critical: Whether the arrow is critical. (this affects :attr:`_arrow_flags`) + :type is_critical: bool, optional + :param is_noclip: Whether the arrow is noclip (used by loyalty tridents when + returning). (this affects :attr:`_arrow_flags`) + :type is_noclip: bool, optional + :param piercing_level: The piercing level of the arrow. + :type piercing_level: int, optional, default: 0 + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + _arrow_flags: ClassVar[int] = entry(ByteEME, 0) + is_critical: bool = proxy(_arrow_flags, BoolMasked, mask=0x1) + is_noclip: bool = proxy(_arrow_flags, BoolMasked, mask=0x2) + piercing_level: int = entry(ByteEME, 0) + + __slots__ = () + + +class ArrowEM(AbstractArrowEM): + """Entity that represents an arrow. + + :param color: Color of the arrow's particles. Set to -1 for no particles. + :type color: int, optional, default: -1 + + Inherited from :class:`AbstractArrowEM`: + + :param is_critical: Whether the arrow is critical. (this affects :attr:`_arrow_flags`) + :type is_critical: bool, optional + :param is_noclip: Whether the arrow is noclip (used by loyalty tridents when + returning). (this affects :attr:`_arrow_flags`) + :type is_noclip: bool, optional + :param piercing_level: The piercing level of the arrow. + :type piercing_level: int, optional, default: 0 + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + color: int = entry(VarIntEME, -1) + + __slots__ = () + + +class SpectralArrowEM(AbstractArrowEM): + """Entity that represents a spectral arrow. + + Inherited from :class:`AbstractArrowEM`: + + :param is_critical: Whether the arrow is critical. (this affects :attr:`_arrow_flags`) + :type is_critical: bool, optional + :param is_noclip: Whether the arrow is noclip (used by loyalty tridents when + returning). (this affects :attr:`_arrow_flags`) + :type is_noclip: bool, optional + :param piercing_level: The piercing level of the arrow. + :type piercing_level: int, optional, default: 0 + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + __slots__ = () + + +class ThrownTridentEM(AbstractArrowEM): + """Entity that represents a thrown trident. + + :param loyalty_level: The loyalty level of the thrown trident (enchantment). + :type loyalty_level: int, optional, default: 0 + :param has_enchantment_glint: Whether the thrown trident has an enchantment glint. + :type has_enchantment_glint: bool, optional, default: False + + Inherited from :class:`AbstractArrowEM`: + + :param is_critical: Whether the arrow is critical. (this affects :attr:`_arrow_flags`) + :type is_critical: bool, optional + :param is_noclip: Whether the arrow is noclip (used by loyalty tridents when + returning). (this affects :attr:`_arrow_flags`) + :type is_noclip: bool, optional + :param piercing_level: The piercing level of the arrow. + :type piercing_level: int, optional, default: 0 + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + loyalty_level: int = entry(VarIntEME, 0) + has_enchantment_glint: bool = entry(BooleanEME, False) + + __slots__ = () + + +class AbstractVehicleEM(EntityEM): + """Entity that represents an abstract vehicle. + + :param shaking_power: The shaking power of the vehicle. + :type shaking_power: int, optional, default: 0 + :param shaking_direction: The shaking direction of the vehicle. + :type shaking_direction: int, optional, default: 1 + :param shaking_multiplier: The shaking multiplier of the vehicle. + :type shaking_multiplier: float, optional, default: 0.0 + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + shaking_power: int = entry(VarIntEME, 0) + shaking_direction: int = entry(VarIntEME, 1) + shaking_multiplier: float = entry(FloatEME, 0.0) + + __slots__ = () + + +class BoatEM(AbstractVehicleEM): + """Entity that represents a boat. + + :param boat_type: The type of the boat. (0 = oak, 1 = spruce, 2 = birch, 3 = jungle, + 4 = acacia, 5 = dark oak) + :type boat_type: int, optional, default: 0 + :param is_left_paddle_turning: Whether the left paddle of the boat is turning. + :type is_left_paddle_turning: bool, optional, default: False + :param is_right_paddle_turning: Whether the right paddle of the boat is turning. + :type is_right_paddle_turning: bool, optional, default: False + :param splash_timer: The splash timer of the boat. + :type splash_timer: int, optional, default: 0 + + Inherited from :class:`AbstractVehicleEM`: + + :param shaking_power: The shaking power of the vehicle. + :type shaking_power: int, optional, default: 0 + :param shaking_direction: The shaking direction of the vehicle. + :type shaking_direction: int, optional, default: 1 + :param shaking_multiplier: The shaking multiplier of the vehicle. + :type shaking_multiplier: float, optional, default: 0.0 + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + boat_type: int = entry(VarIntEME, 0) + is_left_paddle_turning: bool = entry(BooleanEME, False) + is_right_paddle_turning: bool = entry(BooleanEME, False) + splash_timer: int = entry(VarIntEME, 0) + + __slots__ = () + + +class ChestBoatEM(BoatEM): + """Entity that represents a chest boat. + + Inherited from :class:`BoatEM`: + + :param boat_type: The type of the boat. (0 = oak, 1 = spruce, 2 = birch, 3 = jungle, + 4 = acacia, 5 = dark oak) + :type boat_type: int, optional, default: 0 + :param is_left_paddle_turning: Whether the left paddle of the boat is turning. + :type is_left_paddle_turning: bool, optional, default: False + :param is_right_paddle_turning: Whether the right paddle of the boat is turning. + :type is_right_paddle_turning: bool, optional, default: False + :param splash_timer: The splash timer of the boat. + :type splash_timer: int, optional, default: 0 + + Inherited from :class:`AbstractVehicleEM`: + + :param shaking_power: The shaking power of the vehicle. + :type shaking_power: int, optional, default: 0 + :param shaking_direction: The shaking direction of the vehicle. + :type shaking_direction: int, optional, default: 1 + :param shaking_multiplier: The shaking multiplier of the vehicle. + :type shaking_multiplier: float, optional, default: 0.0 + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + __slots__ = () + + +class AbstractMinecartEM(AbstractVehicleEM): + """Entity that represents an abstract minecart. + + :param custom_block_id_and_damage: The custom block ID and damage of the minecart. + :type custom_block_id_and_damage: int, optional, default: 0 + :param custom_block_y_position: The custom block Y position (in 16ths of a block) of the minecart. + :type custom_block_y_position: int, optional, default: 6 + :param show_custom_block: Whether to show the custom block of the minecart. + :type show_custom_block: bool, optional, default: False + + Inherited from :class:`AbstractVehicleEM`: + + :param shaking_power: The shaking power of the vehicle. + :type shaking_power: int, optional, default: 0 + :param shaking_direction: The shaking direction of the vehicle. + :type shaking_direction: int, optional, default: 1 + :param shaking_multiplier: The shaking multiplier of the vehicle. + :type shaking_multiplier: float, optional, default: 0.0 + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + custom_block_id_and_damage: int = entry(VarIntEME, 0) + custom_block_y_position: int = entry(VarIntEME, 6) + show_custom_block: bool = entry(BooleanEME, False) + + __slots__ = () + + +class MinecartEM(AbstractMinecartEM): + """Entity that represents a minecart. + + Inherited from :class:`AbstractMinecartEM`: + + :param custom_block_id_and_damage: The custom block ID and damage of the minecart. + :type custom_block_id_and_damage: int, optional, default: 0 + :param custom_block_y_position: The custom block Y position (in 16ths of a block) of the minecart. + :type custom_block_y_position: int, optional, default: 6 + :param show_custom_block: Whether to show the custom block of the minecart. + :type show_custom_block: bool, optional, default: False + + Inherited from :class:`AbstractVehicleEM`: + + :param shaking_power: The shaking power of the vehicle. + :type shaking_power: int, optional, default: 0 + :param shaking_direction: The shaking direction of the vehicle. + :type shaking_direction: int, optional, default: 1 + :param shaking_multiplier: The shaking multiplier of the vehicle. + :type shaking_multiplier: float, optional, default: 0.0 + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + __slots__ = () + + +class AbstractMinecartContainerEM(AbstractMinecartEM): + """Entity that represents an abstract minecart container. + + Inherited from :class:`AbstractMinecartEM`: + + :param custom_block_id_and_damage: The custom block ID and damage of the minecart. + :type custom_block_id_and_damage: int, optional, default: 0 + :param custom_block_y_position: The custom block Y position (in 16ths of a block) of the minecart. + :type custom_block_y_position: int, optional, default: 6 + :param show_custom_block: Whether to show the custom block of the minecart. + :type show_custom_block: bool, optional, default: False + + Inherited from :class:`AbstractVehicleEM`: + + :param shaking_power: The shaking power of the vehicle. + :type shaking_power: int, optional, default: 0 + :param shaking_direction: The shaking direction of the vehicle. + :type shaking_direction: int, optional, default: 1 + :param shaking_multiplier: The shaking multiplier of the vehicle. + :type shaking_multiplier: float, optional, default: 0.0 + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + __slots__ = () + + +class MinecartHopperEM(AbstractMinecartContainerEM): + """Entity that represents a minecart hopper. + + Inherited from :class:`AbstractMinecartContainerEM`: + + Inherited from :class:`AbstractMinecartEM`: + + :param custom_block_id_and_damage: The custom block ID and damage of the minecart. + :type custom_block_id_and_damage: int, optional, default: 0 + :param custom_block_y_position: The custom block Y position (in 16ths of a block) of the minecart. + :type custom_block_y_position: int, optional, default: 6 + :param show_custom_block: Whether to show the custom block of the minecart. + :type show_custom_block: bool, optional, default: False + + Inherited from :class:`AbstractVehicleEM`: + + :param shaking_power: The shaking power of the vehicle. + :type shaking_power: int, optional, default: 0 + :param shaking_direction: The shaking direction of the vehicle. + :type shaking_direction: int, optional, default: 1 + :param shaking_multiplier: The shaking multiplier of the vehicle. + :type shaking_multiplier: float, optional, default: 0.0 + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + __slots__ = () + + +class MinecartChestEM(AbstractMinecartContainerEM): + """Entity that represents a minecart chest. + + Inherited from :class:`AbstractMinecartContainerEM`: + + Inherited from :class:`AbstractMinecartEM`: + + :param custom_block_id_and_damage: The custom block ID and damage of the minecart. + :type custom_block_id_and_damage: int, optional, default: 0 + :param custom_block_y_position: The custom block Y position (in 16ths of a block) of the minecart. + :type custom_block_y_position: int, optional, default: 6 + :param show_custom_block: Whether to show the custom block of the minecart. + :type show_custom_block: bool, optional, default: False + + Inherited from :class:`AbstractVehicleEM`: + + :param shaking_power: The shaking power of the vehicle. + :type shaking_power: int, optional, default: 0 + :param shaking_direction: The shaking direction of the vehicle. + :type shaking_direction: int, optional, default: 1 + :param shaking_multiplier: The shaking multiplier of the vehicle. + :type shaking_multiplier: float, optional, default: 0.0 + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + __slots__ = () + + +class MinecartFurnaceEM(AbstractMinecartEM): + """Entity that represents a minecart furnace. + + :param has_fuel: Whether the furnace minecart has fuel. + :type has_fuel: bool, optional, default: False + + Inherited from :class:`AbstractMinecartEM`: + + :param custom_block_id_and_damage: The custom block ID and damage of the minecart. + :type custom_block_id_and_damage: int, optional, default: 0 + :param custom_block_y_position: The custom block Y position (in 16ths of a block) of the minecart. + :type custom_block_y_position: int, optional, default: 6 + :param show_custom_block: Whether to show the custom block of the minecart. + :type show_custom_block: bool, optional, default: False + + Inherited from :class:`AbstractVehicleEM`: + + :param shaking_power: The shaking power of the vehicle. + :type shaking_power: int, optional, default: 0 + :param shaking_direction: The shaking direction of the vehicle. + :type shaking_direction: int, optional, default: 1 + :param shaking_multiplier: The shaking multiplier of the vehicle. + :type shaking_multiplier: float, optional, default: 0.0 + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + has_fuel: bool = entry(BooleanEME, False) + + __slots__ = () + + +class MinecartTNTEM(AbstractMinecartEM): + """Entity that represents a minecart TNT. + + Inherited from :class:`AbstractMinecartEM`: + + :param custom_block_id_and_damage: The custom block ID and damage of the minecart. + :type custom_block_id_and_damage: int, optional, default: 0 + :param custom_block_y_position: The custom block Y position (in 16ths of a block) of the minecart. + :type custom_block_y_position: int, optional, default: 6 + :param show_custom_block: Whether to show the custom block of the minecart. + :type show_custom_block: bool, optional, default: False + + Inherited from :class:`AbstractVehicleEM`: + + :param shaking_power: The shaking power of the vehicle. + :type shaking_power: int, optional, default: 0 + :param shaking_direction: The shaking direction of the vehicle. + :type shaking_direction: int, optional, default: 1 + :param shaking_multiplier: The shaking multiplier of the vehicle. + :type shaking_multiplier: float, optional, default: 0.0 + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + __slots__ = () + + +class MinecartSpawnerEM(AbstractMinecartEM): + """Entity that represents a minecart spawner. + + Inherited from :class:`AbstractMinecartEM`: + + :param custom_block_id_and_damage: The custom block ID and damage of the minecart. + :type custom_block_id_and_damage: int, optional, default: 0 + :param custom_block_y_position: The custom block Y position (in 16ths of a block) of the minecart. + :type custom_block_y_position: int, optional, default: 6 + :param show_custom_block: Whether to show the custom block of the minecart. + :type show_custom_block: bool, optional, default: False + + Inherited from :class:`AbstractVehicleEM`: + + :param shaking_power: The shaking power of the vehicle. + :type shaking_power: int, optional, default: 0 + :param shaking_direction: The shaking direction of the vehicle. + :type shaking_direction: int, optional, default: 1 + :param shaking_multiplier: The shaking multiplier of the vehicle. + :type shaking_multiplier: float, optional, default: 0.0 + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + __slots__ = () + + +class MinecartCommandBlockEM(AbstractMinecartEM): + """Entity that represents a minecart command block. + + :param command: The command stored in the command block. + :type command: str, optional, default: "" + :param last_output: The last output from the command block. + :type last_output: :class:`TextComponent`, optional, default: :attr:`TextComponent("")` + + Inherited from :class:`AbstractMinecartEM`: + + :param custom_block_id_and_damage: The custom block ID and damage of the minecart. + :type custom_block_id_and_damage: int, optional, default: 0 + :param custom_block_y_position: The custom block Y position (in 16ths of a block) of the minecart. + :type custom_block_y_position: int, optional, default: 6 + :param show_custom_block: Whether to show the custom block of the minecart. + :type show_custom_block: bool, optional, default: False + + Inherited from :class:`AbstractVehicleEM`: + + :param shaking_power: The shaking power of the vehicle. + :type shaking_power: int, optional, default: 0 + :param shaking_direction: The shaking direction of the vehicle. + :type shaking_direction: int, optional, default: 1 + :param shaking_multiplier: The shaking multiplier of the vehicle. + :type shaking_multiplier: float, optional, default: 0.0 + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + command: str = entry(StringEME, "") + last_output: TextComponent = entry(TextComponentEME, TextComponent("")) + + __slots__ = () + + +class EndCrystalEM(EntityEM): + """Entity that represents an end crystal. + + :param beam_target: The position of the beam target. + :type beam_target: :class:`Position | None`, optional, default: :attr:`None` + :param show_bottom: Whether the bottom of the end crystal is shown. + :type show_bottom: bool, optional, default: True + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + beam_target: Position | None = entry(OptPositionEME, None) + show_bottom: bool = entry(BooleanEME, True) + + __slots__ = () + + +class DragonFireballEM(EntityEM): + """Entity that represents a dragon fireball. + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + __slots__ = () + + +class SmallFireballEM(EntityEM): + """Entity that represents a small fireball. + + :param item: The item representing the small fireball. + :type item: :class:`Slot`, optional, default: :attr:`Slot(None)` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + item: Slot = entry(SlotEME, Slot(None)) + + __slots__ = () + + +class FireballEM(EntityEM): + """Entity that represents a fireball. + + :param item: The item representing the fireball. + :type item: :class:`Slot`, optional, default: :attr:`Slot(None)` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + item: Slot = entry(SlotEME, Slot(None)) + + __slots__ = () + + +class WitherSkullEM(EntityEM): + """Entity that represents a wither skull. + + :param is_invulnerable: Whether the wither skull is invulnerable. + :type is_invulnerable: bool, optional, default: False + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + is_invulnerable: bool = entry(BooleanEME, False) + + __slots__ = () + + +class FireworkRocketEM(EntityEM): + """Entity representing a firework rocket. + + :param firework_info: The information about the firework. + :type firework_info: :class:`Slot`, optional, default: :attr:`Slot(None)` + :param shooter_entity_id: The entity ID of the entity that used the firework (for elytra boosting). + :type shooter_entity_id: int|None, optional, default: None + :param shot_at_angle: Whether the firework rocket was shot at an angle (from a crossbow). + :type shot_at_angle: bool, optional, default: False + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + firework_info: Slot = entry(SlotEME, Slot(None)) + shooter_entity_id: int | None = entry(OptVarIntEME, None) + shot_at_angle: bool = entry(BooleanEME, False) + + __slots__ = () + + +class ItemFrameEM(EntityEM): + """Entity representing an item frame. + + :param item: The item in the item frame. + :type item: :class:`Slot`, optional, default: :attr:`Slot(None)` + :param rotation: The rotation of the item frame. + :type rotation: int, optional, default: 0 + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + item: Slot = entry(SlotEME, Slot(None)) + rotation: int = entry(VarIntEME, 0) + + __slots__ = () + + +class GlowingItemFrameEM(ItemFrameEM): + """Entity representing a glowing item frame. + + Inherited from :class:`ItemFrameEM`: + + :param item: The item in the item frame. + :type item: :class:`Slot`, optional, default: :attr:`Slot(None)` + :param rotation: The rotation of the item frame. + :type rotation: int, optional, default: 0 + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + __slots__ = () + + +class PaintingEM(EntityEM): + """Entity representing a painting. + + :param painting_type: The type of painting variant. + :type painting_type: int, optional, default: 0 + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + painting_type: int = entry(PaintingVariantEME, 0) + + __slots__ = () + + +class ItemEntityEM(EntityEM): + """Entity representing an item. + + :param item: The item in the item entity. + :type item: :class:`Slot`, optional, default: :attr:`Slot(None)` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + item: Slot = entry(SlotEME, Slot(None)) + + __slots__ = () + + +class LivingEntityEM(EntityEM): + """Entity that represents a living entity. + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + _hand_states: ClassVar[int] = entry(ByteEME, 0) + is_hand_active: bool = proxy(_hand_states, BoolMasked, mask=0x1) + active_hand: int = proxy(_hand_states, BoolMasked, mask=0x2) + is_riptide_spin_attack: bool = proxy(_hand_states, BoolMasked, mask=0x4) + health: float = entry(FloatEME, 1.0) + potion_effect_color: int = entry(VarIntEME, 0) + is_potion_effect_ambient: bool = entry(BooleanEME, False) + num_arrows: int = entry(VarIntEME, 0) + num_bee_stingers: int = entry(VarIntEME, 0) + sleeping_bed_location: Position | None = entry(OptPositionEME, None) + + __slots__ = () + + +class PlayerEM(LivingEntityEM): + """Player entity. + + :param additional_hearts: Additional hearts of the player. + :type additional_hearts: float, optional, default: 0.0 + :param score: The score of the player. + :type score: int, optional, default: 0 + :param cape_enabled: Whether the cape is enabled. (this affects :attr:`_displayed_skin_parts`) + :type cape_enabled: bool, optional + :param jacket_enabled: Whether the jacket is enabled. (this affects :attr:`_displayed_skin_parts`) + :type jacket_enabled: bool, optional + :param left_sleeve_enabled: Whether the left sleeve is enabled. (this affects :attr:`_displayed_skin_parts`) + :type left_sleeve_enabled: bool, optional + :param right_sleeve_enabled: Whether the right sleeve is enabled. (this affects :attr:`_displayed_skin_parts`) + :type right_sleeve_enabled: bool, optional + :param left_pants_leg_enabled: Whether the left pants leg is enabled. (this affects :attr:`_displayed_skin_parts`) + :type left_pants_leg_enabled: bool, optional + :param right_pants_leg_enabled: Whether the right pants leg is enabled. + (this affects :attr:`_displayed_skin_parts`) + :type right_pants_leg_enabled: bool, optional + :param hat_enabled: Whether the hat is enabled. (this affects :attr:`_displayed_skin_parts`) + :type hat_enabled: bool, optional + :param main_hand: The main hand of the player (0: Left, 1: Right). + :type main_hand: int, optional, default: 1 + :param left_shoulder_entity_data: Left shoulder entity data (for occupying parrot). + :type left_shoulder_entity_data: :class:`NBTag`, optional, default: :attr:`EndNBT()` + :param right_shoulder_entity_data: Right shoulder entity data (for occupying parrot). + :type right_shoulder_entity_data: :class:`NBTag`, optional, default: :attr:`EndNBT()` + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + additional_hearts: float = entry(FloatEME, 0.0) + score: int = entry(VarIntEME, 0) + _displayed_skin_parts: ClassVar[int] = entry(ByteEME, 0) + cape_enabled: bool = proxy(_displayed_skin_parts, BoolMasked, mask=0x1) + jacket_enabled: bool = proxy(_displayed_skin_parts, BoolMasked, mask=0x2) + left_sleeve_enabled: bool = proxy(_displayed_skin_parts, BoolMasked, mask=0x4) + right_sleeve_enabled: bool = proxy(_displayed_skin_parts, BoolMasked, mask=0x8) + left_pants_leg_enabled: bool = proxy(_displayed_skin_parts, BoolMasked, mask=0x10) + right_pants_leg_enabled: bool = proxy(_displayed_skin_parts, BoolMasked, mask=0x20) + hat_enabled: bool = proxy(_displayed_skin_parts, BoolMasked, mask=0x40) + main_hand: int = entry(ByteEME, 1) + left_shoulder_entity_data: NBTag = entry(NBTagEME, EndNBT()) + right_shoulder_entity_data: NBTag = entry(NBTagEME, EndNBT()) + + __slots__ = () + + +class ArmorStandEM(LivingEntityEM): + """Entity representing an armor stand. + + :param is_small: Whether the armor stand is small. (this affects :attr:`_armorstand_flags`) + :type is_small: bool, optional + :param has_arms: Whether the armor stand has arms. (this affects :attr:`_armorstand_flags`) + :type has_arms: bool, optional + :param has_no_base_plate: Whether the armor stand has no base plate. (this affects :attr:`_armorstand_flags`) + :type has_no_base_plate: bool, optional + :param is_marker: Whether the armor stand is a marker. (this affects :attr:`_armorstand_flags`) + :type is_marker: bool, optional + :param head_rotation: Rotation of the armor stand's head. + :type head_rotation: :class:`Vec3`, optional, default: :attr:`Vec3(0.0, 0.0, 0.0)` + :param body_rotation: Rotation of the armor stand's body. + :type body_rotation: :class:`Vec3`, optional, default: :attr:`Vec3(0.0, 0.0, 0.0)` + :param left_arm_rotation: Rotation of the armor stand's left arm. + :type left_arm_rotation: :class:`Vec3`, optional, default: :attr:`Vec3(-10.0, 0.0, -10.0)` + :param right_arm_rotation: Rotation of the armor stand's right arm. + :type right_arm_rotation: :class:`Vec3`, optional, default: :attr:`Vec3(-15.0, 0.0, 10.0)` + :param left_leg_rotation: Rotation of the armor stand's left leg. + :type left_leg_rotation: :class:`Vec3`, optional, default: :attr:`Vec3(-1.0, 0.0, -1.0)` + :param right_leg_rotation: Rotation of the armor stand's right leg. + :type right_leg_rotation: :class:`Vec3`, optional, default: :attr:`Vec3(1.0, 0.0, 1.0)` + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + _armorstand_flags: ClassVar[int] = entry(ByteEME, 0) + is_small: bool = proxy(_armorstand_flags, BoolMasked, mask=0x1) + has_arms: bool = proxy(_armorstand_flags, BoolMasked, mask=0x4) + has_no_base_plate: bool = proxy(_armorstand_flags, BoolMasked, mask=0x8) + is_marker: bool = proxy(_armorstand_flags, BoolMasked, mask=0x10) + head_rotation: Vec3 = entry(RotationEME, Vec3(0.0, 0.0, 0.0)) + body_rotation: Vec3 = entry(RotationEME, Vec3(0.0, 0.0, 0.0)) + left_arm_rotation: Vec3 = entry(RotationEME, Vec3(-10.0, 0.0, -10.0)) + right_arm_rotation: Vec3 = entry(RotationEME, Vec3(-15.0, 0.0, 10.0)) + left_leg_rotation: Vec3 = entry(RotationEME, Vec3(-1.0, 0.0, -1.0)) + right_leg_rotation: Vec3 = entry(RotationEME, Vec3(1.0, 0.0, 1.0)) + + __slots__ = () + + +class MobEM(LivingEntityEM): + """Generic mobile entity. + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + _mob_flags: ClassVar[int] = entry(ByteEME, 0) + no_ai: bool = proxy(_mob_flags, BoolMasked, mask=0x1) + is_left_handed: bool = proxy(_mob_flags, BoolMasked, mask=0x2) + is_aggressive: bool = proxy(_mob_flags, BoolMasked, mask=0x4) + + __slots__ = () + + +class AmbientCreatureEM(MobEM): + """Entity that represents an ambient creature. + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + __slots__ = () + + +class BatEM(AmbientCreatureEM): + """Entity that represents a bat. + + :param is_hanging: Whether the bat is hanging upside down. (this affects :attr:`_bat_flags`) + :type is_hanging: bool, optional + + Inherited from :class:`AmbientCreatureEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + _bat_flags: ClassVar[int] = entry(ByteEME, 0) + is_hanging: bool = proxy(_bat_flags, BoolMasked, mask=0x1) + + __slots__ = () + + +class PathfinderMobEM(MobEM): + """Entity that represents a pathfinder mob. + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + __slots__ = () + + +class WaterAnimalEM(PathfinderMobEM): + """Entity that represents a water-dwelling animal. + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + __slots__ = () + + +class SquidEM(WaterAnimalEM): + """Entity that represents a squid. + + Inherited from :class:`WaterAnimalEM`: + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + __slots__ = () + + +class DolphinEM(WaterAnimalEM): + """Entity that represents a dolphin. + + :param treasure_position: The position of the dolphin's treasure. + :type treasure_position: :class:`Position`, optional, default: :attr:`Position(0, 0, 0)` + :param has_fish: Whether the dolphin has fish. + :type has_fish: bool, optional, default: False + :param moisture_level: The moisture level of the dolphin. + :type moisture_level: int, optional, default: 2400 + + Inherited from :class:`WaterAnimalEM`: + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + treasure_position: Position = entry(PositionEME, Position(0, 0, 0)) + has_fish: bool = entry(BooleanEME, False) + moisture_level: int = entry(VarIntEME, 2400) + + __slots__ = () + + +class AbstractFishEM(WaterAnimalEM): + """Entity that represents an abstract fish. + + :param from_bucket: Whether the fish is from a bucket. + :type from_bucket: bool, optional, default: False + + Inherited from :class:`WaterAnimalEM`: + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + from_bucket: bool = entry(BooleanEME, False) + + __slots__ = () + + +class CodEM(AbstractFishEM): + """Entity that represents a cod fish. + + Inherited from :class:`AbstractFishEM`: + + :param from_bucket: Whether the fish is from a bucket. + :type from_bucket: bool, optional, default: False + + Inherited from :class:`WaterAnimalEM`: + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + __slots__ = () + + +class PufferFishEM(AbstractFishEM): + """Entity that represents a puffer fish. + + :param puff_state: The state of puffing of the puffer fish, varies from 0 to 2. + :type puff_state: int, optional, default: 0 + + Inherited from :class:`AbstractFishEM`: + + :param from_bucket: Whether the fish is from a bucket. + :type from_bucket: bool, optional, default: False + + Inherited from :class:`WaterAnimalEM`: + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + puff_state: int = entry(VarIntEME, 0) + + __slots__ = () + + +class SalmonEM(AbstractFishEM): + """Entity that represents a salmon fish. + + Inherited from :class:`AbstractFishEM`: + + :param from_bucket: Whether the fish is from a bucket. + :type from_bucket: bool, optional, default: False + + Inherited from :class:`WaterAnimalEM`: + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + __slots__ = () + + +class TropicalFishEM(AbstractFishEM): + """Entity that represents a tropical fish. + + :param variant: The variant of the tropical fish. + :type variant: int, optional, default: 0 + + Inherited from :class:`AbstractFishEM`: + + :param from_bucket: Whether the fish is from a bucket. + :type from_bucket: bool, optional, default: False + + Inherited from :class:`WaterAnimalEM`: + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + variant: int = entry(VarIntEME, 0) + + __slots__ = () + + +class TadpoleEM(AbstractFishEM): + """Entity that represents a tadpole. + + Inherited from :class:`AbstractFishEM`: + + :param from_bucket: Whether the fish is from a bucket. + :type from_bucket: bool, optional, default: False + + Inherited from :class:`WaterAnimalEM`: + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + __slots__ = () + + +class AgeableMobEM(PathfinderMobEM): + """Entity that represents an ageable mob. + + :param is_baby: Whether the mob is a baby. + :type is_baby: bool, optional, default: False + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + is_baby: bool = entry(BooleanEME, False) + + __slots__ = () + + +class AnimalEM(AgeableMobEM): + """Entity that represents an animal. + + Inherited from :class:`AgeableMobEM`: + + :param is_baby: Whether the mob is a baby. + :type is_baby: bool, optional, default: False + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + __slots__ = () + + +class SnifferEM(AnimalEM): + """Entity that represents a sniffer. + + :param sniffer_state: The state of the sniffer. + :type sniffer_state: :class:`SnifferState`, optional, default: :attr:`SnifferState.IDLING` + :param drop_seed_at_tick: The tick at which the sniffer will drop seed. + :type drop_seed_at_tick: int, optional, default: 0 + + Inherited from :class:`AnimalEM`: + + Inherited from :class:`AgeableMobEM`: + + :param is_baby: Whether the mob is a baby. + :type is_baby: bool, optional, default: False + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + sniffer_state: SnifferState = entry(SnifferStateEME, SnifferState.IDLING) + drop_seed_at_tick: int = entry(VarIntEME, 0) + + __slots__ = () + + +class AbstractHorseEM(AnimalEM): + """Entity that represents an abstract horse. + + :param is_tame: Whether the horse is tame. (this affects :attr:`_horse_flags`) + :type is_tame: bool, optional + :param is_saddled: Whether the horse is saddled. (this affects :attr:`_horse_flags`) + :type is_saddled: bool, optional + :param has_bred: Whether the horse has bred. (this affects :attr:`_horse_flags`) + :type has_bred: bool, optional + :param is_eating: Whether the horse is eating. (this affects :attr:`_horse_flags`) + :type is_eating: bool, optional + :param is_rearing: Whether the horse is rearing (on hind legs). (this affects :attr:`_horse_flags`) + :type is_rearing: bool, optional + :param is_mouth_open: Whether the horse's mouth is open. (this affects :attr:`_horse_flags`) + :type is_mouth_open: bool, optional + + Inherited from :class:`AnimalEM`: + + Inherited from :class:`AgeableMobEM`: + + :param is_baby: Whether the mob is a baby. + :type is_baby: bool, optional, default: False + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + _horse_flags: ClassVar[int] = entry(ByteEME, 0) + is_tame: bool = proxy(_horse_flags, BoolMasked, mask=0x2) + is_saddled: bool = proxy(_horse_flags, BoolMasked, mask=0x4) + has_bred: bool = proxy(_horse_flags, BoolMasked, mask=0x8) + is_eating: bool = proxy(_horse_flags, BoolMasked, mask=0x10) + is_rearing: bool = proxy(_horse_flags, BoolMasked, mask=0x20) + is_mouth_open: bool = proxy(_horse_flags, BoolMasked, mask=0x40) + + __slots__ = () + + +class HorseEM(AbstractHorseEM): + """Entity that represents a horse. + + :param variant: The variant of the horse representing its color and style. + :type variant: int, optional, default: 0 + + Inherited from :class:`AbstractHorseEM`: + + :param is_tame: Whether the horse is tame. (this affects :attr:`_horse_flags`) + :type is_tame: bool, optional + :param is_saddled: Whether the horse is saddled. (this affects :attr:`_horse_flags`) + :type is_saddled: bool, optional + :param has_bred: Whether the horse has bred. (this affects :attr:`_horse_flags`) + :type has_bred: bool, optional + :param is_eating: Whether the horse is eating. (this affects :attr:`_horse_flags`) + :type is_eating: bool, optional + :param is_rearing: Whether the horse is rearing (on hind legs). (this affects :attr:`_horse_flags`) + :type is_rearing: bool, optional + :param is_mouth_open: Whether the horse's mouth is open. (this affects :attr:`_horse_flags`) + :type is_mouth_open: bool, optional + + Inherited from :class:`AnimalEM`: + + Inherited from :class:`AgeableMobEM`: + + :param is_baby: Whether the mob is a baby. + :type is_baby: bool, optional, default: False + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + variant: int = entry(VarIntEME, 0) + + __slots__ = () + + +class ZombieHorseEM(AbstractHorseEM): + """Entity that represents a zombie horse. + + Inherited from :class:`AbstractHorseEM`: + + :param is_tame: Whether the horse is tame. (this affects :attr:`_horse_flags`) + :type is_tame: bool, optional + :param is_saddled: Whether the horse is saddled. (this affects :attr:`_horse_flags`) + :type is_saddled: bool, optional + :param has_bred: Whether the horse has bred. (this affects :attr:`_horse_flags`) + :type has_bred: bool, optional + :param is_eating: Whether the horse is eating. (this affects :attr:`_horse_flags`) + :type is_eating: bool, optional + :param is_rearing: Whether the horse is rearing (on hind legs). (this affects :attr:`_horse_flags`) + :type is_rearing: bool, optional + :param is_mouth_open: Whether the horse's mouth is open. (this affects :attr:`_horse_flags`) + :type is_mouth_open: bool, optional + + Inherited from :class:`AnimalEM`: + + Inherited from :class:`AgeableMobEM`: + + :param is_baby: Whether the mob is a baby. + :type is_baby: bool, optional, default: False + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + __slots__ = () + + +class SkeletonHorseEM(AbstractHorseEM): + """Entity that represents a skeleton horse. + + Inherited from :class:`AbstractHorseEM`: + + :param is_tame: Whether the horse is tame. (this affects :attr:`_horse_flags`) + :type is_tame: bool, optional + :param is_saddled: Whether the horse is saddled. (this affects :attr:`_horse_flags`) + :type is_saddled: bool, optional + :param has_bred: Whether the horse has bred. (this affects :attr:`_horse_flags`) + :type has_bred: bool, optional + :param is_eating: Whether the horse is eating. (this affects :attr:`_horse_flags`) + :type is_eating: bool, optional + :param is_rearing: Whether the horse is rearing (on hind legs). (this affects :attr:`_horse_flags`) + :type is_rearing: bool, optional + :param is_mouth_open: Whether the horse's mouth is open. (this affects :attr:`_horse_flags`) + :type is_mouth_open: bool, optional + + Inherited from :class:`AnimalEM`: + + Inherited from :class:`AgeableMobEM`: + + :param is_baby: Whether the mob is a baby. + :type is_baby: bool, optional, default: False + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + __slots__ = () + + +class CamelEM(AbstractHorseEM): + """Entity that represents a camel. + + :param is_dashing: Whether the camel is dashing. + :type is_dashing: bool, optional, default: False + :param last_pose_change_tick: The tick at which the camel's pose was last changed. + :type last_pose_change_tick: int, optional, default: 0 + + Inherited from :class:`AbstractHorseEM`: + + :param is_tame: Whether the horse is tame. (this affects :attr:`_horse_flags`) + :type is_tame: bool, optional + :param is_saddled: Whether the horse is saddled. (this affects :attr:`_horse_flags`) + :type is_saddled: bool, optional + :param has_bred: Whether the horse has bred. (this affects :attr:`_horse_flags`) + :type has_bred: bool, optional + :param is_eating: Whether the horse is eating. (this affects :attr:`_horse_flags`) + :type is_eating: bool, optional + :param is_rearing: Whether the horse is rearing (on hind legs). (this affects :attr:`_horse_flags`) + :type is_rearing: bool, optional + :param is_mouth_open: Whether the horse's mouth is open. (this affects :attr:`_horse_flags`) + :type is_mouth_open: bool, optional + + Inherited from :class:`AnimalEM`: + + Inherited from :class:`AgeableMobEM`: + + :param is_baby: Whether the mob is a baby. + :type is_baby: bool, optional, default: False + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + is_dashing: bool = entry(BooleanEME, False) + last_pose_change_tick: int = entry(VarLongEME, 0) + + __slots__ = () + + +class ChestedHorseEM(AbstractHorseEM): + """Entity that represents a horse with a chest. + + :param has_chest: Whether the horse has a chest. + :type has_chest: bool, optional, default: False + + Inherited from :class:`AbstractHorseEM`: + + :param is_tame: Whether the horse is tame. (this affects :attr:`_horse_flags`) + :type is_tame: bool, optional + :param is_saddled: Whether the horse is saddled. (this affects :attr:`_horse_flags`) + :type is_saddled: bool, optional + :param has_bred: Whether the horse has bred. (this affects :attr:`_horse_flags`) + :type has_bred: bool, optional + :param is_eating: Whether the horse is eating. (this affects :attr:`_horse_flags`) + :type is_eating: bool, optional + :param is_rearing: Whether the horse is rearing (on hind legs). (this affects :attr:`_horse_flags`) + :type is_rearing: bool, optional + :param is_mouth_open: Whether the horse's mouth is open. (this affects :attr:`_horse_flags`) + :type is_mouth_open: bool, optional + + Inherited from :class:`AnimalEM`: + + Inherited from :class:`AgeableMobEM`: + + :param is_baby: Whether the mob is a baby. + :type is_baby: bool, optional, default: False + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + has_chest: bool = entry(BooleanEME, False) + + __slots__ = () + + +class DonkeyEM(ChestedHorseEM): + """Entity that represents a donkey. + + Inherited from :class:`ChestedHorseEM`: + + :param has_chest: Whether the horse has a chest. + :type has_chest: bool, optional, default: False + + Inherited from :class:`AbstractHorseEM`: + + :param is_tame: Whether the horse is tame. (this affects :attr:`_horse_flags`) + :type is_tame: bool, optional + :param is_saddled: Whether the horse is saddled. (this affects :attr:`_horse_flags`) + :type is_saddled: bool, optional + :param has_bred: Whether the horse has bred. (this affects :attr:`_horse_flags`) + :type has_bred: bool, optional + :param is_eating: Whether the horse is eating. (this affects :attr:`_horse_flags`) + :type is_eating: bool, optional + :param is_rearing: Whether the horse is rearing (on hind legs). (this affects :attr:`_horse_flags`) + :type is_rearing: bool, optional + :param is_mouth_open: Whether the horse's mouth is open. (this affects :attr:`_horse_flags`) + :type is_mouth_open: bool, optional + + Inherited from :class:`AnimalEM`: + + Inherited from :class:`AgeableMobEM`: + + :param is_baby: Whether the mob is a baby. + :type is_baby: bool, optional, default: False + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + __slots__ = () + + +class LlamaEM(ChestedHorseEM): + """Entity that represents a llama. + + :param strength: The strength of the llama, representing the number of columns of 3 slots in its + inventory once a chest is equipped. + :type strength: int, optional, default: 0 + :param carpet_color: The color of the carpet equipped on the llama, represented as a dye color. -1 if no + carpet is equipped. + :type carpet_color: int, optional, default: -1 + :param variant: The variant of the llama. + :type variant: int, optional, default: 0 + + Inherited from :class:`ChestedHorseEM`: + + :param has_chest: Whether the horse has a chest. + :type has_chest: bool, optional, default: False + + Inherited from :class:`AbstractHorseEM`: + + :param is_tame: Whether the horse is tame. (this affects :attr:`_horse_flags`) + :type is_tame: bool, optional + :param is_saddled: Whether the horse is saddled. (this affects :attr:`_horse_flags`) + :type is_saddled: bool, optional + :param has_bred: Whether the horse has bred. (this affects :attr:`_horse_flags`) + :type has_bred: bool, optional + :param is_eating: Whether the horse is eating. (this affects :attr:`_horse_flags`) + :type is_eating: bool, optional + :param is_rearing: Whether the horse is rearing (on hind legs). (this affects :attr:`_horse_flags`) + :type is_rearing: bool, optional + :param is_mouth_open: Whether the horse's mouth is open. (this affects :attr:`_horse_flags`) + :type is_mouth_open: bool, optional + + Inherited from :class:`AnimalEM`: + + Inherited from :class:`AgeableMobEM`: + + :param is_baby: Whether the mob is a baby. + :type is_baby: bool, optional, default: False + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + strength: int = entry(VarIntEME, 0) + carpet_color: int = entry(VarIntEME, -1) + variant: int = entry(VarIntEME, 0) + + __slots__ = () + + +class TraderLlamaEM(LlamaEM): + """Entity that represents a trader llama. + + Inherited from :class:`LlamaEM`: + + :param strength: The strength of the llama, representing the number of columns of 3 slots in its + inventory once a chest is equipped. + :type strength: int, optional, default: 0 + :param carpet_color: The color of the carpet equipped on the llama, represented as a dye color. -1 if no + carpet is equipped. + :type carpet_color: int, optional, default: -1 + :param variant: The variant of the llama. + :type variant: int, optional, default: 0 + + Inherited from :class:`ChestedHorseEM`: + + :param has_chest: Whether the horse has a chest. + :type has_chest: bool, optional, default: False + + Inherited from :class:`AbstractHorseEM`: + + :param is_tame: Whether the horse is tame. (this affects :attr:`_horse_flags`) + :type is_tame: bool, optional + :param is_saddled: Whether the horse is saddled. (this affects :attr:`_horse_flags`) + :type is_saddled: bool, optional + :param has_bred: Whether the horse has bred. (this affects :attr:`_horse_flags`) + :type has_bred: bool, optional + :param is_eating: Whether the horse is eating. (this affects :attr:`_horse_flags`) + :type is_eating: bool, optional + :param is_rearing: Whether the horse is rearing (on hind legs). (this affects :attr:`_horse_flags`) + :type is_rearing: bool, optional + :param is_mouth_open: Whether the horse's mouth is open. (this affects :attr:`_horse_flags`) + :type is_mouth_open: bool, optional + + Inherited from :class:`AnimalEM`: + + Inherited from :class:`AgeableMobEM`: + + :param is_baby: Whether the mob is a baby. + :type is_baby: bool, optional, default: False + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + __slots__ = () + + +class MuleEM(ChestedHorseEM): + """Entity that represents a mule. + + Inherited from :class:`ChestedHorseEM`: + + :param has_chest: Whether the horse has a chest. + :type has_chest: bool, optional, default: False + + Inherited from :class:`AbstractHorseEM`: + + :param is_tame: Whether the horse is tame. (this affects :attr:`_horse_flags`) + :type is_tame: bool, optional + :param is_saddled: Whether the horse is saddled. (this affects :attr:`_horse_flags`) + :type is_saddled: bool, optional + :param has_bred: Whether the horse has bred. (this affects :attr:`_horse_flags`) + :type has_bred: bool, optional + :param is_eating: Whether the horse is eating. (this affects :attr:`_horse_flags`) + :type is_eating: bool, optional + :param is_rearing: Whether the horse is rearing (on hind legs). (this affects :attr:`_horse_flags`) + :type is_rearing: bool, optional + :param is_mouth_open: Whether the horse's mouth is open. (this affects :attr:`_horse_flags`) + :type is_mouth_open: bool, optional + + Inherited from :class:`AnimalEM`: + + Inherited from :class:`AgeableMobEM`: + + :param is_baby: Whether the mob is a baby. + :type is_baby: bool, optional, default: False + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + __slots__ = () + + +class AxolotlEM(AnimalEM): + """Entity that represents an axolotl. + + :param variant: The variant of the axolotl. + :type variant: int, optional, default: 0 + :param is_playing_dead: Whether the axolotl is currently playing dead. + :type is_playing_dead: bool, optional, default: False + :param is_spawned_from_bucket: Whether the axolotl was spawned from a bucket. + :type is_spawned_from_bucket: bool, optional, default: False + + Inherited from :class:`AnimalEM`: + + Inherited from :class:`AgeableMobEM`: + + :param is_baby: Whether the mob is a baby. + :type is_baby: bool, optional, default: False + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + variant: int = entry(VarIntEME, 0) + is_playing_dead: bool = entry(BooleanEME, False) + is_spawned_from_bucket: bool = entry(BooleanEME, False) + + __slots__ = () + + +class BeeEM(AnimalEM): + """Entity that represents a bee. + + :param is_angry: Whether the bee is angry. (this affects :attr:`_bee_flags`) + :type is_angry: bool, optional + :param has_stung: Whether the bee has stung. (this affects :attr:`_bee_flags`) + :type has_stung: bool, optional + :param has_nectar: Whether the bee has nectar. (this affects :attr:`_bee_flags`) + :type has_nectar: bool, optional + :param anger_time: The time in ticks for which the bee remains angry. + :type anger_time: int, optional, default: 0 + + Inherited from :class:`AnimalEM`: + + Inherited from :class:`AgeableMobEM`: + + :param is_baby: Whether the mob is a baby. + :type is_baby: bool, optional, default: False + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + _bee_flags: ClassVar[int] = entry(ByteEME, 0) + is_angry: bool = proxy(_bee_flags, BoolMasked, mask=0x2) + has_stung: bool = proxy(_bee_flags, BoolMasked, mask=0x4) + has_nectar: bool = proxy(_bee_flags, BoolMasked, mask=0x8) + anger_time: int = entry(VarIntEME, 0) + + __slots__ = () + + +class FoxEM(AnimalEM): + """Entity that represents a fox. + + :param fox_type: The type of the fox. + :type fox_type: int, optional, default: 0 + :param is_sitting: Whether the fox is sitting. (this affects :attr:`_fox_flags`) + :type is_sitting: bool, optional + :param is_fox_crouching: Whether the fox is crouching. (this affects :attr:`_fox_flags`) + :type is_fox_crouching: bool, optional + :param is_interested: Whether the fox is interested. (this affects :attr:`_fox_flags`) + :type is_interested: bool, optional + :param is_pouncing: Whether the fox is pouncing. (this affects :attr:`_fox_flags`) + :type is_pouncing: bool, optional + :param is_sleeping: Whether the fox is sleeping. (this affects :attr:`_fox_flags`) + :type is_sleeping: bool, optional + :param is_faceplanted: Whether the fox is faceplanted. (this affects :attr:`_fox_flags`) + :type is_faceplanted: bool, optional + :param is_defending: Whether the fox is defending. (this affects :attr:`_fox_flags`) + :type is_defending: bool, optional + :param trusted_uuid: The UUID of the player that the fox trusts. + :type trusted_uuid: :class:`UUID|None`, optional, default: :attr:`None` + :param trusted_uuid_2: Another player that the fox trusts. + :type trusted_uuid_2: :class:`UUID|None`, optional, default: :attr:`None` + + Inherited from :class:`AnimalEM`: + + Inherited from :class:`AgeableMobEM`: + + :param is_baby: Whether the mob is a baby. + :type is_baby: bool, optional, default: False + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + fox_type: int = entry(VarIntEME, 0) + _fox_flags: ClassVar[int] = entry(ByteEME, 0) + is_sitting: bool = proxy(_fox_flags, BoolMasked, mask=0x1) + is_fox_crouching: bool = proxy(_fox_flags, BoolMasked, mask=0x4) + is_interested: bool = proxy(_fox_flags, BoolMasked, mask=0x8) + is_pouncing: bool = proxy(_fox_flags, BoolMasked, mask=0x10) + is_sleeping: bool = proxy(_fox_flags, BoolMasked, mask=0x20) + is_faceplanted: bool = proxy(_fox_flags, BoolMasked, mask=0x40) + is_defending: bool = proxy(_fox_flags, BoolMasked, mask=0x80) + trusted_uuid: UUID | None = entry(OptUUIDEME, None) + trusted_uuid_2: UUID | None = entry(OptUUIDEME, None) + + __slots__ = () + + +class FrogEM(AnimalEM): + """Entity that represents a frog. + + :param variant: The variant of the frog. + :type variant: int, optional, default: 0 + :param tongue_target: The target of the frog's tongue. + :type tongue_target: int | None, optional, default: 0 + + Inherited from :class:`AnimalEM`: + + Inherited from :class:`AgeableMobEM`: + + :param is_baby: Whether the mob is a baby. + :type is_baby: bool, optional, default: False + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + variant: int = entry(FrogVariantEME, 0) + tongue_target: int | None = entry(OptVarIntEME, 0) + + __slots__ = () + + +class OcelotEM(AnimalEM): + """Entity that represents an ocelot. + + :param is_trusting: Whether the ocelot is trusting. + :type is_trusting: bool, optional, default: False + + Inherited from :class:`AnimalEM`: + + Inherited from :class:`AgeableMobEM`: + + :param is_baby: Whether the mob is a baby. + :type is_baby: bool, optional, default: False + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + is_trusting: bool = entry(BooleanEME, False) + + __slots__ = () + + +class PandaEM(AnimalEM): + """Entity that represents a panda. + + :param breed_timer: The breed timer of the panda. + :type breed_timer: int, optional, default: 0 + :param sneeze_timer: The sneeze timer of the panda. + :type sneeze_timer: int, optional, default: 0 + :param eat_timer: The eat timer of the panda. + :type eat_timer: int, optional, default: 0 + :param main_gene: The main gene of the panda. + :type main_gene: int, optional, default: 0 + :param hidden_gene: The hidden gene of the panda. + :type hidden_gene: int, optional, default: 0 + :param is_sneezing: Whether the panda is sneezing. (this affects :attr:`_panda_flags`) + :type is_sneezing: bool, optional + :param is_rolling: Whether the panda is rolling. (this affects :attr:`_panda_flags`) + :type is_rolling: bool, optional + :param is_sitting: Whether the panda is sitting. (this affects :attr:`_panda_flags`) + :type is_sitting: bool, optional + :param is_on_back: Whether the panda is on its back. (this affects :attr:`_panda_flags`) + :type is_on_back: bool, optional + + Inherited from :class:`AnimalEM`: + + Inherited from :class:`AgeableMobEM`: + + :param is_baby: Whether the mob is a baby. + :type is_baby: bool, optional, default: False + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + breed_timer: int = entry(VarIntEME, 0) + sneeze_timer: int = entry(VarIntEME, 0) + eat_timer: int = entry(VarIntEME, 0) + main_gene: int = entry(ByteEME, 0) + hidden_gene: int = entry(ByteEME, 0) + _panda_flags: ClassVar[int] = entry(ByteEME, 0) + is_sneezing: bool = proxy(_panda_flags, BoolMasked, mask=0x2) + is_rolling: bool = proxy(_panda_flags, BoolMasked, mask=0x4) + is_sitting: bool = proxy(_panda_flags, BoolMasked, mask=0x8) + is_on_back: bool = proxy(_panda_flags, BoolMasked, mask=0x10) + + __slots__ = () + + +class PigEM(AnimalEM): + """Entity that represents a pig. + + :param has_saddle: Whether the pig has a saddle. + :type has_saddle: bool, optional, default: False + :param boost_time: Total time to 'boost' with a carrot on a stick for. + :type boost_time: int, optional, default: 0 + + Inherited from :class:`AnimalEM`: + + Inherited from :class:`AgeableMobEM`: + + :param is_baby: Whether the mob is a baby. + :type is_baby: bool, optional, default: False + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + has_saddle: bool = entry(BooleanEME, False) + boost_time: int = entry(VarIntEME, 0) + + __slots__ = () + + +class RabbitEM(AnimalEM): + """Entity that represents a rabbit. + + :param rabbit_type: The type of the rabbit. + :type rabbit_type: int, optional, default: 0 + + Inherited from :class:`AnimalEM`: + + Inherited from :class:`AgeableMobEM`: + + :param is_baby: Whether the mob is a baby. + :type is_baby: bool, optional, default: False + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + rabbit_type: int = entry(VarIntEME, 0) + + __slots__ = () + + +class TurtleEM(AnimalEM): + """Entity that represents a turtle. + + :param home_pos: The home position of the turtle. + :type home_pos: :class:`Position`, optional, default: :attr:`Position(0, 0, 0)` + :param has_egg: Whether the turtle has an egg. + :type has_egg: bool, optional, default: False + :param is_laying_egg: Whether the turtle is laying an egg. + :type is_laying_egg: bool, optional, default: False + :param travel_pos: The travel position of the turtle. + :type travel_pos: :class:`Position`, optional, default: :attr:`Position(0, 0, 0)` + :param is_going_home: Whether the turtle is going home. + :type is_going_home: bool, optional, default: False + :param is_traveling: Whether the turtle is traveling. + :type is_traveling: bool, optional, default: False + + Inherited from :class:`AnimalEM`: + + Inherited from :class:`AgeableMobEM`: + + :param is_baby: Whether the mob is a baby. + :type is_baby: bool, optional, default: False + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + home_pos: Position = entry(PositionEME, Position(0, 0, 0)) + has_egg: bool = entry(BooleanEME, False) + is_laying_egg: bool = entry(BooleanEME, False) + travel_pos: Position = entry(PositionEME, Position(0, 0, 0)) + is_going_home: bool = entry(BooleanEME, False) + is_traveling: bool = entry(BooleanEME, False) + + __slots__ = () + + +class PolarBearEM(AnimalEM): + """Entity that represents a polar bear. + + :param is_standing_up: Whether the polar bear is standing up. + :type is_standing_up: bool, optional, default: False + + Inherited from :class:`AnimalEM`: + + Inherited from :class:`AgeableMobEM`: + + :param is_baby: Whether the mob is a baby. + :type is_baby: bool, optional, default: False + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + is_standing_up: bool = entry(BooleanEME, False) + + __slots__ = () + + +class ChickenEM(AnimalEM): + """Entity representing a chicken. + + Inherited from :class:`AnimalEM`: + + Inherited from :class:`AgeableMobEM`: + + :param is_baby: Whether the mob is a baby. + :type is_baby: bool, optional, default: False + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + __slots__ = () + + +class CowEM(AnimalEM): + """Entity representing a cow. + + Inherited from :class:`AnimalEM`: + + Inherited from :class:`AgeableMobEM`: + + :param is_baby: Whether the mob is a baby. + :type is_baby: bool, optional, default: False + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + __slots__ = () + + +class MooshroomEM(CowEM): + """Entity representing a mooshroom. + + :param variant: The variant of the mooshroom: 'red' or 'brown'. + :type variant: str, optional, default: "red" + + Inherited from :class:`CowEM`: + + Inherited from :class:`AnimalEM`: + + Inherited from :class:`AgeableMobEM`: + + :param is_baby: Whether the mob is a baby. + :type is_baby: bool, optional, default: False + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + variant: str = entry(StringEME, "red") + + __slots__ = () + + +class HoglinEM(AnimalEM): + """Entity representing a hoglin. + + :param immune_to_zombification: Whether the hoglin is immune to zombification. + :type immune_to_zombification: bool, optional, default: False + + Inherited from :class:`AnimalEM`: + + Inherited from :class:`AgeableMobEM`: + + :param is_baby: Whether the mob is a baby. + :type is_baby: bool, optional, default: False + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + immune_to_zombification: bool = entry(BooleanEME, False) + + __slots__ = () + + +class SheepEM(AnimalEM): + """Entity representing a sheep. + + :param color_id: The color of the sheep. (this affects :attr:`_sheep_data`) + :type color_id: int, optional + :param is_sheared: Whether the sheep is sheared. (this affects :attr:`_sheep_data`) + :type is_sheared: bool, optional + + Inherited from :class:`AnimalEM`: + + Inherited from :class:`AgeableMobEM`: + + :param is_baby: Whether the mob is a baby. + :type is_baby: bool, optional, default: False + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + _sheep_data: ClassVar[int] = entry(ByteEME, 0) + color_id: int = proxy(_sheep_data, BoolMasked, mask=0xF) + is_sheared: bool = proxy(_sheep_data, BoolMasked, mask=0x10) + + __slots__ = () + + +class StriderEM(AnimalEM): + """Entity representing a strider. + + :param boost_duration: Total time to 'boost' with warped fungus on a stick. + :type boost_duration: int, optional, default: 0 + :param is_shaking: Whether the strider is shaking. (True unless riding a vehicle or on or in a block + tagged with strider_warm_blocks (default: lava)) + :type is_shaking: bool, optional, default: False + :param has_saddle: Whether the strider has a saddle. + :type has_saddle: bool, optional, default: False + + Inherited from :class:`AnimalEM`: + + Inherited from :class:`AgeableMobEM`: + + :param is_baby: Whether the mob is a baby. + :type is_baby: bool, optional, default: False + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + boost_duration: int = entry(VarIntEME, 0) + is_shaking: bool = entry(BooleanEME, False) + has_saddle: bool = entry(BooleanEME, False) + + __slots__ = () + + +class GoatEM(AnimalEM): + """Entity representing a goat. + + :param is_screaming_goat: Whether the goat is a screaming goat. + :type is_screaming_goat: bool, optional, default: False + :param has_left_horn: Whether the goat has a left horn. + :type has_left_horn: bool, optional, default: True + :param has_right_horn: Whether the goat has a right horn. + :type has_right_horn: bool, optional, default: True + + Inherited from :class:`AnimalEM`: + + Inherited from :class:`AgeableMobEM`: + + :param is_baby: Whether the mob is a baby. + :type is_baby: bool, optional, default: False + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + is_screaming_goat: bool = entry(BooleanEME, False) + has_left_horn: bool = entry(BooleanEME, True) + has_right_horn: bool = entry(BooleanEME, True) + + __slots__ = () + + +class TameableAnimalEM(AnimalEM): + """Entity representing a tameable animal. + + :param is_sitting: Whether the animal is sitting. (this affects :attr:`_tameable_data`) + :type is_sitting: bool, optional + :param is_tamed: Whether the animal is tamed. (this affects :attr:`_tameable_data`) + :type is_tamed: bool, optional + :param owner_uuid: The UUID of the owner, if the animal is tamed. + :type owner_uuid: :class:`UUID|None`, optional, default: :attr:`None` + + Inherited from :class:`AnimalEM`: + + Inherited from :class:`AgeableMobEM`: + + :param is_baby: Whether the mob is a baby. + :type is_baby: bool, optional, default: False + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + _tameable_data: ClassVar[int] = entry(ByteEME, 0) + is_sitting: bool = proxy(_tameable_data, BoolMasked, mask=0x1) + is_tamed: bool = proxy(_tameable_data, BoolMasked, mask=0x4) + owner_uuid: UUID | None = entry(OptUUIDEME, None) + + __slots__ = () + + +class CatEM(TameableAnimalEM): + """Entity representing a cat. + + :param cat_variant: The variant of the cat. + :type cat_variant: int, optional, default: 0 + :param is_lying: Whether the cat is lying down. + :type is_lying: bool, optional, default: False + :param is_relaxed: Unknown use. When true, the cat's head goes slightly upwards. + :type is_relaxed: bool, optional, default: False + :param collar_color: The color of the cat's collar, using dye values. + :type collar_color: int, optional, default: 14 + + Inherited from :class:`TameableAnimalEM`: + + :param is_sitting: Whether the animal is sitting. (this affects :attr:`_tameable_data`) + :type is_sitting: bool, optional + :param is_tamed: Whether the animal is tamed. (this affects :attr:`_tameable_data`) + :type is_tamed: bool, optional + :param owner_uuid: The UUID of the owner, if the animal is tamed. + :type owner_uuid: :class:`UUID|None`, optional, default: :attr:`None` + + Inherited from :class:`AnimalEM`: + + Inherited from :class:`AgeableMobEM`: + + :param is_baby: Whether the mob is a baby. + :type is_baby: bool, optional, default: False + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + cat_variant: int = entry(CatVariantEME, 0) + is_lying: bool = entry(BooleanEME, False) + is_relaxed: bool = entry(BooleanEME, False) + collar_color: int = entry(VarIntEME, 14) + + __slots__ = () + + +class WolfEM(TameableAnimalEM): + """Entity representing a wolf. + + :param is_begging: Whether the wolf is begging. + :type is_begging: bool, optional, default: False + :param collar_color: The color of the wolf's collar, using dye values. + :type collar_color: int, optional, default: 14 + :param anger_time: The time for which the wolf remains angry. + :type anger_time: int, optional, default: 0 + + Inherited from :class:`TameableAnimalEM`: + + :param is_sitting: Whether the animal is sitting. (this affects :attr:`_tameable_data`) + :type is_sitting: bool, optional + :param is_tamed: Whether the animal is tamed. (this affects :attr:`_tameable_data`) + :type is_tamed: bool, optional + :param owner_uuid: The UUID of the owner, if the animal is tamed. + :type owner_uuid: :class:`UUID|None`, optional, default: :attr:`None` + + Inherited from :class:`AnimalEM`: + + Inherited from :class:`AgeableMobEM`: + + :param is_baby: Whether the mob is a baby. + :type is_baby: bool, optional, default: False + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + is_begging: bool = entry(BooleanEME, False) + collar_color: int = entry(VarIntEME, 14) + anger_time: int = entry(VarIntEME, 0) + + __slots__ = () + + +class ParrotEM(TameableAnimalEM): + """Entity representing a parrot. + + :param variant: The variant of the parrot. + :type variant: int, optional, default: 0 + + Inherited from :class:`TameableAnimalEM`: + + :param is_sitting: Whether the animal is sitting. (this affects :attr:`_tameable_data`) + :type is_sitting: bool, optional + :param is_tamed: Whether the animal is tamed. (this affects :attr:`_tameable_data`) + :type is_tamed: bool, optional + :param owner_uuid: The UUID of the owner, if the animal is tamed. + :type owner_uuid: :class:`UUID|None`, optional, default: :attr:`None` + + Inherited from :class:`AnimalEM`: + + Inherited from :class:`AgeableMobEM`: + + :param is_baby: Whether the mob is a baby. + :type is_baby: bool, optional, default: False + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + variant: int = entry(VarIntEME, 0) + + __slots__ = () + + +class AbstractVillagerEM(AgeableMobEM): + """Entity representing an abstract villager. + + :param head_shake_timer: The head shake timer of the villager, starting at 40 and decrementing each tick. + :type head_shake_timer: int, optional, default: 0 + + Inherited from :class:`AgeableMobEM`: + + :param is_baby: Whether the mob is a baby. + :type is_baby: bool, optional, default: False + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + head_shake_timer: int = entry(VarIntEME, 0) + + __slots__ = () + + +class VillagerEM(AbstractVillagerEM): + """Entity representing a villager. + + :param villager_data: The data associated with the villager. + :type villager_data: tuple[int, int, int], optional, default: (0, 0, 0) + + Inherited from :class:`AbstractVillagerEM`: + + :param head_shake_timer: The head shake timer of the villager, starting at 40 and decrementing each tick. + :type head_shake_timer: int, optional, default: 0 + + Inherited from :class:`AgeableMobEM`: + + :param is_baby: Whether the mob is a baby. + :type is_baby: bool, optional, default: False + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + villager_data: tuple[int, int, int] = entry(VillagerDataEME, (0, 0, 0)) + + __slots__ = () + + +class WanderingTraderEM(AbstractVillagerEM): + """Entity representing a wandering trader. + + Inherited from :class:`AbstractVillagerEM`: + + :param head_shake_timer: The head shake timer of the villager, starting at 40 and decrementing each tick. + :type head_shake_timer: int, optional, default: 0 + + Inherited from :class:`AgeableMobEM`: + + :param is_baby: Whether the mob is a baby. + :type is_baby: bool, optional, default: False + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + __slots__ = () + + +class AbstractGolemEM(PathfinderMobEM): + """Entity representing an abstract golem. + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + __slots__ = () + + +class IronGolemEM(AbstractGolemEM): + """Entity representing an iron golem. + + :param is_player_created: Whether the iron golem was created by a player. (this affects :attr:`_iron_golem_flags`) + :type is_player_created: bool, optional + + Inherited from :class:`AbstractGolemEM`: + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + _iron_golem_flags: ClassVar[int] = entry(ByteEME, 0) + is_player_created: bool = proxy(_iron_golem_flags, BoolMasked, mask=0x1) + + __slots__ = () + + +class SnowGolemEM(AbstractGolemEM): + """Entity representing a snow golem. + + :param has_pumpkin: Whether the snow golem has a pumpkin on its head. (this affects :attr:`_snow_golem_flags`) + :type has_pumpkin: bool, optional + + Inherited from :class:`AbstractGolemEM`: + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + _snow_golem_flags: ClassVar[int] = entry(ByteEME, 16) + has_pumpkin: bool = proxy(_snow_golem_flags, BoolMasked, mask=0x10) + + __slots__ = () + + +class ShulkerEM(AbstractGolemEM): + """Entity representing a shulker. + + :param attach_face: The face to which the shulker is attached. + :type attach_face: :class:`Direction`, optional, default: :attr:`Direction.DOWN` + :param shield_height: The shield height of the shulker. + :type shield_height: int, optional, default: 0 + :param color: The color of the shulker, using dye color values. + :type color: int, optional, default: 16 + + Inherited from :class:`AbstractGolemEM`: + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + attach_face: Direction = entry(DirectionEME, Direction.DOWN) + shield_height: int = entry(ByteEME, 0) + color: int = entry(ByteEME, 16) + + __slots__ = () + + +class MonsterEM(PathfinderMobEM): + """Entity representing a monster. + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + __slots__ = () + + +class BasePiglinEM(MonsterEM): + """Entity representing a base piglin. + + :param is_immune_to_zombification: Indicates if the piglin is immune to zombification. + :type is_immune_to_zombification: bool, optional, default: False + + Inherited from :class:`MonsterEM`: + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + is_immune_to_zombification: bool = entry(BooleanEME, False) + + __slots__ = () + + +class PiglinEM(BasePiglinEM): + """Entity representing a piglin. + + :param is_baby: Indicates if the piglin is a baby. + :type is_baby: bool, optional, default: False + :param is_charging_crossbow: Indicates if the piglin is charging a crossbow. + :type is_charging_crossbow: bool, optional, default: False + :param is_dancing: Indicates if the piglin is dancing. + :type is_dancing: bool, optional, default: False + + Inherited from :class:`BasePiglinEM`: + + :param is_immune_to_zombification: Indicates if the piglin is immune to zombification. + :type is_immune_to_zombification: bool, optional, default: False + + Inherited from :class:`MonsterEM`: + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + is_baby: bool = entry(BooleanEME, False) + is_charging_crossbow: bool = entry(BooleanEME, False) + is_dancing: bool = entry(BooleanEME, False) + + __slots__ = () + + +class PiglinBruteEM(BasePiglinEM): + """Entity representing a piglin brute. + + Inherited from :class:`BasePiglinEM`: + + :param is_immune_to_zombification: Indicates if the piglin is immune to zombification. + :type is_immune_to_zombification: bool, optional, default: False + + Inherited from :class:`MonsterEM`: + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + __slots__ = () + + +class BlazeEM(MonsterEM): + """Entity representing a blaze. + + :param is_blaze_on_fire: Whether the blaze is on fire. (this affects :attr:`_blaze_flags`) + :type is_blaze_on_fire: bool, optional + + Inherited from :class:`MonsterEM`: + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + _blaze_flags: ClassVar[int] = entry(ByteEME, 0) + is_blaze_on_fire: bool = proxy(_blaze_flags, BoolMasked, mask=0x1) + + __slots__ = () + + +class CreeperEM(MonsterEM): + """Entity representing a creeper. + + :param state: The state of the creeper (-1 = idle, 1 = fuse). + :type state: int, optional, default: -1 + :param is_charged: Indicates if the creeper is charged. + :type is_charged: bool, optional, default: False + :param is_ignited: Indicates if the creeper is ignited. + :type is_ignited: bool, optional, default: False + + Inherited from :class:`MonsterEM`: + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + state: int = entry(VarIntEME, -1) + is_charged: bool = entry(BooleanEME, False) + is_ignited: bool = entry(BooleanEME, False) + + __slots__ = () + + +class EndermiteEM(MonsterEM): + """Entity representing an endermite. + + Inherited from :class:`MonsterEM`: + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + __slots__ = () + + +class GiantEM(MonsterEM): + """Entity representing a giant. + + Inherited from :class:`MonsterEM`: + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + __slots__ = () + + +class GuardianEM(MonsterEM): + """Entity representing a guardian. + + :param is_retracting_spikes: Indicates if the guardian is retracting spikes. + :type is_retracting_spikes: bool, optional, default: False + :param target_eid: The Entity ID of the target. + :type target_eid: int, optional, default: 0 + + Inherited from :class:`MonsterEM`: + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + is_retracting_spikes: bool = entry(BooleanEME, False) + target_eid: int = entry(VarIntEME, 0) + + __slots__ = () + + +class ElderGuardianEM(GuardianEM): + """Entity representing an elder guardian. + + Inherited from :class:`GuardianEM`: + + :param is_retracting_spikes: Indicates if the guardian is retracting spikes. + :type is_retracting_spikes: bool, optional, default: False + :param target_eid: The Entity ID of the target. + :type target_eid: int, optional, default: 0 + + Inherited from :class:`MonsterEM`: + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + __slots__ = () + + +class SilverfishEM(MonsterEM): + """Entity representing a silverfish. + + Inherited from :class:`MonsterEM`: + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + __slots__ = () + + +class RaiderEM(MonsterEM): + """Entity representing a raider. + + :param is_celebrating: Indicates if the raider is celebrating. + :type is_celebrating: bool, optional, default: False + + Inherited from :class:`MonsterEM`: + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + is_celebrating: bool = entry(BooleanEME, False) + + __slots__ = () + + +class AbstractIllagerEM(RaiderEM): + """Entity representing an abstract illager. + + Inherited from :class:`RaiderEM`: + + :param is_celebrating: Indicates if the raider is celebrating. + :type is_celebrating: bool, optional, default: False + + Inherited from :class:`MonsterEM`: + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + __slots__ = () + + +class VindicatorEM(AbstractIllagerEM): + """Entity representing a vindicator. + + Inherited from :class:`AbstractIllagerEM`: + + Inherited from :class:`RaiderEM`: + + :param is_celebrating: Indicates if the raider is celebrating. + :type is_celebrating: bool, optional, default: False + + Inherited from :class:`MonsterEM`: + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + __slots__ = () + + +class PillagerEM(AbstractIllagerEM): + """Entity representing a pillager. + + :param is_charging: Indicates if the pillager is charging. + :type is_charging: bool, optional, default: False + + Inherited from :class:`AbstractIllagerEM`: + + Inherited from :class:`RaiderEM`: + + :param is_celebrating: Indicates if the raider is celebrating. + :type is_celebrating: bool, optional, default: False + + Inherited from :class:`MonsterEM`: + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + is_charging: bool = entry(BooleanEME, False) + + __slots__ = () + + +class SpellcasterIllagerEM(AbstractIllagerEM): + """Entity representing a spellcaster illager. + + :param spell: The type of spell the illager is casting. (0: none, 1: summon vex, 2: attack, + 3: wololo, 4: disappear, 5: blindness) + :type spell: int, optional, default: 0 + + Inherited from :class:`AbstractIllagerEM`: + + Inherited from :class:`RaiderEM`: + + :param is_celebrating: Indicates if the raider is celebrating. + :type is_celebrating: bool, optional, default: False + + Inherited from :class:`MonsterEM`: + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + spell: int = entry(ByteEME, 0) + + __slots__ = () + + +class EvokerEM(SpellcasterIllagerEM): + """Entity representing an evoker. + + Inherited from :class:`SpellcasterIllagerEM`: + + :param spell: The type of spell the illager is casting. (0: none, 1: summon vex, 2: attack, + 3: wololo, 4: disappear, 5: blindness) + :type spell: int, optional, default: 0 + + Inherited from :class:`AbstractIllagerEM`: + + Inherited from :class:`RaiderEM`: + + :param is_celebrating: Indicates if the raider is celebrating. + :type is_celebrating: bool, optional, default: False + + Inherited from :class:`MonsterEM`: + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + __slots__ = () + + +class IllusionerEM(SpellcasterIllagerEM): + """Entity representing an illusioner. + + Inherited from :class:`SpellcasterIllagerEM`: + + :param spell: The type of spell the illager is casting. (0: none, 1: summon vex, 2: attack, + 3: wololo, 4: disappear, 5: blindness) + :type spell: int, optional, default: 0 + + Inherited from :class:`AbstractIllagerEM`: + + Inherited from :class:`RaiderEM`: + + :param is_celebrating: Indicates if the raider is celebrating. + :type is_celebrating: bool, optional, default: False + + Inherited from :class:`MonsterEM`: + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + __slots__ = () + + +class RavagerEM(RaiderEM): + """Entity representing a ravager. + + Inherited from :class:`RaiderEM`: + + :param is_celebrating: Indicates if the raider is celebrating. + :type is_celebrating: bool, optional, default: False + + Inherited from :class:`MonsterEM`: + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + __slots__ = () + + +class WitchEM(RaiderEM): + """Entity representing a witch. + + :param is_drinking_potion: Indicates if the witch is drinking a potion. + :type is_drinking_potion: bool, optional, default: False + + Inherited from :class:`RaiderEM`: + + :param is_celebrating: Indicates if the raider is celebrating. + :type is_celebrating: bool, optional, default: False + + Inherited from :class:`MonsterEM`: + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + is_drinking_potion: bool = entry(BooleanEME, False) + + __slots__ = () + + +class EvokerFangsEM(EntityEM): + """Entity representing evoker fangs. + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + __slots__ = () + + +class VexEM(MonsterEM): + """Entity representing a vex. + + :param is_attacking: Indicates if the vex is charging. (this affects :attr:`_vex_flags`) + :type is_attacking: bool, optional + + Inherited from :class:`MonsterEM`: + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + _vex_flags: ClassVar[int] = entry(ByteEME, 0) + is_attacking: bool = proxy(_vex_flags, BoolMasked, mask=0x1) + + __slots__ = () + + +class AbstractSkeletonEM(MonsterEM): + """Entity representing an abstract skeleton. + + Inherited from :class:`MonsterEM`: + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + __slots__ = () + + +class SkeletonEM(AbstractSkeletonEM): + """Entity representing a skeleton. + + Inherited from :class:`AbstractSkeletonEM`: + + Inherited from :class:`MonsterEM`: + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + __slots__ = () + + +class WitherSkeletonEM(AbstractSkeletonEM): + """Entity representing a wither skeleton. + + Inherited from :class:`AbstractSkeletonEM`: + + Inherited from :class:`MonsterEM`: + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + __slots__ = () + + +class StrayEM(AbstractSkeletonEM): + """Entity representing a stray skeleton. + + Inherited from :class:`AbstractSkeletonEM`: + + Inherited from :class:`MonsterEM`: + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + __slots__ = () + + +class SpiderEM(MonsterEM): + """Entity representing a spider. + + :param is_climbing: Whether the spider is climbing. (this affects :attr:`_spider_flags`) + :type is_climbing: bool, optional + + Inherited from :class:`MonsterEM`: + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + _spider_flags: ClassVar[int] = entry(ByteEME, 0) + is_climbing: bool = proxy(_spider_flags, BoolMasked, mask=0x1) + + __slots__ = () + + +class WardenEM(MonsterEM): + """Entity representing a warden. + + :param anger_level: The level of anger of the warden. + :type anger_level: int, optional, default: 0 + + Inherited from :class:`MonsterEM`: + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + anger_level: int = entry(VarIntEME, 0) + + __slots__ = () + + +class WitherEM(MonsterEM): + """Entity representing a wither. + + :param center_head_target: The entity ID of the target for the center head. (0 if no target) + :type center_head_target: int, optional, default: 0 + :param left_head_target: The entity ID of the target for the left head. (0 if no target) + :type left_head_target: int, optional, default: 0 + :param right_head_target: The entity ID of the target for the right head. (0 if no target) + :type right_head_target: int, optional, default: 0 + :param invulnerable_time: The amount of time the wither is invulnerable. + :type invulnerable_time: int, optional, default: 0 + + Inherited from :class:`MonsterEM`: + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + center_head_target: int = entry(VarIntEME, 0) + left_head_target: int = entry(VarIntEME, 0) + right_head_target: int = entry(VarIntEME, 0) + invulnerable_time: int = entry(VarIntEME, 0) + + __slots__ = () + + +class ZoglinEM(MonsterEM): + """Entity representing a zoglin. + + :param is_baby: Indicates whether the zoglin is a baby. + :type is_baby: bool, optional, default: False + + Inherited from :class:`MonsterEM`: + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + is_baby: bool = entry(BooleanEME, False) + + __slots__ = () + + +class ZombieEM(MonsterEM): + """Entity representing a zombie. + + :param is_baby: Indicates whether the zombie is a baby. + :type is_baby: bool, optional, default: False + :param _zombie_type: Unused metadata. (Previously used for zombie type) + :type _zombie_type: int, optional, default: 0 + :param is_becoming_drowned: Indicates whether the zombie is in the process of becoming a drowned. + :type is_becoming_drowned: bool, optional, default: False + + Inherited from :class:`MonsterEM`: + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + is_baby: bool = entry(BooleanEME, False) + _zombie_type: int = entry(VarIntEME, 0) + is_becoming_drowned: bool = entry(BooleanEME, False) + + __slots__ = () + + +class ZombieVillagerEM(ZombieEM): + """Entity representing a zombie villager. + + :param is_converting: Indicates whether the zombie villager is currently converting. + :type is_converting: bool, optional, default: False + :param villager_data: The data of the villager associated with the zombie villager. + :type villager_data: tuple[int, int, int], optional, default: (0, 0, 0) + + Inherited from :class:`ZombieEM`: + + :param is_baby: Indicates whether the zombie is a baby. + :type is_baby: bool, optional, default: False + :param _zombie_type: Unused metadata. (Previously used for zombie type) + :type _zombie_type: int, optional, default: 0 + :param is_becoming_drowned: Indicates whether the zombie is in the process of becoming a drowned. + :type is_becoming_drowned: bool, optional, default: False + + Inherited from :class:`MonsterEM`: + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + is_converting: bool = entry(BooleanEME, False) + villager_data: tuple[int, int, int] = entry(VillagerDataEME, (0, 0, 0)) + + __slots__ = () + + +class HuskEM(ZombieEM): + """Entity representing a husk. + + Inherited from :class:`ZombieEM`: + + :param is_baby: Indicates whether the zombie is a baby. + :type is_baby: bool, optional, default: False + :param _zombie_type: Unused metadata. (Previously used for zombie type) + :type _zombie_type: int, optional, default: 0 + :param is_becoming_drowned: Indicates whether the zombie is in the process of becoming a drowned. + :type is_becoming_drowned: bool, optional, default: False + + Inherited from :class:`MonsterEM`: + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + __slots__ = () + + +class DrownedEM(ZombieEM): + """Entity representing a drowned. + + Inherited from :class:`ZombieEM`: + + :param is_baby: Indicates whether the zombie is a baby. + :type is_baby: bool, optional, default: False + :param _zombie_type: Unused metadata. (Previously used for zombie type) + :type _zombie_type: int, optional, default: 0 + :param is_becoming_drowned: Indicates whether the zombie is in the process of becoming a drowned. + :type is_becoming_drowned: bool, optional, default: False + + Inherited from :class:`MonsterEM`: + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + __slots__ = () + + +class ZombifiedPiglinEM(ZombieEM): + """Entity representing a zombified piglin. + + Inherited from :class:`ZombieEM`: + + :param is_baby: Indicates whether the zombie is a baby. + :type is_baby: bool, optional, default: False + :param _zombie_type: Unused metadata. (Previously used for zombie type) + :type _zombie_type: int, optional, default: 0 + :param is_becoming_drowned: Indicates whether the zombie is in the process of becoming a drowned. + :type is_becoming_drowned: bool, optional, default: False + + Inherited from :class:`MonsterEM`: + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + __slots__ = () + + +class EndermanEM(MonsterEM): + """Entity representing an enderman. + + :param carried_block: The block the enderman is carrying. + :type carried_block: int | None, optional, default: None + :param is_screaming: Indicates if the enderman is screaming. + :type is_screaming: bool, optional, default: False + :param is_staring: Indicates if the enderman is staring. + :type is_staring: bool, optional, default: False + + Inherited from :class:`MonsterEM`: + + Inherited from :class:`PathfinderMobEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + carried_block: int | None = entry(OptBlockStateEME, None) + is_screaming: bool = entry(BooleanEME, False) + is_staring: bool = entry(BooleanEME, False) + + __slots__ = () + + +class EnderDragonEM(MobEM): + """Entity representing an ender dragon. + + :param dragon_phase: The current phase of the ender dragon. + :type dragon_phase: :class:`DragonPhase`, optional, default: :attr:`DragonPhase.HOVERING_NO_AI` + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + dragon_phase: DragonPhase = entry(DragonPhaseEME, DragonPhase.HOVERING_NO_AI) + + __slots__ = () + + +class FlyingEM(MobEM): + """Base entity for flying mobs. + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + __slots__ = () + + +class GhastEM(FlyingEM): + """Entity representing a ghast. + + :param is_attacking: Indicates if the ghast is attacking. + :type is_attacking: bool, optional, default: False + + Inherited from :class:`FlyingEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + is_attacking: bool = entry(BooleanEME, False) + + __slots__ = () + + +class PhantomEM(FlyingEM): + """Entity representing a phantom. + + :param size: The size of the phantom. + :type size: int, optional, default: 0 + + Inherited from :class:`FlyingEM`: + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + size: int = entry(VarIntEME, 0) + + __slots__ = () + + +class SlimeEM(MobEM): + """Entity representing a slime. + + :param size: The size of the slime. + :type size: int, optional, default: 1 + + Inherited from :class:`MobEM`: + + :param no_ai: Whether the mob has AI. (this affects :attr:`_mob_flags`) + :type no_ai: bool, optional + :param is_left_handed: Whether the mob is left-handed. (this affects :attr:`_mob_flags`) + :type is_left_handed: bool, optional + :param is_aggressive: Whether the mob is aggressive. (this affects :attr:`_mob_flags`) + :type is_aggressive: bool, optional + + Inherited from :class:`LivingEntityEM`: + + :param is_hand_active: Whether the hand is active. (this affects :attr:`_hand_states`) + :type is_hand_active: bool, optional + :param active_hand: Which hand is active (0 = main hand, 1 = offhand). (this affects :attr:`_hand_states`) + :type active_hand: int, optional + :param is_riptide_spin_attack: Whether the entity is in riptide spin attack. (this affects :attr:`_hand_states`) + :type is_riptide_spin_attack: bool, optional + :param health: The health of the living entity. + :type health: float, optional, default: 1.0 + :param potion_effect_color: Color of the potion effect (or 0 if there is no effect). + :type potion_effect_color: int, optional, default: 0 + :param is_potion_effect_ambient: Whether the potion effect is ambient: reduces the number of particles generated by + potions to 1/5 the normal amount. + :type is_potion_effect_ambient: bool, optional, default: False + :param num_arrows: Number of arrows in the entity. + :type num_arrows: int, optional, default: 0 + :param num_bee_stingers: Number of bee stingers in the entity. + :type num_bee_stingers: int, optional, default: 0 + :param sleeping_bed_location: Location of the bed that the entity is currently sleeping + in (Empty if it isn't sleeping). + :type sleeping_bed_location: :class:`Position|None`, optional, default: :attr:`None` + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + size: int = entry(VarIntEME, 1) + + __slots__ = () + + +class LlamaSpitEM(EntityEM): + """Entity representing spit from a llama. + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + __slots__ = () + + +class PrimedTntEM(EntityEM): + """Entity representing primed TNT. + + :param fuse_time: The fuse time for the primed TNT. + :type fuse_time: int, optional, default: 80 + + Inherited from :class:`EntityEM`: + + :param is_on_fire: Whether the entity is on fire. (this affects :attr:`_entity_flags`) + :type is_on_fire: bool, optional + :param is_crouching: Whether the entity is crouching. (this affects :attr:`_entity_flags`) + :type is_crouching: bool, optional + :param is_riding: [UNUSED] Whether the entity is riding something. (this affects :attr:`_entity_flags`) + :type is_riding: bool, optional + :param is_sprinting: Whether the entity is sprinting. (this affects :attr:`_entity_flags`) + :type is_sprinting: bool, optional + :param is_swimming: Whether the entity is swimming. (this affects :attr:`_entity_flags`) + :type is_swimming: bool, optional + :param is_invisible: Whether the entity is invisible. (this affects :attr:`_entity_flags`) + :type is_invisible: bool, optional + :param is_glowing: Whether the entity has a glowing effect. (this affects :attr:`_entity_flags`) + :type is_glowing: bool, optional + :param is_flying: Whether the entity is flying. (this affects :attr:`_entity_flags`) + :type is_flying: bool, optional + :param air: The amount of air the entity has. + :type air: int, optional, default: 300 + :param custom_name: The custom name of the entity. + :type custom_name: str, optional, default: "" + :param is_custom_name_visible: Whether the custom name is visible. + :type is_custom_name_visible: bool, optional, default: False + :param is_silent: Whether the entity is silent. + :type is_silent: bool, optional, default: False + :param no_gravity: Whether the entity should ignore gravity. + :type no_gravity: bool, optional, default: False + :param pose: The pose of the entity. Can be one of the following: STANDING, FALL_FLYING, + SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING. + :type pose: :class:`Pose`, optional, default: :attr:`Pose.STANDING` + :param ticks_frozen: The amount of ticks the entity has been in powdered snow for. + :type ticks_frozen: int, optional, default: 0 + + """ + + fuse_time: int = entry(VarIntEME, 80) + + __slots__ = () diff --git a/mcproto/types/entity/metadata.py b/mcproto/types/entity/metadata.py new file mode 100644 index 00000000..3012eabd --- /dev/null +++ b/mcproto/types/entity/metadata.py @@ -0,0 +1,442 @@ +from __future__ import annotations + +from abc import ABCMeta, abstractmethod +from typing import Any, ClassVar, Generic, Literal, TypeVar, cast, final, overload + +from attrs import define +from typing_extensions import dataclass_transform, override + +from mcproto.buffer import Buffer +from mcproto.protocol import StructFormat +from mcproto.types.abc import MCType + +T = TypeVar("T") +U = TypeVar("U") + + +class EntityMetadataEntry(MCType, Generic[T]): + """Represents an entry in an entity metadata list. + + :param index: The index of the entry. + :param entry_type: The type of the entry. + :param value: The value of the entry. + :param default: The default value of the entry. + :param hidden: Whether the entry is hidden from the metadata list. + :param name: The name of the entry. This is used for debugging purposes and not always set. DO NOT RELY ON THIS + """ + + ENTRY_TYPE: ClassVar[int] = None # type: ignore + + index: int + value: T + + __slots__ = ("index", "value", "hidden", "default", "name") + + def __init__( + self, + index: int, + value: T | None = None, + default: T | None = None, + hidden: bool = False, + name: str | None = None, + ): + self.index = index + self.value = value if value is not None else default # type: ignore + self.hidden = hidden + self.default = default + self.name = name # for debugging purposes + + self.validate() + + def setter(self, value: T) -> None: + """Set the value of the entry.""" + self.value = value + + def getter(self) -> T: + """Get the value of the entry.""" + return self.value + + def _write_header(self, buf: Buffer) -> None: + """Write the index and type of the entry. + + :param buf: The buffer to write to. + """ + buf.write_value(StructFormat.UBYTE, self.index) + buf.write_varint(self.ENTRY_TYPE) + + @overload + @classmethod + def read_header(cls, buf: Buffer, return_type: Literal[True]) -> tuple[int, int]: ... + + @overload + @classmethod + def read_header(cls, buf: Buffer, return_type: Literal[False] = False) -> int: ... + + @classmethod + def read_header(cls, buf: Buffer, return_type: bool = False) -> tuple[int, int] | int: + """Read the index and type of the entry, and optionally return the type. + + :param buf: The buffer to read from. + :param return_type: Whether to return the type of the entry. If this is set to false, the type will be read but + not returned. + :return: The index of the entry. + + :raises ValueError: If return_type is False and the entity type does not match the expected type. + """ + index = buf.read_value(StructFormat.UBYTE) + if index == 0xFF: + if return_type: + return index, -1 + raise ValueError("Index 0xFF is reserved for the end of the metadata list.") + + entry_type = buf.read_varint() + if entry_type != cls.ENTRY_TYPE and not return_type: + raise TypeError(f"Expected entry type {cls.ENTRY_TYPE}, got {entry_type}.") + if return_type: + return index, entry_type + return index + + def validate(self) -> None: + """Check that the entry has a valid index. + + Subclasses can override this method to add additional validation. + """ + if self.index < 0 or self.index > 0xFF: + raise ValueError("Index must be between 0 and 0xFF.") + + @override + def __repr__(self) -> str: + return f"{self.__class__.__name__}(index={self.index}, value={self.value})" + + @override + def __eq__(self, value: object) -> bool: + if not isinstance(value, EntityMetadataEntry): + return NotImplemented + return self.index == value.index and self.value == value.value + + @classmethod + @abstractmethod + def read_value(cls, buf: Buffer) -> Any: + """Read the value of the entry from the buffer. + + :param buf: The buffer to read from. + :return: The value of the entry. + """ + + @override + @classmethod + @final + def deserialize(cls, buf: Buffer) -> EntityMetadataEntry[T]: + """Deserialize the entity metadata entry. + + :param buf: The buffer to read from. + :return: The entity metadata entry. + """ + index = cls.read_header(buf) + value = cls.read_value(buf) + return cls(index=index, value=value) + + +class ProxyEntityMetadataEntry(MCType, Generic[T, U]): + """A proxy entity metadata entry which is used to designate a part of a metadata entry in a human-readable format. + + For example, this can be used to represent a certain mask for a ByteEME entry. + """ + + ENTRY_TYPE: ClassVar[int] = None # type: ignore + + bound_entry: EntityMetadataEntry[U] + + __slots__ = ("bound_entry",) + + def __init__(self, bound_entry: EntityMetadataEntry[U], *args: Any, **kwargs: Any): + self.bound_entry = bound_entry + self.validate() + + @override + def serialize_to(self, buf: Buffer) -> None: + raise NotImplementedError("Proxy entity metadata entries cannot be serialized.") + + @override + @classmethod + def deserialize(cls, buf: Buffer) -> ProxyEntityMetadataEntry[T, U]: + raise NotImplementedError("Proxy entity metadata entries cannot be deserialized.") + + @abstractmethod + def setter(self, value: T) -> None: + """Set the value of the entry by modifying the bound entry.""" + + @abstractmethod + def getter(self) -> T: + """Get the value of the entry by reading the bound entry.""" + + def validate(self) -> None: + """Validate that the proxy metadata entry has valid values.""" + + +@define +class DefaultEntityMetadataEntryDeclaration(Generic[T]): + """Class used to pass the default metadata to the entity metadata.""" + + m_default: Any + m_type: type[EntityMetadataEntry[T]] + m_index: int + + +def entry(entry_type: type[EntityMetadataEntry[T]], value: T) -> T: + """Create a entity metadata entry with the given value. + + :param entry_type: The type of the entry. + :param default: The default value of the entry. + :return: The default entity metadata entry. + """ + # This will be taken care of by EntityMetadata + return DefaultEntityMetadataEntryDeclaration(m_default=value, m_type=entry_type, m_index=-1) # type: ignore + + +@define +class ProxyEntityMetadataEntryDeclaration(Generic[T, U]): + """Class used to pass the bound entry and additional arguments to the proxy entity metadata entry. + + Explanation: + m_bound_entry: The real entry that the proxy will modify. + m_args: Additional arguments for the proxy entity metadata entry. + m_kwargs: Additional keyword arguments for the proxy entity metadata entry. + m_type: The type of the proxy entity metadata entry, this defines how the proxy will modify the real entry. + All of the above are set by the proxy() function. + + m_bound_index: The index of the bound entry in the metadata list. + This is set by the EntityMetadataCreator. + """ + + m_bound_entry: EntityMetadataEntry[U] + m_args: tuple[Any] + m_kwargs: dict[str, Any] + m_type: type[ProxyEntityMetadataEntry[T, U]] + m_bound_index: int + + +def proxy( + bound_entry: U, # This will in fact be an EntityMetadataEntry, but treated as a U during type checking + proxy: type[ProxyEntityMetadataEntry[T, U]], + *args: Any, + **kwargs: Any, +) -> T: + """Initialize the proxy entity metadata entry with the given bound entry and additional arguments. + + :param bound_entry: The bound entry. + :param proxy: The proxy entity metadata entry type. + :param args: Additional arguments for the proxy entity metadata entry. + :param kwargs: Additional keyword arguments for the proxy entity metadata entry. + + :return: The proxy entity metadata entry initializer. + """ + if not isinstance(bound_entry, DefaultEntityMetadataEntryDeclaration): + raise TypeError("The bound entry must be an entity metadata entry type.") + + return ProxyEntityMetadataEntryDeclaration( # type: ignore + m_bound_entry=bound_entry, # type: ignore + m_args=args, + m_kwargs=kwargs, + m_type=proxy, + m_bound_index=-1, + ) + + +@dataclass_transform(kw_only_default=True) # field_specifiers=(entry, proxy)) +class EntityMetadataCreator(ABCMeta): + """Metaclass for the EntityMetadata. + + This metaclass is used to create the EntityMetadata with the correct attributes to allow for using them + like dataclasses. + + The entry() and proxy() functions are used to set the attributes of the entity class. + ``` + """ + + m_defaults: ClassVar[ + dict[ + str, + DefaultEntityMetadataEntryDeclaration[Any] + | ProxyEntityMetadataEntryDeclaration[Any, EntityMetadataEntry[Any]], + ] + ] + m_index: ClassVar[dict[int, str]] + m_metadata: ClassVar[ + dict[str, EntityMetadataEntry[Any] | ProxyEntityMetadataEntry[Any, EntityMetadataEntry[Any]]] + ] # This is not an actual classvar, but I + # Do not want it to appear in the __init__ signature + + def __new__(cls, name: str, bases: tuple[type], namespace: dict[str, Any]) -> EntityMetadata: + """Create a new EntityMetadata.""" + new_cls = super().__new__(cls, name, bases, namespace) + cls.setup_class(new_cls) + return cast("EntityMetadata", new_cls) + + def setup_class(cls: type[EntityMetadata]) -> None: + """Set up the class for the entity metadata. + + This function will create a few class attributes : + - m_defaults: A dictionary that maps the names of the entries to their "setup class" (the return of entry() + or proxy()) + - m_index: A mapping of the names of the entity metadata entries to their index + + The m_metadata is mentioned here but nothing is created yet. __init__ will take care of this. + + """ + cls.m_defaults = {} + cls.m_index = {} + + bound_index: dict[int, int] = {} + current_index = 0 + # Find all the entries in the class + + attributes: list[str] = [] + for parent in reversed(cls.mro()): + for name in vars(parent): + if name in attributes: + continue + attributes.append(name) + + for name in attributes: + # Default is assigned in the class definition + default = getattr(cls, name, None) + if default is None: + raise ValueError(f"Default value for {name} is not set. Use the entry() or proxy() functions.") + # Check if we have a default entry + if isinstance(default, DefaultEntityMetadataEntryDeclaration): + default = cast(DefaultEntityMetadataEntryDeclaration[Any], default) + # Set the index of the entry + default.m_index = current_index + + # Add the index to the index mapping + cls.m_index[current_index] = name + + # Add the entry to the bound_index mapping to be used by the proxy entries + bound_index[id(default)] = current_index + + # Increment the index + current_index += 1 + elif isinstance(default, ProxyEntityMetadataEntryDeclaration): + default = cast(ProxyEntityMetadataEntryDeclaration[Any, EntityMetadataEntry[Any]], default) + # Find the bound entry + if id(default.m_bound_entry) not in bound_index: + raise ValueError(f"Bound entry for {name} is not set.") + bound_entry = bound_index[id(default.m_bound_entry)] + + # Set the index of the proxy entry + default.m_bound_index = bound_entry + else: + continue + # Add the entry to the defaults + cls.m_defaults[name] = default + + +class EntityMetadata(MCType, metaclass=EntityMetadataCreator): + """Base for all Entity classes. + + All the entity classes are subclasses of this class. + + You can set attributes of the entity class by using the entry() and proxy() functions. + + Example: + + .. code-block:: python + + class EntityMetadata(EntityMetadata): + byte_entry: ClassVar[int] = entry(ByteEME, 0) # ByteEME is the type and 0 is the default value + varint_entry: int = entry(VarIntEME, 0) + proxy_entry: int = proxy(byte_entry, Masked, mask=0x01) + proxy_entry2: int = proxy(byte_entry, Masked, mask=0x02) + + + Note that the extra arguments for the proxy() function are passed to the proxy class and that the + bound entry is passed as the first argument without quotes. + """ + + __slots__ = ("m_metadata",) + + def __init__(self, *args: None, **kwargs: Any) -> None: + if len(args) > 0: + raise ValueError( + "EntityMetadata does not accept positional arguments. Specify all metadata entries by name." + ) + self.m_metadata: dict[ + str, EntityMetadataEntry[Any] | ProxyEntityMetadataEntry[Any, EntityMetadataEntry[Any]] + ] = {} + for name, default in self.m_defaults.items(): + if isinstance(default, DefaultEntityMetadataEntryDeclaration): + self.m_metadata[name] = default.m_type(index=default.m_index, default=default.m_default, name=name) + elif isinstance(default, ProxyEntityMetadataEntryDeclaration): # type: ignore # Check anyway + # Bound entry + bound_name = self.m_index[default.m_bound_index] + bound_entry = cast(EntityMetadataEntry[Any], self.m_metadata[bound_name]) + self.m_metadata[name] = default.m_type(bound_entry, *default.m_args, **default.m_kwargs) + else: # pragma: no cover + raise ValueError(f"Invalid default value for {name}. Use the entry() or proxy() functions.") # noqa: TRY004 + + for name, value in kwargs.items(): + if name not in self.m_metadata: + raise ValueError(f"Unknown metadata entry {name}.") + self.m_metadata[name].setter(value) + + @override + def __setattr__(self, name: str, value: Any) -> None: + """Any is used here because the type will be discovered statically by other means (dataclass_transform).""" + if name != "m_metadata" and hasattr(self, "m_metadata") and name in self.m_metadata: + self.m_metadata[name].setter(value) + else: + super().__setattr__(name, value) + + @override + def __getattribute__(self, name: str) -> Any: + """Get the value of the metadata entry. + + .. seealso:: :meth:`__setattr__` + """ + if name != "m_metadata" and hasattr(self, "m_metadata") and name in self.m_metadata: + return self.m_metadata[name].getter() + return super().__getattribute__(name) + + @override + def __repr__(self) -> str: + # Iterate over m_metadata to get the string representation of the metadata + metadata: list[str] = [] + for name, entry in self.m_metadata.items(): + metadata.append(f"{name}={entry.getter()}") + return f"{self.__class__.__name__}({', '.join(metadata)})" + + @override + def serialize_to(self, buf: Buffer) -> None: + for entry in self.m_metadata.values(): + # Check if the value is a proxy entry + if isinstance(entry, ProxyEntityMetadataEntry): + continue + # Check if the value differs from the default value + if entry.value != entry.default: + entry.serialize_to(buf) + # Mark the end of the metadata list + buf.write_value(StructFormat.UBYTE, 0xFF) + + @override + @classmethod + def deserialize(cls, buf: Buffer) -> EntityMetadata: + from mcproto.types.entity.metadata_types import ASSOCIATIONS + + entries: list[tuple[int, Any]] = [] + + while True: + index, entry_type_index = EntityMetadataEntry.read_header(buf, return_type=True) + if index == 0xFF: + break + if entry_type_index not in ASSOCIATIONS: + raise TypeError(f"Unknown entry type {entry_type_index}.") + entry_type = ASSOCIATIONS[entry_type_index] + + entry = entry_type.read_value(buf) + entries.append((index, entry)) + + new_instance = cls() # Initialize the new instance with the default values + for index, value in entries: + new_instance.m_metadata[cls.m_index[index]].setter(value) + return new_instance diff --git a/mcproto/types/entity/metadata_types.py b/mcproto/types/entity/metadata_types.py new file mode 100644 index 00000000..9b2dc4e4 --- /dev/null +++ b/mcproto/types/entity/metadata_types.py @@ -0,0 +1,653 @@ +from __future__ import annotations + +from enum import IntEnum +from typing import Any, ClassVar, Generic, TypeVar, Union, cast + +from typing_extensions import override + +from mcproto.buffer import Buffer +from mcproto.protocol import StructFormat +from mcproto.types.chat import TextComponent +from mcproto.types.entity.enums import Direction, DragonPhase, Pose, SnifferState +from mcproto.types.entity.metadata import EntityMetadataEntry, ProxyEntityMetadataEntry +from mcproto.types.identifier import Identifier +from mcproto.types.nbt import NBTag +from mcproto.types.particle_data import ParticleData +from mcproto.types.quaternion import Quaternion +from mcproto.types.slot import Slot +from mcproto.types.uuid import UUID +from mcproto.types.vec3 import Position, Vec3 + + +class ByteEME(EntityMetadataEntry[int]): + """Represents a byte entry in an entity metadata list.""" + + ENTRY_TYPE: ClassVar[int] = 0 + __slots__ = () + + @override + def serialize_to(self, buf: Buffer) -> None: + self._write_header(buf) + buf.write_value(StructFormat.BYTE, self.value) + + @override + @classmethod + def read_value(cls, buf: Buffer) -> int: + return buf.read_value(StructFormat.BYTE) + + @override + def validate(self) -> None: + if not -128 <= self.value <= 127: + raise ValueError(f"Byte value {self.value} is out of range.") + super().validate() + + +class BoolMasked(ProxyEntityMetadataEntry[bool, int]): + """Represents a masked entry in an entity metadata list.""" + + __slots__ = ("mask", "_mask_shift") + + def __init__(self, bound_entry: EntityMetadataEntry[int], *, mask: int): + self.mask = mask + super().__init__(bound_entry) + self._mask_shift = self.mask.bit_length() - 1 + + @override + def setter(self, value: int) -> None: + bound = self.bound_entry.getter() + bound = (bound & ~self.mask) | (int(value) << self._mask_shift) + self.bound_entry.setter(bound) + + @override + def getter(self) -> bool: + return bool(self.bound_entry.getter() & self.mask) + + @override + def validate(self) -> None: + # Ensure that there is only one bit set in the mask + if self.mask & (self.mask - 1): + raise ValueError(f"Mask {self.mask} is not a power of 2.") + + +class IntMasked(ProxyEntityMetadataEntry[int, int]): + """Represents a masked entry in an entity metadata list.""" + + __slots__ = ("mask",) + + def __init__(self, bound_entry: EntityMetadataEntry[int], *, mask: int): + super().__init__(bound_entry) + self.mask = mask + + @override + def setter(self, value: int) -> None: + bound = self.bound_entry.getter() + # spread value over the mask + for i in range(32): + if self.mask & (1 << i): + bound = (bound & ~(1 << i)) | ((value & 1) << i) + value >>= 1 + self.bound_entry.setter(bound) + + @override + def getter(self) -> int: + # collect bits from the mask + value = 0 + bound = self.bound_entry.getter() + if bound == 0: # Save 32 iterations of a useless loop + return 0 + shift = 0 + for i in range(32): + if self.mask & (1 << i): + # Find the bit that is set and shift it back to the right position + value |= (bound & (1 << i)) >> (i - shift) + shift += 1 + return value + + +class VarIntEME(EntityMetadataEntry[int]): + """Represents a varint entry in an entity metadata list.""" + + ENTRY_TYPE: ClassVar[int] = 1 + __slots__ = () + + @override + def serialize_to(self, buf: Buffer) -> None: + self._write_header(buf) + buf.write_varint(self.value) + + @override + @classmethod + def read_value(cls, buf: Buffer) -> Any: + return buf.read_varint() + + @override + def validate(self) -> None: + if not -(2**31) <= self.value < 2**31: + raise ValueError(f"VarInt value {self.value} is out of range.") + super().validate() + + +class _RegistryVarIntEME(VarIntEME): + """Represents a varint entry that refereces a registry ID in an entity metadata list.""" + + ENTRY_TYPE: ClassVar[int] = -1 + __slots__ = () + + +IntEnum_T = TypeVar("IntEnum_T", bound=IntEnum) + + +class _VarIntEnumEME(EntityMetadataEntry[IntEnum_T], Generic[IntEnum_T]): + """Represents a varint entry that refereces an enum in an entity metadata list.""" + + ENTRY_TYPE: ClassVar[int] = -1 + __slots__ = () + ENUM: ClassVar[type[IntEnum]] = None # type: ignore + + @override + def serialize_to(self, buf: Buffer) -> None: + self._write_header(buf) + buf.write_varint(self.value.value) + + @override + @classmethod + def read_value(cls, buf: Buffer) -> IntEnum_T: + value = buf.read_varint() + try: + value_enum = cls.ENUM(value) + except ValueError as e: + raise ValueError(f"Invalid value {value} for enum {cls.ENUM.__name__}.") from e + return cast(IntEnum_T, value_enum) + + @override + def validate(self) -> None: + super().validate() + try: + self.ENUM(self.value) + except ValueError as e: + raise ValueError(f"Invalid value {self.value} for enum {self.ENUM.__name__}.") from e + + +class VarLongEME(EntityMetadataEntry[int]): + """Represents a varlong entry in an entity metadata list.""" + + ENTRY_TYPE: ClassVar[int] = 2 + __slots__ = () + + @override + def serialize_to(self, buf: Buffer) -> None: + self._write_header(buf) + buf.write_varlong(self.value) + + @override + @classmethod + def read_value(cls, buf: Buffer) -> int: + return buf.read_varlong() + + @override + def validate(self) -> None: + if not -(2**63) <= self.value < 2**63: + raise ValueError(f"VarLong value {self.value} is out of range.") + super().validate() + + +class FloatEME(EntityMetadataEntry[float]): + """Represents a float entry in an entity metadata list.""" + + ENTRY_TYPE: ClassVar[int] = 3 + __slots__ = () + + @override + def serialize_to(self, buf: Buffer) -> None: + self._write_header(buf) + buf.write_value(StructFormat.FLOAT, self.value) + + @override + @classmethod + def read_value(cls, buf: Buffer) -> float: + return buf.read_value(StructFormat.FLOAT) + + +class StringEME(EntityMetadataEntry[str]): + """Represents a string entry in an entity metadata list.""" + + ENTRY_TYPE: ClassVar[int] = 4 + __slots__ = () + + @override + def serialize_to(self, buf: Buffer) -> None: + self._write_header(buf) + buf.write_utf(self.value) + + @override + @classmethod + def read_value(cls, buf: Buffer) -> str: + return buf.read_utf() + + @override + def validate(self) -> None: + if len(self.value) > 32767: + raise ValueError(f"String value {self.value} is too long.") + super().validate() + + +class TextComponentEME(EntityMetadataEntry[TextComponent]): + """Represents a text component entry in an entity metadata list.""" + + ENTRY_TYPE: ClassVar[int] = 5 + __slots__ = () + + @override + def serialize_to(self, buf: Buffer) -> None: + self._write_header(buf) + self.value.serialize_to(buf) + + @override + @classmethod + def read_value(cls, buf: Buffer) -> TextComponent: + return TextComponent.deserialize(buf) + + +class OptTextComponentEME(EntityMetadataEntry[Union[TextComponent, None]]): + """Represents an optional text component entry in an entity metadata list.""" + + ENTRY_TYPE: ClassVar[int] = 6 + __slots__ = () + + @override + def serialize_to(self, buf: Buffer) -> None: + self._write_header(buf) + # We use the old python True == 1 trick to represent a boolean + buf.write_value(StructFormat.BYTE, self.value is not None) + if self.value is not None: + self.value.serialize_to(buf) + + @override + @classmethod + def read_value(cls, buf: Buffer) -> TextComponent | None: + present = buf.read_value(StructFormat.BYTE) + if present: + return TextComponent.deserialize(buf) + return None + + +class SlotEME(EntityMetadataEntry[Slot]): + """Represents a slot entry in an entity metadata list.""" + + ENTRY_TYPE: ClassVar[int] = 7 + __slots__ = () + + @override + def serialize_to(self, buf: Buffer) -> None: + self._write_header(buf) + self.value.serialize_to(buf) + + @override + @classmethod + def read_value(cls, buf: Buffer) -> Slot: + return Slot.deserialize(buf) + + +class BooleanEME(EntityMetadataEntry[bool]): + """Represents a boolean entry in an entity metadata list.""" + + ENTRY_TYPE: ClassVar[int] = 8 + __slots__ = () + + @override + def serialize_to(self, buf: Buffer) -> None: + self._write_header(buf) + buf.write_value(StructFormat.BYTE, self.value) + + @override + @classmethod + def read_value(cls, buf: Buffer) -> bool: + return bool(buf.read_value(StructFormat.BYTE)) + + +class RotationEME(EntityMetadataEntry[Vec3]): + """Represents a rotation entry in an entity metadata list.""" + + ENTRY_TYPE: ClassVar[int] = 9 + __slots__ = () + + @override + def serialize_to(self, buf: Buffer) -> None: + self._write_header(buf) + self.value.serialize_to(buf) + + @override + @classmethod + def read_value(cls, buf: Buffer) -> Vec3: + return Vec3.deserialize(buf) + + +class PositionEME(EntityMetadataEntry[Position]): + """Represents a position entry in an entity metadata list.""" + + ENTRY_TYPE: ClassVar[int] = 10 + __slots__ = () + + @override + def serialize_to(self, buf: Buffer) -> None: + self._write_header(buf) + self.value.serialize_to(buf) + + @override + @classmethod + def read_value(cls, buf: Buffer) -> Position: + return Position.deserialize(buf) + + +class OptPositionEME(EntityMetadataEntry[Union[Position, None]]): + """Represents an optional position entry in an entity metadata list.""" + + ENTRY_TYPE: ClassVar[int] = 11 + __slots__ = () + + @override + def serialize_to(self, buf: Buffer) -> None: + self._write_header(buf) + # We use the old python True == 1 trick to represent a boolean + buf.write_value(StructFormat.BYTE, self.value is not None) + if self.value is not None: + self.value.serialize_to(buf) + + @override + @classmethod + def read_value(cls, buf: Buffer) -> Position | None: + present = buf.read_value(StructFormat.BYTE) + if present: + return Position.deserialize(buf) + return None + + +class DirectionEME(EntityMetadataEntry[Direction]): + """Represents a direction in the world.""" + + ENTRY_TYPE: ClassVar[int] = 12 + __slots__ = () + + @override + def serialize_to(self, buf: Buffer) -> None: + self._write_header(buf) + buf.write_value(StructFormat.BYTE, self.value) + + @override + @classmethod + def read_value(cls, buf: Buffer) -> Direction: + return Direction(buf.read_value(StructFormat.BYTE)) + + +class OptUUIDEME(EntityMetadataEntry[Union[UUID, None]]): + """Represents an optional UUID entry in an entity metadata list.""" + + ENTRY_TYPE: ClassVar[int] = 13 + __slots__ = () + + @override + def serialize_to(self, buf: Buffer) -> None: + self._write_header(buf) + # We use the old python True == 1 trick to represent a boolean + buf.write_value(StructFormat.BYTE, self.value is not None) + if self.value is not None: + self.value.serialize_to(buf) + + @override + @classmethod + def read_value(cls, buf: Buffer) -> UUID | None: + present = buf.read_value(StructFormat.BYTE) + if present: + return UUID.deserialize(buf) + return None + + +class BlockStateEME(VarIntEME): + """Represents a block state in the world.""" + + ENTRY_TYPE: ClassVar[int] = 14 + __slots__ = () + + +class OptBlockStateEME(EntityMetadataEntry[Union[int, None]]): + """Represents an optional block state in the world.""" + + ENTRY_TYPE: ClassVar[int] = 15 + __slots__ = () + + @override + def serialize_to(self, buf: Buffer) -> None: + self._write_header(buf) + if self.value is not None: + buf.write_varint(self.value) + else: + buf.write_varint(0) + + @override + @classmethod + def read_value(cls, buf: Buffer) -> int | None: + value = buf.read_varint() + if value == 0: + value = None + return value + + +class NBTagEME(EntityMetadataEntry[NBTag]): + """Represents an NBT entry in an entity metadata list.""" + + ENTRY_TYPE: ClassVar[int] = 16 + __slots__ = () + + @override + def serialize_to(self, buf: Buffer) -> None: + self._write_header(buf) + self.value.serialize_to(buf, with_name=False) + + @override + @classmethod + def read_value(cls, buf: Buffer) -> NBTag: + return NBTag.deserialize(buf, with_name=False) + + +class ParticleEME(EntityMetadataEntry[ParticleData]): + """Represents a particle entry in an entity metadata list.""" + + ENTRY_TYPE: ClassVar[int] = 17 + __slots__ = () + + @override + def serialize_to(self, buf: Buffer) -> None: + self._write_header(buf) + self.value.serialize_to(buf, with_id=True) + + @override + @classmethod + def read_value(cls, buf: Buffer) -> ParticleData: + return ParticleData.deserialize(buf, particle_id=None) # Read the particle ID from the buffer + + +class VillagerDataEME(EntityMetadataEntry["tuple[int, int, int]"]): + """Represents a villager data entry in an entity metadata list. + + This includes the type, profession, and level of the villager. + """ + + ENTRY_TYPE: ClassVar[int] = 18 + __slots__ = () + + @override + def serialize_to(self, buf: Buffer) -> None: + self._write_header(buf) + buf.write_varint(self.value[0]) + buf.write_varint(self.value[1]) + buf.write_varint(self.value[2]) + + @override + @classmethod + def read_value(cls, buf: Buffer) -> tuple[int, int, int]: + return (buf.read_varint(), buf.read_varint(), buf.read_varint()) + + +class OptVarIntEME(EntityMetadataEntry[Union[int, None]]): + """Represents an optional varint entry in an entity metadata list.""" + + ENTRY_TYPE: ClassVar[int] = 19 + __slots__ = () + + @override + def serialize_to(self, buf: Buffer) -> None: + self._write_header(buf) + # We use the old python True == 1 trick to represent a boolean + if self.value is not None: + buf.write_varint(self.value + 1) + else: + buf.write_varint(0) + + @override + @classmethod + def read_value(cls, buf: Buffer) -> int | None: + value = buf.read_varint() - 1 + if value == -1: + value = None + return value + + +class PoseEME(_VarIntEnumEME[Pose]): + """Represents a pose entry in an entity metadata list.""" + + ENTRY_TYPE: ClassVar[int] = 20 + __slots__ = () + ENUM: ClassVar[type[IntEnum]] = Pose + + +class CatVariantEME(_RegistryVarIntEME): + """Represents a cat variant entry in an entity metadata list.""" + + ENTRY_TYPE: ClassVar[int] = 21 + __slots__ = () + + +class FrogVariantEME(_RegistryVarIntEME): + """Represents a frog variant entry in an entity metadata list.""" + + ENTRY_TYPE: ClassVar[int] = 22 + __slots__ = () + + +class DragonPhaseEME(_VarIntEnumEME[DragonPhase]): + """Represents a dragon phase entry in an entity metadata list. + + .. note:: This is not a real type, because the type is `VarInt`, but the values are predefined. + """ + + ENTRY_TYPE: ClassVar[int] = 1 + __slots__ = () + ENUM: ClassVar[type[IntEnum]] = DragonPhase + + +class OptGlobalPositionEME(EntityMetadataEntry[Union["tuple[Identifier, Position]", None]]): + """Represents an optional global position entry in an entity metadata list. + + This includes an identifier for the dimension as well as the position in it. + """ + + ENTRY_TYPE: ClassVar[int] = 23 + __slots__ = () + + @override + def serialize_to(self, buf: Buffer) -> None: + self._write_header(buf) + # We use the old python True == 1 trick to represent a boolean + buf.write_value(StructFormat.BYTE, self.value is not None) + if self.value is not None: + self.value[0].serialize_to(buf) + self.value[1].serialize_to(buf) + + @override + @classmethod + def read_value(cls, buf: Buffer) -> tuple[Identifier, Position] | None: + present = buf.read_value(StructFormat.BYTE) + if present: + return (Identifier.deserialize(buf), Position.deserialize(buf)) + return None + + +class PaintingVariantEME(_RegistryVarIntEME): + """Represents a painting variant entry in an entity metadata list.""" + + ENTRY_TYPE: ClassVar[int] = 24 + __slots__ = () + + +class SnifferStateEME(_VarIntEnumEME[SnifferState]): + """Represents a sniffer state entry in an entity metadata list.""" + + ENTRY_TYPE: ClassVar[int] = 25 + __slots__ = () + ENUM: ClassVar[type[IntEnum]] = SnifferState + + +class Vector3EME(EntityMetadataEntry[Vec3]): + """Represents a vector3 entry in an entity metadata list.""" + + ENTRY_TYPE: ClassVar[int] = 26 + __slots__ = () + + @override + def serialize_to(self, buf: Buffer) -> None: + self._write_header(buf) + self.value.serialize_to(buf) + + @override + @classmethod + def read_value(cls, buf: Buffer) -> Vec3: + return Vec3.deserialize(buf) + + +class QuaternionEME(EntityMetadataEntry[Quaternion]): + """Represents a quaternion entry in an entity metadata list.""" + + ENTRY_TYPE: ClassVar[int] = 27 + __slots__ = () + + @override + def serialize_to(self, buf: Buffer) -> None: + self._write_header(buf) + self.value.serialize_to(buf) + + @override + @classmethod + def read_value(cls, buf: Buffer) -> Quaternion: + return Quaternion.deserialize(buf) + + +ASSOCIATIONS = { + 0: ByteEME, + 1: VarIntEME, + 2: _RegistryVarIntEME, + 3: FloatEME, + 4: StringEME, + 5: TextComponentEME, + 6: OptTextComponentEME, + 7: SlotEME, + 8: BooleanEME, + 9: RotationEME, + 10: PositionEME, + 11: OptPositionEME, + 12: DirectionEME, + 13: OptUUIDEME, + 14: BlockStateEME, + 15: OptBlockStateEME, + 16: NBTagEME, + 17: ParticleEME, + 18: VillagerDataEME, + 19: OptVarIntEME, + 20: PoseEME, + 21: CatVariantEME, + 22: FrogVariantEME, + 23: OptGlobalPositionEME, + 24: PaintingVariantEME, + 25: SnifferStateEME, + 26: Vector3EME, + 27: QuaternionEME, +} diff --git a/mcproto/types/identifier.py b/mcproto/types/identifier.py new file mode 100644 index 00000000..ba2209ea --- /dev/null +++ b/mcproto/types/identifier.py @@ -0,0 +1,80 @@ +from __future__ import annotations + +import re + +from attrs import define +from typing_extensions import override + +from mcproto.buffer import Buffer +from mcproto.types.abc import MCType +from mcproto.types.nbt import NBTag, NBTagConvertible, StringNBT + + +@define(init=False) +class Identifier(MCType, NBTagConvertible): + """A Minecraft identifier.""" + + _NAMESPACE_REGEX = re.compile(r"^[a-z0-9\.\-_]+$") + _PATH_REGEX = re.compile(r"^[a-z0-9\.\-_/]+$") + + namespace: str + path: str + + @override + def __init__(self, namespace: str, path: str | None = None): + """Initialize the Identifier class. + + :param namespace: The namespace of the identifier. + :param path: The path of the identifier. + :type path: str, optional + + If the path is not provided, the namespace and path will be extracted from the :attr:`namespace` argument. + If the namespace is not provided, it will default to "minecraft". + + We use this to initialize the Identifier class instead of attrs because of the extra transformations that we + need to do, attrs does not support this out of the box. + + """ + if namespace.startswith("#"): + namespace = namespace[1:] + + if path is None: + if ":" not in namespace: + path = namespace + namespace = "minecraft" + else: + namespace, path = namespace.split(":", 1) + + if not self._NAMESPACE_REGEX.match(namespace): + raise ValueError(f"Invalid namespace: {namespace}") + if not self._PATH_REGEX.match(path): + raise ValueError(f"Invalid path: {path}") + + if len(namespace) + len(path) + 1 > 32767: + raise ValueError("Identifier is too long") + + self.__attrs_init__(namespace=namespace, path=path) # type: ignore + + @override + def serialize_to(self, buf: Buffer) -> None: + data = f"{self.namespace}:{self.path}" + buf.write_utf(data) + + @override + @classmethod + def deserialize(cls, buf: Buffer) -> Identifier: + data = buf.read_utf() + namespace, path = data.split(":", 1) + return cls(namespace, path) + + @override + def __hash__(self) -> int: + return hash((self.namespace, self.path)) + + @override + def __str__(self) -> str: + return f"{self.namespace}:{self.path}" + + @override + def to_nbt(self, name: str = "") -> NBTag: + return StringNBT(self.__str__(), name=name) diff --git a/mcproto/types/map_icon.py b/mcproto/types/map_icon.py new file mode 100644 index 00000000..49ade619 --- /dev/null +++ b/mcproto/types/map_icon.py @@ -0,0 +1,89 @@ +from __future__ import annotations + +from enum import IntEnum +from typing import final + +from attrs import define, field, validators +from typing_extensions import override + +from mcproto.buffer import Buffer +from mcproto.protocol.base_io import StructFormat +from mcproto.types.abc import MCType +from mcproto.types.chat import TextComponent + + +class IconType(IntEnum): + """Represents the type of a map icon.""" + + PLAYER = 0 + FRAME = 1 + RED_MARKER = 2 + BLUE_MARKER = 3 + TARGET_X = 4 + TARGET_POINT = 5 + PLAYER_OFF_MAP = 6 + PLAYER_OFF_LIMITS = 7 + + MANSION = 8 + MONUMENT = 9 + + WHITE_BANNER = 10 + ORANGE_BANNER = 11 + MAGENTA_BANNER = 12 + LIGHT_BLUE_BANNER = 13 + YELLOW_BANNER = 14 + LIME_BANNER = 15 + PINK_BANNER = 16 + GRAY_BANNER = 17 + LIGHT_GRAY_BANNER = 18 + CYAN_BANNER = 19 + PURPLE_BANNER = 20 + BLUE_BANNER = 21 + BROWN_BANNER = 22 + GREEN_BANNER = 23 + RED_BANNER = 24 + BLACK_BANNER = 25 + + TREASURE_MARKER = 26 + + +@final +@define +class MapIcon(MCType): + """Represents a map icon. + + :param type: The type of the icon. + :type type: IconType + :param x: The x-coordinate of the icon. + :type x: int + :param z: The z-coordinate of the icon. + :type z: int + :param direction: The direction of the icon. + :type direction: int + :param display_name: The display name of the icon. + :type display_name: :class:`~mcproto.types.chat.TextComponent`, optional + """ + + icon_type: IconType = field(validator=validators.instance_of(IconType), converter=IconType) + x: int = field(validator=[validators.le(127), validators.ge(-128)]) + z: int = field(validator=[validators.le(127), validators.ge(-128)]) + direction: int = field(validator=[validators.le(15), validators.ge(0)]) + display_name: TextComponent | None = field(default=None) + + @override + def serialize_to(self, buf: Buffer) -> None: + buf.write_varint(self.icon_type) + buf.write_value(StructFormat.BYTE, self.x) + buf.write_value(StructFormat.BYTE, self.z) + buf.write_value(StructFormat.BYTE, self.direction) + buf.write_optional(self.display_name, lambda x: x.serialize_to(buf)) + + @override + @classmethod + def deserialize(cls, buf: Buffer) -> MapIcon: + icon_type = IconType(buf.read_varint()) + x = buf.read_value(StructFormat.BYTE) + z = buf.read_value(StructFormat.BYTE) + direction = buf.read_value(StructFormat.BYTE) + display_name = buf.read_optional(lambda: TextComponent.deserialize(buf)) + return cls(icon_type, x, z, direction, display_name) diff --git a/mcproto/types/modifier.py b/mcproto/types/modifier.py new file mode 100644 index 00000000..f9841ec1 --- /dev/null +++ b/mcproto/types/modifier.py @@ -0,0 +1,60 @@ +from __future__ import annotations + +from enum import IntEnum +from typing import final + +from attrs import define +from typing_extensions import override + +from mcproto.buffer import Buffer +from mcproto.protocol import StructFormat +from mcproto.types.abc import MCType +from mcproto.types.uuid import UUID + + +class ModifierOperation(IntEnum): + """Represents the operation of a modifier. + + .. note:: The modifier operations are applied in the order :attr:`ADD`, :attr:`ADD_PERCENT`, :attr:`MULTIPLY_TOTAL` + """ + + ADD = 0 + """Add/subtract the amount to the base value.""" + MULTIPLY_BASE = 1 + """Add/subtract a percentage of the base value to the base value.""" + MULTIPLY_TOTAL = 2 + """Multiply the total value by a percentage.""" + + +@final +@define +class ModifierData(MCType): + """Represents a modifier data in the :class:`~mcproto.packets.play.UpdateAttributes` packet. + + + + :param uuid: The UUID of the modifier. + :type uuid: :class:`~mcproto.types.uuid.UUID` + :param amount: The amount of the modifier. + :type amount: float + :param operation: The operation of the modifier. + :type operation: :class:`ModifierOperation` + """ + + uuid: UUID + amount: float + operation: ModifierOperation + + @override + def serialize_to(self, buf: Buffer) -> None: + self.uuid.serialize_to(buf) + buf.write_value(StructFormat.DOUBLE, self.amount) + buf.write_value(StructFormat.BYTE, self.operation) + + @override + @classmethod + def deserialize(cls, buf: Buffer) -> ModifierData: + uuid = UUID.deserialize(buf) + amount = buf.read_value(StructFormat.DOUBLE) + operation = ModifierOperation(buf.read_value(StructFormat.BYTE)) + return cls(uuid=uuid, amount=amount, operation=operation) diff --git a/mcproto/types/nbt.py b/mcproto/types/nbt.py index bb49a8d6..a8b32673 100644 --- a/mcproto/types/nbt.py +++ b/mcproto/types/nbt.py @@ -3,10 +3,10 @@ from abc import abstractmethod from collections.abc import Iterator, Mapping, Sequence from enum import IntEnum -from typing import ClassVar, Protocol, Union, cast, final, runtime_checkable +from typing import ClassVar, Hashable, Protocol, Union, cast, final, runtime_checkable -from attrs import define -from typing_extensions import Self, TypeAlias, override +from attrs import define, field, validators +from typing_extensions import Literal, Self, TypeAlias, override from mcproto.buffer import Buffer from mcproto.protocol.base_io import FLOAT_FORMATS_TYPE, INT_FORMATS_TYPE, StructFormat @@ -180,7 +180,7 @@ def to_nbt(self, name: str = "") -> NBTag: """Represents the type of a schema, used to define how an object should be converted to an NBT tag(s).""" -class NBTag(MCType, NBTagConvertible): +class NBTag(MCType, NBTagConvertible, Hashable): """Base class for NBT tags. In MC v1.20.2+ the type and name of the root tag is not written to the buffer, and unless specified, @@ -189,6 +189,12 @@ class NBTag(MCType, NBTagConvertible): __slots__ = ("name", "payload") + def __init__(self, payload: PayloadType, name: str = ""): + self.name = name + self.payload = payload + + self.validate() + @override # Add some extra kwargs to control serialization def serialize(self, with_type: bool = True, with_name: bool = True) -> Buffer: """Serialize the NBT tag to a new buffer. @@ -207,7 +213,7 @@ def serialize(self, with_type: bool = True, with_name: bool = True) -> Buffer: @override @classmethod - def deserialize(cls, buf: Buffer, with_name: bool = True, with_type: bool = True) -> NBTag: + def deserialize(cls, buf: Buffer, with_name: bool = True, with_type: bool = True) -> Self: """Deserialize the NBT tag. :param buf: The buffer to read from. @@ -222,12 +228,14 @@ def deserialize(cls, buf: Buffer, with_name: bool = True, with_type: bool = True name, tag_type = cls._read_header(buf, with_name=with_name, read_type=with_type) tag_class = ASSOCIATED_TYPES[tag_type] - if cls not in (NBTag, tag_class): + if not issubclass(tag_class, cls): + # Either we are using NBTag.deserialize and in that case tag_class is any subclass of NBTag + # or we are using a specific tag and in that case we want to ensure that the tag is of the correct type raise TypeError(f"Expected a {cls.__name__} tag, but found a different tag ({tag_class.__name__}).") tag = tag_class.read_from(buf, with_type=False, with_name=False) tag.name = name - return tag + return tag # type: ignore @override @abstractmethod @@ -341,6 +349,7 @@ def from_object(data: FromObjectType, schema: FromObjectSchema, name: str = "") raise ValueError("Use a list or a dictionary in the schema to create a CompoundNBT or a ListNBT.") # Check if the data contains the name (if it is a dictionary) if isinstance(data, dict): + data = cast("Mapping[str, FromObjectType]", data) if len(data) != 1: raise ValueError("Expected a dictionary with a single key-value pair.") # We also check if the name isn't already set @@ -357,7 +366,7 @@ def from_object(data: FromObjectType, schema: FromObjectSchema, name: str = "") raise TypeError("Expected a list of integers, but a non-integer element was found.") data = cast(Union[bytes, str, int, float, "list[int]"], data) # Create the tag with the data and the name - return schema(data, name=name) # type: ignore # The schema is a subclass of NBTag + return schema(data, name=name) # The schema is a subclass of NBTag # Sanity check : Verify that all type schemas have been handled if not isinstance(schema, (list, tuple, dict)): @@ -462,19 +471,35 @@ def value(self) -> PayloadType: """Get the payload of the NBT tag in a python-friendly format.""" raise NotImplementedError + def validate(self) -> None: + """Check that the value contained in the NBTag payload is valid for a certain tag type.""" + + @override + def __hash__(self) -> int: + return hash((self.name, self.payload, type(self))) + + @override + def __eq__(self, value: object) -> bool: + if not isinstance(value, NBTag): + return NotImplemented + return (self.name, self.payload, type(self)) == (value.name, value.payload, type(value)) + # endregion # region NBT tags types @final -@define +@define(hash=False, eq=False, init=False) class EndNBT(NBTag): """Sentinel tag used to mark the end of a TAG_Compound.""" payload: None = None name: str = "" + def __init__(self, payload: None = None, name: Literal[""] = ""): + super().__init__(None, "") # type: ignore + @override def serialize_to(self, buf: Buffer, with_type: bool = True, with_name: bool = False) -> None: self._write_header(buf, with_type=with_type, with_name=False) @@ -499,7 +524,7 @@ def value(self) -> PayloadType: return NotImplemented -@define +@define(hash=False, eq=False, init=False) class _NumberNBTag(NBTag, RequiredParamsABCMixin): """Base class for NBT tags representing a number. @@ -589,7 +614,7 @@ class LongNBT(_NumberNBTag): __slots__ = () -@define +@define(hash=False, eq=False, init=False) class _FloatingNBTag(NBTag, RequiredParamsABCMixin): """Base class for NBT tags representing a floating-point number.""" @@ -598,14 +623,8 @@ class _FloatingNBTag(NBTag, RequiredParamsABCMixin): STRUCT_FORMAT: ClassVar[FLOAT_FORMATS_TYPE] = NotImplemented # type: ignore DATA_SIZE: ClassVar[int] = NotImplemented - payload: float - name: str = "" - - @override - def __attrs_post_init__(self) -> None: - if isinstance(self.payload, int): - self.payload = float(self.payload) - return super().__attrs_post_init__() + payload: float = field(converter=float, validator=validators.instance_of((int, float))) + name: str = field(default="") @override def serialize_to(self, buf: Buffer, with_type: bool = True, with_name: bool = True) -> None: @@ -632,11 +651,6 @@ def __float__(self) -> float: def value(self) -> float: return self.payload - @override - def validate(self) -> None: - if not isinstance(self.payload, (int, float)): # type: ignore # We want to check anyway - raise TypeError(f"Expected a float, but found {type(self.payload).__name__}.") - @final class FloatNBT(_FloatingNBTag): @@ -658,18 +672,12 @@ class DoubleNBT(_FloatingNBTag): __slots__ = () -@define +@define(hash=False, eq=False, init=False) class ByteArrayNBT(NBTag): """NBT tag representing an array of bytes. The length of the array is stored as a signed 32-bit integer.""" - payload: bytes - name: str = "" - - @override - def __attrs_post_init__(self) -> None: - if isinstance(self.payload, bytearray): - self.payload = bytes(self.payload) - return super().__attrs_post_init__() + payload: bytes = field(converter=bytes, validator=validators.instance_of((bytes, bytearray))) + name: str = field(default="") @override def serialize_to(self, buf: Buffer, with_type: bool = True, with_name: bool = True) -> None: @@ -715,13 +723,8 @@ def __repr__(self) -> str: def value(self) -> bytes: return self.payload - @override - def validate(self) -> None: - if not isinstance(self.payload, (bytearray, bytes)): - raise TypeError(f"Expected a bytes, but found {type(self.payload).__name__}.") - -@define +@define(hash=False, eq=False, init=False) class StringNBT(NBTag): """NBT tag representing an UTF-8 string value. The length of the string is stored as a signed 16-bit integer.""" @@ -780,7 +783,7 @@ def validate(self) -> None: raise ValueError("Invalid UTF-8 string.") from exc -@define +@define(hash=False, eq=False, init=False) class ListNBT(NBTag): """NBT tag representing a list of tags. All tags in the list must be of the same type.""" @@ -872,6 +875,7 @@ def to_object( # or the `validate` method if not isinstance(first, (dict, list)): # pragma: no cover raise TypeError(f"The schema must contain either a dict or a list. Found {first!r}") + first = cast("dict[str, PayloadType]|list[PayloadType]", first) # This will take care of ensuring either everything is a dict or a list if not all(isinstance(schema, type(first)) for schema in subschemas): # pragma: no cover raise TypeError(f"All items in the list must have the same type. Found {subschemas!r}") @@ -898,7 +902,7 @@ def validate(self) -> None: raise ValueError("All tags in a list must be unnamed.") -@define +@define(hash=False, eq=False, init=False) class CompoundNBT(NBTag): """NBT tag representing a compound of named tags.""" @@ -1009,8 +1013,12 @@ def validate(self) -> None: if len(self.payload) != len({tag.name for tag in self.payload}): raise ValueError("All tags in a compound must have unique names.") + @override + def __hash__(self) -> int: + return hash((self.name, frozenset(self.payload), type(self))) # Use frozenset to ignore the order + -@define +@define(hash=False, eq=False, init=False) class _NumberArrayNBTag(NBTag, RequiredParamsABCMixin): """Base class for NBT tags representing an array of numbers.""" diff --git a/mcproto/types/particle_data.py b/mcproto/types/particle_data.py new file mode 100644 index 00000000..8f784984 --- /dev/null +++ b/mcproto/types/particle_data.py @@ -0,0 +1,308 @@ +from __future__ import annotations + +from typing import cast, final + +from attrs import define +from typing_extensions import Self, override + +from mcproto.buffer import Buffer +from mcproto.protocol.base_io import StructFormat +from mcproto.protocol.utils import from_twos_complement, to_twos_complement +from mcproto.types.abc import MCType +from mcproto.types.slot import Slot +from mcproto.types.vec3 import Position + + +@final +@define +class ParticleData(MCType): + """Represents the data of a particle. + + .. note:: Only some of the parameters can be used at the same time. They are determined by the particle ID. + + :param particle_id: The ID of the particle (used to determine the actual data to read). + :type particle_id: int + + :param block_state: The ID of the block state. + :type block_state: int, optional + + :param red: The red color component of the particle. + :type red: float, optional + :param green: The green color component of the particle. + :type green: float, optional + :param blue: The blue color component of the particle. + :type blue: float, optional + :param scale: The scale of the particle. + :type scale: float, optional + + :param from_red: The initial red color component of the particle. + :type from_red: float, optional + :param from_green: The initial green color component of the particle. + :type from_green: float, optional + :param from_blue: The initial blue color component of the particle. + :type from_blue: float, optional + :param to_red: The final red color component of the particle. + :type to_red: float, optional + :param to_green: The final green color component of the particle. + :type to_green: float, optional + :param to_blue: The final blue color component of the particle. + :type to_blue: float, optional + + :param roll: How much the particle will be rotated when displayed. + :type roll: float, optional + + :param item: The item that will be displayed as a particle. + :type item: :class:`~mcproto.types.item.Slot`, optional + + :param source_type: The type of the source of the particle. (0 for `minecraft:block`, 1 for `minecraft:entity`) + :type source_type: int, optional + :param block_position: The position of the block that is the source of the particle. (used when `source_type` is 0) + :type block_position: :class:`~mcproto.types.vec3.Position`, optional + :param entity_id: The ID of the entity that is the source of the particle. (used when `source_type` is 1) + :type entity_id: int, optional + :param entity_eye_height: The height of the entity's eye relative to the entity. (used when `source_type` is 1) + :type entity_eye_height: float, optional + :param tick: The amount of ticks it takes for the vibration to travel from its source to its destination. + :type tick: int, optional + + :param delay: The delay before the particle is displayed. + :type delay: int, optional + + :param color: The color of the particle. + :type color: int, optional + """ + + # TODO: Use registries for particle IDs + + WITH_BLOCK_STATE = ( + 1, # minecraft:block + 2, # minecraft:block_marker + 28, # minecraft:falling_dust + 105, # minecraft:dust_pillar + ) + + WITH_RGB_SCALE = ( + 13, # minecraft:dust + ) + + WITH_RGB_TRANSITION = ( + 14, # minecraft:dust_color_transition + ) + + WITH_ROLL = ( + 35, # minecraft:sculk_charge + ) + + WITH_ITEM = ( + 44, # minecraft:item + ) + + WITH_VIBRATION = ( + 45, # minecraft:vibration + ) + + WITH_DELAY = ( + 99, # minecraft:shriek + ) + + WITH_COLOR = ( + 20, # minecraft:entity_effect + ) + + particle_id: int + block_state: int | None = None + red: float | None = None + green: float | None = None + blue: float | None = None + scale: float | None = None + from_red: float | None = None + from_green: float | None = None + from_blue: float | None = None + to_red: float | None = None + to_green: float | None = None + to_blue: float | None = None + roll: float | None = None + item: Slot | None = None + source_type: int | None = None + block_position: Position | None = None + entity_id: int | None = None + entity_eye_height: float | None = None + tick: int | None = None + delay: int | None = None + color: int | None = None + + def __attrs_post_init__(self) -> None: # noqa: PLR0912 # I know but what can I do? + """Run all the sanity checks for the particle data.""" + if self.particle_id in self.WITH_BLOCK_STATE: + if self.block_state is None: + raise ValueError("block_state is required for this particle ID") + elif self.particle_id in self.WITH_RGB_SCALE: + if self.red is None or self.green is None or self.blue is None: + raise ValueError("red, green, and blue are required for this particle ID") + elif self.particle_id in self.WITH_RGB_TRANSITION: + if self.from_red is None or self.from_green is None or self.from_blue is None: + raise ValueError("from_red, from_green, and from_blue are required for this particle ID") + if self.scale is None: + raise ValueError("scale is required for this particle ID") + if self.to_red is None or self.to_green is None or self.to_blue is None: + raise ValueError("to_red, to_green, and to_blue are required for this particle ID") + elif self.particle_id in self.WITH_ROLL: + if self.roll is None: + raise ValueError("roll is required for this particle ID") + elif self.particle_id in self.WITH_ITEM: + if self.item is None: + raise ValueError("item is required for this particle ID") + elif self.particle_id in self.WITH_VIBRATION: + if self.source_type is None: + raise ValueError("source_type is required for this particle ID") + if self.source_type == 0: + if self.block_position is None: + raise ValueError("block_position is required for this particle ID with source_type 0") + else: + if self.entity_id is None: + raise ValueError("entity_id is required for this particle ID with source_type 1") + if self.entity_eye_height is None: + raise ValueError("entity_eye_height is required for this particle ID with source_type 1") + if self.tick is None: + raise ValueError("tick is required for this particle ID") + elif self.particle_id in self.WITH_DELAY: + if self.delay is None: + raise ValueError("delay is required for this particle ID") + elif self.particle_id in self.WITH_COLOR: + if self.color is None: + raise ValueError("color is required for this particle ID") + + @override + def serialize_to(self, buf: Buffer, with_id: bool = True) -> None: + if with_id: + buf.write_varint(self.particle_id) + if self.particle_id in self.WITH_BLOCK_STATE: + self.block_state = cast(int, self.block_state) + buf.write_varint(self.block_state) + if self.particle_id in self.WITH_RGB_SCALE: + self.red = cast(float, self.red) + self.green = cast(float, self.green) + self.blue = cast(float, self.blue) + buf.write_value(StructFormat.FLOAT, self.red) + buf.write_value(StructFormat.FLOAT, self.green) + buf.write_value(StructFormat.FLOAT, self.blue) + if self.particle_id in self.WITH_RGB_TRANSITION: + self.from_red = cast(float, self.from_red) + self.from_green = cast(float, self.from_green) + self.from_blue = cast(float, self.from_blue) + self.scale = cast(float, self.scale) + self.to_red = cast(float, self.to_red) + self.to_green = cast(float, self.to_green) + self.to_blue = cast(float, self.to_blue) + buf.write_value(StructFormat.FLOAT, self.from_red) + buf.write_value(StructFormat.FLOAT, self.from_green) + buf.write_value(StructFormat.FLOAT, self.from_blue) + buf.write_value(StructFormat.FLOAT, self.scale) + buf.write_value(StructFormat.FLOAT, self.to_red) + buf.write_value(StructFormat.FLOAT, self.to_green) + buf.write_value(StructFormat.FLOAT, self.to_blue) + if self.particle_id in self.WITH_ROLL: + self.roll = cast(float, self.roll) + buf.write_value(StructFormat.FLOAT, self.roll) + if self.particle_id in self.WITH_ITEM: + self.item = cast(Slot, self.item) + self.item.serialize_to(buf) + if self.particle_id in self.WITH_VIBRATION: + self.source_type = cast(int, self.source_type) + self.tick = cast(int, self.tick) + buf.write_varint(self.source_type) + if self.source_type == 0: + self.block_position = cast(Position, self.block_position) + self.block_position.serialize_to(buf) + else: + self.entity_id = cast(int, self.entity_id) + self.entity_eye_height = cast(float, self.entity_eye_height) + buf.write_varint(self.entity_id) + buf.write_value(StructFormat.FLOAT, self.entity_eye_height) + buf.write_varint(self.tick) + if self.particle_id in self.WITH_DELAY: + self.delay = cast(int, self.delay) + buf.write_varint(self.delay) + if self.particle_id in self.WITH_COLOR: + self.color = cast(int, self.color) + buf.write_value(StructFormat.INT, from_twos_complement(self.color, 32)) + + @classmethod + @override + def deserialize(cls, buf: Buffer, particle_id: int | None = None) -> Self: + particle_id = buf.read_varint() if particle_id is None else particle_id + block_state = None + red = None + green = None + blue = None + scale = None + from_red = None + from_green = None + from_blue = None + to_red = None + to_green = None + to_blue = None + roll = None + item = None + source_type = None + block_position = None + entity_id = None + entity_eye_height = None + tick = None + delay = None + color = None + + if particle_id in cls.WITH_BLOCK_STATE: + block_state = buf.read_varint() + if particle_id in cls.WITH_RGB_SCALE: + red = buf.read_value(StructFormat.FLOAT) + green = buf.read_value(StructFormat.FLOAT) + blue = buf.read_value(StructFormat.FLOAT) + if particle_id in cls.WITH_RGB_TRANSITION: + from_red = buf.read_value(StructFormat.FLOAT) + from_green = buf.read_value(StructFormat.FLOAT) + from_blue = buf.read_value(StructFormat.FLOAT) + scale = buf.read_value(StructFormat.FLOAT) + to_red = buf.read_value(StructFormat.FLOAT) + to_green = buf.read_value(StructFormat.FLOAT) + to_blue = buf.read_value(StructFormat.FLOAT) + if particle_id in cls.WITH_ROLL: + roll = buf.read_value(StructFormat.FLOAT) + if particle_id in cls.WITH_ITEM: + item = Slot.deserialize(buf) + if particle_id in cls.WITH_VIBRATION: + source_type = buf.read_varint() + if source_type == 0: + block_position = Position.deserialize(buf) + else: + entity_id = buf.read_varint() + entity_eye_height = buf.read_value(StructFormat.FLOAT) + tick = buf.read_varint() + if particle_id in cls.WITH_DELAY: + delay = buf.read_varint() + if particle_id in cls.WITH_COLOR: + color = to_twos_complement(buf.read_value(StructFormat.INT), 32) + + return cls( + particle_id=particle_id, + block_state=block_state, + red=red, + green=green, + blue=blue, + scale=scale, + from_red=from_red, + from_green=from_green, + from_blue=from_blue, + to_red=to_red, + to_green=to_green, + to_blue=to_blue, + roll=roll, + item=item, + source_type=source_type, + block_position=block_position, + entity_id=entity_id, + entity_eye_height=entity_eye_height, + tick=tick, + delay=delay, + color=color, + ) diff --git a/mcproto/types/quaternion.py b/mcproto/types/quaternion.py new file mode 100644 index 00000000..da83ca69 --- /dev/null +++ b/mcproto/types/quaternion.py @@ -0,0 +1,83 @@ +from __future__ import annotations + +import math +from typing import final + +from attrs import Attribute, define, field, validators +from typing_extensions import override + +from mcproto.buffer import Buffer +from mcproto.protocol import StructFormat +from mcproto.types.abc import MCType + + +@define +@final +class Quaternion(MCType): + """Represents a quaternion. + + :param x: The x component. + :param y: The y component. + :param z: The z component. + :param w: The w component. + """ + + @staticmethod + def finite_validator(instance: Quaternion, attribute: Attribute[float], value: float) -> None: + """Validate that the quaternion components are finite.""" + if not math.isfinite(value): + raise ValueError(f"Quaternion components must be finite, got {value!r}") + + x: float = field(validator=[validators.instance_of((float, int)), finite_validator.__get__(object)]) + y: float = field(validator=[validators.instance_of((float, int)), finite_validator.__get__(object)]) + z: float = field(validator=[validators.instance_of((float, int)), finite_validator.__get__(object)]) + w: float = field(validator=[validators.instance_of((float, int)), finite_validator.__get__(object)]) + + @override + def serialize_to(self, buf: Buffer) -> None: + buf.write_value(StructFormat.FLOAT, self.x) + buf.write_value(StructFormat.FLOAT, self.y) + buf.write_value(StructFormat.FLOAT, self.z) + buf.write_value(StructFormat.FLOAT, self.w) + + @override + @classmethod + def deserialize(cls, buf: Buffer) -> Quaternion: + x = buf.read_value(StructFormat.FLOAT) + y = buf.read_value(StructFormat.FLOAT) + z = buf.read_value(StructFormat.FLOAT) + w = buf.read_value(StructFormat.FLOAT) + return cls(x=x, y=y, z=z, w=w) + + def __add__(self, other: Quaternion) -> Quaternion: + # Use the type of self to return a Quaternion or a subclass. + return type(self)(x=self.x + other.x, y=self.y + other.y, z=self.z + other.z, w=self.w + other.w) + + def __sub__(self, other: Quaternion) -> Quaternion: + return type(self)(x=self.x - other.x, y=self.y - other.y, z=self.z - other.z, w=self.w - other.w) + + def __neg__(self) -> Quaternion: + return type(self)(x=-self.x, y=-self.y, z=-self.z, w=-self.w) + + def __mul__(self, other: float) -> Quaternion: + return type(self)(x=self.x * other, y=self.y * other, z=self.z * other, w=self.w * other) + + def __truediv__(self, other: float) -> Quaternion: + return type(self)(x=self.x / other, y=self.y / other, z=self.z / other, w=self.w / other) + + def to_tuple(self) -> tuple[float, float, float, float]: + """Convert the quaternion to a tuple.""" + return (self.x, self.y, self.z, self.w) + + def norm_squared(self) -> float: + """Return the squared norm of the quaternion.""" + return self.x**2 + self.y**2 + self.z**2 + self.w**2 + + def norm(self) -> float: + """Return the norm of the quaternion.""" + return math.sqrt(self.norm_squared()) + + def normalize(self) -> Quaternion: + """Return the normalized quaternion.""" + norm = self.norm() + return Quaternion(x=self.x / norm, y=self.y / norm, z=self.z / norm, w=self.w / norm) diff --git a/mcproto/types/recipe.py b/mcproto/types/recipe.py new file mode 100644 index 00000000..bbda97f9 --- /dev/null +++ b/mcproto/types/recipe.py @@ -0,0 +1,605 @@ +from __future__ import annotations + +from abc import abstractmethod +from typing import ClassVar, final + +from attrs import Attribute, define, field, validators +from typing_extensions import Self, override + +from mcproto.buffer import Buffer +from mcproto.protocol import StructFormat +from mcproto.types.abc import MCType +from mcproto.types.identifier import Identifier +from mcproto.types.slot import Slot +from mcproto.utils.abc import RequiredParamsABCMixin + + +@final +@define +class Ingredient(MCType): + """Represents an item in a :class:`Recipe`. + + :param count: The count of the item. + :type count: int + :param items: The items that can be used to craft the item. + :type items: list[:class:`~mcproto.types.slot.Slot`] + + .. note:: Each item in the list has to have a count of 1. + """ + + count: int = field(validator=validators.ge(1)) + items: set[Slot] = field() + + @items.validator # pyright: ignore + def _check_quantity(self, attribute: Attribute[set[Slot]], value: set[Slot]) -> None: + """Check that each ingredient is valid.""" + if any(item.data is None or item.data.num != 1 for item in value): + raise ValueError("Each item in the list has to have a count of 1.") + + @override + def serialize_to(self, buf: Buffer) -> None: + buf.write_varint(self.count) + buf.write_varint(len(self.items)) + for item in self.items: + item.serialize_to(buf) + + @override + @classmethod + def deserialize(cls, buf: Buffer) -> Self: + count = buf.read_varint() + items = {Slot.deserialize(buf) for _ in range(buf.read_varint())} + return cls(count=count, items=items) + + +@define +class Recipe(MCType, RequiredParamsABCMixin): + """Represents a recipe in the :class:`~mcproto.packets.play.UpdateRecipes` packet. + + + + :param recipe_id: The ID of the recipe. + :type recipe_id: :class:`~mcproto.types.identifier.Identifier` + """ + + _REQUIRED_CLASS_VARS = ("recipe_type",) + + recipe_id: Identifier + recipe_type: ClassVar[int] = NotImplemented + recipe_type_identifier: ClassVar[Identifier] = NotImplemented # unused + + @override + @abstractmethod + def serialize_to(self, buf: Buffer) -> None: + self.recipe_id.serialize_to(buf) + buf.write_varint(self.recipe_type) + + @classmethod + @abstractmethod + def _deserialize(cls, buf: Buffer, recipe_id: Identifier) -> Self: ... + + @override + @classmethod + def deserialize(cls, buf: Buffer) -> Recipe: + recipe_id = Identifier.deserialize(buf) + recipe_type = buf.read_varint() + return ID_ASSOCIATION[recipe_type]._deserialize(buf, recipe_id) + + +@final +@define +class ShapedRecipe(Recipe): + """Represents a shaped recipe in the :class:`~mcproto.packets.play.UpdateRecipes` packet. + + Shaped crafting recipe. All items must be present in the same pattern (which may be flipped horizontally or + translated). + + :param group: Used to group similar recipes together in the recipe book. Tag is present in recipe JSON. + :type group: str + :param category: The category of the recipe. Building = 0, Redstone = 1, Equipment = 2, Misc = 3 + :type category: int + :param width: The width of the recipe. + :type width: int + :param height: The height of the recipe. + :type height: int + :param ingredients: The ingredients of the recipe. + :type ingredients: list[:class:`Ingredient`] + :param result: The result of the recipe. + :type result: :class:`~mcproto.types.slot.Slot` + :param show_toast: Whether to show a toast notification when the recipe is unlocked. + :type show_toast: bool + """ + + recipe_type: ClassVar[int] = 0 + recipe_type_identifier: ClassVar[Identifier] = Identifier("minecraft", "crafting_shaped") + + group: str + category: int + width: int + height: int + ingredients: list[Ingredient] + result: Slot + show_toast: bool + + @override + def serialize_to(self, buf: Buffer) -> None: + super().serialize_to(buf) + buf.write_utf(self.group) + buf.write_varint(self.category) + buf.write_varint(self.width) + buf.write_varint(self.height) + buf.write_varint(len(self.ingredients)) + for ingredient in self.ingredients: + ingredient.serialize_to(buf) + self.result.serialize_to(buf) + buf.write_value(StructFormat.BOOL, self.show_toast) + + @override + @classmethod + def _deserialize(cls, buf: Buffer, recipe_id: Identifier) -> Self: + group = buf.read_utf() + category = buf.read_varint() + width = buf.read_varint() + height = buf.read_varint() + ingredients = [Ingredient.deserialize(buf) for _ in range(buf.read_varint())] + result = Slot.deserialize(buf) + show_toast = buf.read_value(StructFormat.BOOL) + return cls( + recipe_id=recipe_id, + group=group, + category=category, + width=width, + height=height, + ingredients=ingredients, + result=result, + show_toast=show_toast, + ) + + +@final +@define +class ShapelessRecipe(Recipe): + """Represents a shapeless recipe in the :class:`~mcproto.packets.play.UpdateRecipes` packet. + + Shapeless crafting recipe. Items can be anywhere in the grid. + + :param group: Used to group similar recipes together in the recipe book. Tag is present in recipe JSON. + :type group: str + :param category: The category of the recipe. Building = 0, Redstone = 1, Equipment = 2, Misc = 3 + :type category: int + :param ingredients: The ingredients of the recipe. + :type ingredients: list[:class:`Ingredient`] + :param result: The result of the recipe. + :type result: :class:`~mcproto.types.slot.Slot` + """ + + recipe_type: ClassVar[int] = 1 + recipe_type_identifier: ClassVar[Identifier] = Identifier("minecraft", "crafting_shapeless") + + group: str + category: int + ingredients: list[Ingredient] + result: Slot + + @override + def serialize_to(self, buf: Buffer) -> None: + super().serialize_to(buf) + buf.write_utf(self.group) + buf.write_varint(self.category) + buf.write_varint(len(self.ingredients)) + for ingredient in self.ingredients: + ingredient.serialize_to(buf) + self.result.serialize_to(buf) + + @override + @classmethod + def _deserialize(cls, buf: Buffer, recipe_id: Identifier) -> Self: + group = buf.read_utf() + category = buf.read_varint() + ingredients = [Ingredient.deserialize(buf) for _ in range(buf.read_varint())] + result = Slot.deserialize(buf) + return cls( + recipe_id=recipe_id, + group=group, + category=category, + ingredients=ingredients, + result=result, + ) + + +@define +class _SpecialRecipe(Recipe): + """Represents a recipe containing only the category. + + :param category: The category of the recipe. Building = 0, Redstone = 1, Equipment = 2, Misc = 3 + :type category: int + """ + + category: int + + @override + def serialize_to(self, buf: Buffer) -> None: + super().serialize_to(buf) + buf.write_varint(self.category) + + @override + @classmethod + def _deserialize(cls, buf: Buffer, recipe_id: Identifier) -> Self: + category = buf.read_varint() + return cls(recipe_id=recipe_id, category=category) + + +@final +class ArmorDyeRecipe(_SpecialRecipe): + """Recipe for dying leather armor.""" + + recipe_type_identifier: ClassVar[Identifier] = Identifier("minecraft", "crafting_special_armordye") + recipe_type: ClassVar[int] = 2 + + __slots__ = () + + +@final +class BookCloningRecipe(_SpecialRecipe): + """Recipe for copying contents of written books.""" + + recipe_type_identifier: ClassVar[Identifier] = Identifier("minecraft", "crafting_special_bookcloning") + recipe_type: ClassVar[int] = 3 + + __slots__ = () + + +@final +class MapCloningRecipe(_SpecialRecipe): + """Recipe for copying maps.""" + + recipe_type_identifier: ClassVar[Identifier] = Identifier("minecraft", "crafting_special_mapcloning") + recipe_type: ClassVar[int] = 4 + + __slots__ = () + + +@final +class MapExtendingRecipe(_SpecialRecipe): + """Recipe for adding paper to maps.""" + + recipe_type_identifier: ClassVar[Identifier] = Identifier("minecraft", "crafting_special_mapextending") + recipe_type: ClassVar[int] = 5 + + __slots__ = () + + +@final +class FireworkRocketRecipe(_SpecialRecipe): + """Recipe for making firework rockets.""" + + recipe_type_identifier: ClassVar[Identifier] = Identifier("minecraft", "crafting_special_firework_rocket") + recipe_type: ClassVar[int] = 6 + + __slots__ = () + + +@final +class FireworkStarRecipe(_SpecialRecipe): + """Recipe for making firework stars.""" + + recipe_type_identifier: ClassVar[Identifier] = Identifier("minecraft", "crafting_special_firework_star") + recipe_type: ClassVar[int] = 7 + + __slots__ = () + + +@final +class FireworkStarFadeRecipe(_SpecialRecipe): + """Recipe for making firework stars fade between multiple colors.""" + + recipe_type_identifier: ClassVar[Identifier] = Identifier("minecraft", "crafting_special_firework_star_fade") + recipe_type: ClassVar[int] = 8 + + __slots__ = () + + +@final +class TippedArrowRecipe(_SpecialRecipe): + """Recipe for crafting tipped arrows.""" + + recipe_type_identifier: ClassVar[Identifier] = Identifier("minecraft", "crafting_special_tippedarrow") + recipe_type: ClassVar[int] = 9 + + __slots__ = () + + +@final +class BannerDuplicateRecipe(_SpecialRecipe): + """Recipe for copying banner patterns.""" + + recipe_type_identifier: ClassVar[Identifier] = Identifier("minecraft", "crafting_special_bannerduplicate") + recipe_type: ClassVar[int] = 10 + + __slots__ = () + + +@final +class ShieldDecorationRecipe(_SpecialRecipe): + """Recipe for applying a banner's pattern to a shield.""" + + recipe_type_identifier: ClassVar[Identifier] = Identifier("minecraft", "crafting_special_shielddecoration") + recipe_type: ClassVar[int] = 11 + + __slots__ = () + + +@final +class ShulkerBoxColoringRecipe(_SpecialRecipe): + """Recipe for recoloring a shulker box.""" + + recipe_type_identifier: ClassVar[Identifier] = Identifier("minecraft", "crafting_special_shulkerboxcoloring") + recipe_type: ClassVar[int] = 12 + + __slots__ = () + + +@final +class SuspiciousStewRecipe(_SpecialRecipe): + """Recipe for crafting suspicious stews.""" + + recipe_type_identifier: ClassVar[Identifier] = Identifier("minecraft", "crafting_special_suspiciousstew") + recipe_type: ClassVar[int] = 13 + + __slots__ = () + + +@final +class RepairItemRecipe(_SpecialRecipe): + """Recipe for repairing items via crafting.""" + + recipe_type_identifier: ClassVar[Identifier] = Identifier("minecraft", "crafting_special_repairitem") + recipe_type: ClassVar[int] = 14 + + __slots__ = () + + +@final +class DecoratedPotRecipe(_SpecialRecipe): + """Recipe for crafting decorated pots.""" + + recipe_type_identifier: ClassVar[Identifier] = Identifier("minecraft", "crafting_decorated_pot") + recipe_type: ClassVar[int] = 22 + + __slots__ = () + + +@define +class SmeltingRecipe(Recipe): + """Smelting recipe. + + :param group: Used to group similar recipes together in the recipe book. Tag is present in recipe JSON. + :type group: str + :param category: The category of the recipe. Building = 0, Redstone = 1, Equipment = 2, Misc = 3 + :type category: int + :param ingredient: The ingredient of the recipe. + :type ingredient: :class:`Ingredient` + :param result: The result of the recipe. + :type result: :class:`~mcproto.types.slot.Slot` + :param experience: The experience given when the recipe is completed. + :type experience: float + :param cooking_time: The time it takes to complete the recipe. + :type cooking_time: int + """ + + recipe_type: ClassVar[int] = 15 + recipe_type_identifier: ClassVar[Identifier] = Identifier("minecraft", "smelting") + + group: str + category: int + ingredient: Ingredient + result: Slot + experience: float + cooking_time: int + + @override + def serialize_to(self, buf: Buffer) -> None: + super().serialize_to(buf) + buf.write_utf(self.group) + buf.write_varint(self.category) + self.ingredient.serialize_to(buf) + self.result.serialize_to(buf) + buf.write_value(StructFormat.FLOAT, self.experience) + buf.write_varint(self.cooking_time) + + @override + @classmethod + def _deserialize(cls, buf: Buffer, recipe_id: Identifier) -> Self: + group = buf.read_utf() + category = buf.read_varint() + ingredient = Ingredient.deserialize(buf) + result = Slot.deserialize(buf) + experience = buf.read_value(StructFormat.FLOAT) + cooking_time = buf.read_varint() + return cls( + recipe_id=recipe_id, + group=group, + category=category, + ingredient=ingredient, + result=result, + experience=experience, + cooking_time=cooking_time, + ) + + +@final +class BlastingRecipe(SmeltingRecipe): + """Blast furnace recipe.""" + + recipe_type: ClassVar[int] = 16 + recipe_type_identifier: ClassVar[Identifier] = Identifier("minecraft", "blasting") + + __slots__ = () + + +@final +class SmokingRecipe(SmeltingRecipe): + """Smoker recipe.""" + + recipe_type: ClassVar[int] = 17 + recipe_type_identifier: ClassVar[Identifier] = Identifier("minecraft", "smoking") + + __slots__ = () + + +@final +class CampfireRecipe(SmeltingRecipe): + """Campfire recipe.""" + + recipe_type: ClassVar[int] = 18 + recipe_type_identifier: ClassVar[Identifier] = Identifier("minecraft", "campfire_cooking") + + __slots__ = () + + +@final +@define +class StoneCuttingRecipe(Recipe): + """Stone cutting recipe. + + :param group: Used to group similar recipes together in the recipe book. Tag is present in recipe JSON. + :type group: str + :param ingredient: The ingredient of the recipe. + :type ingredient: :class:`Ingredient` + :param result: The result of the recipe. + :type result: :class:`~mcproto.types.slot.Slot` + """ + + recipe_type: ClassVar[int] = 19 + recipe_type_identifier: ClassVar[Identifier] = Identifier("minecraft", "stonecutting") + + group: str + ingredient: Ingredient + result: Slot + + @override + def serialize_to(self, buf: Buffer) -> None: + super().serialize_to(buf) + buf.write_utf(self.group) + self.ingredient.serialize_to(buf) + self.result.serialize_to(buf) + + @override + @classmethod + def _deserialize(cls, buf: Buffer, recipe_id: Identifier) -> Self: + group = buf.read_utf() + ingredient = Ingredient.deserialize(buf) + result = Slot.deserialize(buf) + return cls( + recipe_id=recipe_id, + group=group, + ingredient=ingredient, + result=result, + ) + + +@define +class SmithingTrimRecipe(Recipe): + """Smithing transform recipe. + + :param template: The smithing template. + :type template: :class:`Ingredient` + :param base: The base item of the recipe. + :type base: :class:`Ingredient` + :param addition: The additional ingredient of the recipe. + :type addition: :class:`Ingredient` + """ + + recipe_type: ClassVar[int] = 21 + recipe_type_identifier: ClassVar[Identifier] = Identifier("minecraft", "smithing_trim") + + template: Ingredient + base: Ingredient + addition: Ingredient + + @override + def serialize_to(self, buf: Buffer) -> None: + super().serialize_to(buf) + self.template.serialize_to(buf) + self.base.serialize_to(buf) + self.addition.serialize_to(buf) + + @override + @classmethod + def _deserialize(cls, buf: Buffer, recipe_id: Identifier) -> Self: + template = Ingredient.deserialize(buf) + base = Ingredient.deserialize(buf) + addition = Ingredient.deserialize(buf) + return cls( + recipe_id=recipe_id, + template=template, + base=base, + addition=addition, + ) + + +@final +@define +class SmithingTransformRecipe(SmithingTrimRecipe): + """Recipe for smithing netherite gear. + + :param template: The smithing template. + :type template: :class:`Ingredient` + :param base: The base item of the recipe. + :type base: :class:`Ingredient` + :param addition: The additional ingredient of the recipe. + :type addition: :class:`Ingredient` + :param result: The result of the recipe. + :type result: :class:`~mcproto.types.slot.Slot` + """ + + recipe_type: ClassVar[int] = 20 + recipe_type_identifier: ClassVar[Identifier] = Identifier("minecraft", "smithing_transform") + + result: Slot + + @override + def serialize_to(self, buf: Buffer) -> None: + super().serialize_to(buf) + self.result.serialize_to(buf) + + @override + @classmethod + def _deserialize(cls, buf: Buffer, recipe_id: Identifier) -> Self: + template = Ingredient.deserialize(buf) + base = Ingredient.deserialize(buf) + addition = Ingredient.deserialize(buf) + result = Slot.deserialize(buf) + return cls( + recipe_id=recipe_id, + template=template, + base=base, + addition=addition, + result=result, + ) + + +ID_ASSOCIATION: dict[int, type[Recipe]] = { + 0: ShapedRecipe, + 1: ShapelessRecipe, + 2: ArmorDyeRecipe, + 3: BookCloningRecipe, + 4: MapCloningRecipe, + 5: MapExtendingRecipe, + 6: FireworkRocketRecipe, + 7: FireworkStarRecipe, + 8: FireworkStarFadeRecipe, + 9: TippedArrowRecipe, + 10: BannerDuplicateRecipe, + 11: ShieldDecorationRecipe, + 12: ShulkerBoxColoringRecipe, + 13: SuspiciousStewRecipe, + 14: RepairItemRecipe, + 15: SmeltingRecipe, + 16: BlastingRecipe, + 17: SmokingRecipe, + 18: CampfireRecipe, + 19: StoneCuttingRecipe, + 20: SmithingTransformRecipe, + 21: SmithingTrimRecipe, + 22: DecoratedPotRecipe, +} diff --git a/mcproto/types/registry_tag.py b/mcproto/types/registry_tag.py new file mode 100644 index 00000000..af6d214f --- /dev/null +++ b/mcproto/types/registry_tag.py @@ -0,0 +1,42 @@ +from __future__ import annotations + +from typing import final + +from attrs import define +from typing_extensions import override + +from mcproto.buffer import Buffer +from mcproto.types.abc import MCType +from mcproto.types.identifier import Identifier + + +@final +@define +class RegistryTag(MCType): + """Represents a tag for a registry. + + :param registry: The registry this tag is for. + :param name: The name of the tag. + :param values: The values in the tag. + """ + + name: Identifier + values: list[int] + + @override + def serialize_to(self, buf: Buffer) -> None: + self.name.serialize_to(buf) + buf.write_varint(len(self.values)) + for value in self.values: + buf.write_varint(value) + + @override + @classmethod + def deserialize(cls, buf: Buffer) -> RegistryTag: + name = Identifier.deserialize(buf) + values = [buf.read_varint() for _ in range(buf.read_varint())] + return cls(name, values) + + @override + def __str__(self) -> str: + return f"#{self.name}" diff --git a/mcproto/types/slot.py b/mcproto/types/slot.py new file mode 100644 index 00000000..84d213f2 --- /dev/null +++ b/mcproto/types/slot.py @@ -0,0 +1,76 @@ +from __future__ import annotations + +from typing import NamedTuple, final + +from attrs import define +from typing_extensions import override + +from mcproto.buffer import Buffer +from mcproto.protocol import StructFormat +from mcproto.types.abc import MCType +from mcproto.types.nbt import EndNBT, NBTag + +__all__ = ["Slot"] + +""" + +""" + + +class SlotData(NamedTuple): + """Represents the data of a slot in an inventory. + + :param item: The item ID of the item in the slot. + :type item: int + :param num: The count of items in the slot. + :type num: int + :param nbt: The NBT data of the item in the slot, None if there is no item or no NBT data. + :type nbt: :class:`~mcproto.types.nbt.NBTag`, optional + """ + + item: int + num: int + nbt: NBTag | None = None + + +@define +@final +class Slot(MCType): + """Represents a slot in an inventory. + + :param data: The data of the slot. + + .. note:: The optional parameters are present if and only if the slot is present. + """ + + data: SlotData | None + + @override + def serialize_to(self, buf: Buffer) -> None: + buf.write_value(StructFormat.BOOL, self.data is not None) + if self.data is not None: + buf.write_varint(self.data.item) + buf.write_value(StructFormat.BYTE, self.data.num) + if self.data.nbt is None: + EndNBT().serialize_to(buf) + else: + self.data.nbt.serialize_to(buf, with_name=False) + # In 1.20.2 and later, the NBT is not named, there is only the + # type (TAG_End or TAG_Compound) and the payload. + + @override + @classmethod + def deserialize(cls, buf: Buffer) -> Slot: + present = buf.read_value(StructFormat.BOOL) + if not present: + return cls(None) + item_id = buf.read_varint() + item_count = buf.read_value(StructFormat.BYTE) + nbt = NBTag.deserialize(buf, with_name=False) + if isinstance(nbt, EndNBT): + nbt = None + return cls(SlotData(item_id, item_count, nbt)) + + @override + def __hash__(self) -> int: + return hash(self.data) diff --git a/mcproto/types/trade.py b/mcproto/types/trade.py new file mode 100644 index 00000000..3bf943ad --- /dev/null +++ b/mcproto/types/trade.py @@ -0,0 +1,89 @@ +from __future__ import annotations + +from typing import final + +from attrs import define +from typing_extensions import override + +from mcproto.buffer import Buffer +from mcproto.protocol.base_io import StructFormat +from mcproto.types.abc import MCType +from mcproto.types.slot import Slot + + +@final +@define +class Trade(MCType): + """Defines a trade in a trade list. + + :param input_item: The item to be traded. + :type input_item: Slot + :param input_item2: The second item to be traded. + :type input_item2: Slot + :param output_item: The item to be received. + :type output_item: Slot + :param trade_disabled: Whether the trade is disabled. + :type trade_disabled: bool + :param trade_uses: The number of times the trade has been used. + :type trade_uses: int + :param max_trade_uses: The maximum number of times the trade can be used. + :type max_trade_uses: int + :param experience: The experience given to the villager when the trade is used. + :type experience: int + :param special_price: Price delta for the trade. + :type special_price: int + :param price_multiplier: Price multiplier for the trade. + :type price_multiplier: float + :param demand: The demand for the trade. + :type demand: int + """ + + input_item: Slot + input_item2: Slot + output_item: Slot + trade_disabled: bool + trade_uses: int + max_trade_uses: int + experience: int + special_price: int + price_multiplier: float + demand: int + + @override + def serialize_to(self, buf: Buffer) -> None: + self.input_item.serialize_to(buf) + self.input_item2.serialize_to(buf) + self.output_item.serialize_to(buf) + buf.write_value(StructFormat.BYTE, int(self.trade_disabled)) + buf.write_varint(self.trade_uses) + buf.write_varint(self.max_trade_uses) + buf.write_varint(self.experience) + buf.write_varint(self.special_price) + buf.write_value(StructFormat.FLOAT, self.price_multiplier) + buf.write_varint(self.demand) + + @override + @classmethod + def deserialize(cls, buf: Buffer) -> Trade: + input_item = Slot.deserialize(buf) + input_item2 = Slot.deserialize(buf) + output_item = Slot.deserialize(buf) + trade_disabled = bool(buf.read_value(StructFormat.BYTE)) + trade_uses = buf.read_varint() + max_trade_uses = buf.read_varint() + experience = buf.read_varint() + special_price = buf.read_varint() + price_multiplier = buf.read_value(StructFormat.FLOAT) + demand = buf.read_varint() + return cls( + input_item=input_item, + input_item2=input_item2, + output_item=output_item, + trade_disabled=trade_disabled, + trade_uses=trade_uses, + max_trade_uses=max_trade_uses, + experience=experience, + special_price=special_price, + price_multiplier=price_multiplier, + demand=demand, + ) diff --git a/mcproto/types/vec3.py b/mcproto/types/vec3.py new file mode 100644 index 00000000..112bc0e2 --- /dev/null +++ b/mcproto/types/vec3.py @@ -0,0 +1,187 @@ +from __future__ import annotations + +import math +from typing import final + +from attrs import Attribute, define, field, validators +from typing_extensions import override + +from mcproto.buffer import Buffer +from mcproto.protocol import StructFormat +from mcproto.types.abc import MCType + + +@define +class Vec3(MCType): + """Represents a 3D vector. + + :param x: The x component. + :param y: The y component. + :param z: The z component. + """ + + @staticmethod + def finite_validator(instance: Vec3, attribute: Attribute[float], value: float) -> None: + """Validate that the quaternion components are finite.""" + if not math.isfinite(value): + raise ValueError(f"Quaternion components must be finite, got {value!r}") + + x: float = field(validator=[validators.instance_of((float, int)), finite_validator.__get__(object)]) + y: float = field(validator=[validators.instance_of((float, int)), finite_validator.__get__(object)]) + z: float = field(validator=[validators.instance_of((float, int)), finite_validator.__get__(object)]) + + @override + def serialize_to(self, buf: Buffer) -> None: + buf.write_value(StructFormat.FLOAT, self.x) + buf.write_value(StructFormat.FLOAT, self.y) + buf.write_value(StructFormat.FLOAT, self.z) + + @override + @classmethod + def deserialize(cls, buf: Buffer) -> Vec3: + x = buf.read_value(StructFormat.FLOAT) + y = buf.read_value(StructFormat.FLOAT) + z = buf.read_value(StructFormat.FLOAT) + return cls(x=x, y=y, z=z) + + def serialize_to_double(self, buf: Buffer) -> None: + """Serialize the vector to a buffer using double precision. + + .. seealso:: :meth:`serialize_to` + """ + buf.write_value(StructFormat.DOUBLE, self.x) + buf.write_value(StructFormat.DOUBLE, self.y) + buf.write_value(StructFormat.DOUBLE, self.z) + + @classmethod + def deserialize_double(cls, buf: Buffer) -> Vec3: + """Deserialize a vector from a buffer using double precision. + + .. seealso:: :meth:`deserialize` + """ + x = buf.read_value(StructFormat.DOUBLE) + y = buf.read_value(StructFormat.DOUBLE) + z = buf.read_value(StructFormat.DOUBLE) + return cls(x=x, y=y, z=z) + + def __add__(self, other: Vec3) -> Vec3: + # Use the type of self to return a Vec3 or a subclass. + return type(self)(x=self.x + other.x, y=self.y + other.y, z=self.z + other.z) + + def __sub__(self, other: Vec3) -> Vec3: + return type(self)(x=self.x - other.x, y=self.y - other.y, z=self.z - other.z) + + def __neg__(self) -> Vec3: + return type(self)(x=-self.x, y=-self.y, z=-self.z) + + def __mul__(self, other: float) -> Vec3: + return type(self)(x=self.x * other, y=self.y * other, z=self.z * other) + + def __truediv__(self, other: float) -> Vec3: + return type(self)(x=self.x / other, y=self.y / other, z=self.z / other) + + def to_position(self) -> Position: + """Convert the vector to a position.""" + return Position(x=int(self.x), y=int(self.y), z=int(self.z)) + + def to_tuple(self) -> tuple[float, float, float]: + """Convert the vector to a tuple.""" + return (self.x, self.y, self.z) + + def to_vec3(self) -> Vec3: + """Convert the vector to a Vec3. + + This function creates a new Vec3 object with the same components. + """ + return Vec3(x=self.x, y=self.y, z=self.z) + + def norm_squared(self) -> float: + """Return the squared norm of the vector.""" + return self.x**2 + self.y**2 + self.z**2 + + def norm(self) -> float: + """Return the norm of the vector.""" + return math.sqrt(self.norm_squared()) + + def normalize(self) -> Vec3: + """Return the normalized vector.""" + norm = self.norm() + return Vec3(x=self.x / norm, y=self.y / norm, z=self.z / norm) + + +@final +@define +class Position(Vec3): + """Represents a position in the world. + + :param x: The x coordinate (26 bits). + :param y: The y coordinate (12 bits). + :param z: The z coordinate (26 bits). + """ + + x: int = field( # type: ignore + validator=[ + validators.instance_of((float, int)), + Vec3.finite_validator, + validators.ge(float(-1 << 25)), + validators.lt(float(1 << 25)), + ], + converter=int, + ) + y: int = field( # type: ignore + validator=[ + validators.instance_of((float, int)), + Vec3.finite_validator, + validators.ge(float(-1 << 11)), + validators.lt(float(1 << 11)), + ], + converter=int, + ) + z: int = field( # type: ignore + validator=[ + validators.instance_of((float, int)), + Vec3.finite_validator, + validators.ge(float(-1 << 25)), + validators.lt(float(1 << 25)), + ], + converter=int, + ) + + __slots__ = () + + @override + def serialize_to(self, buf: Buffer) -> None: + encoded = ((self.x & 0x3FFFFFF) << 38) | ((self.z & 0x3FFFFFF) << 12) | (self.y & 0xFFF) + + # Convert the bit mess to a signed integer for packing. + if encoded & 0x8000000000000000: + encoded -= 1 << 64 + buf.write_value(StructFormat.LONGLONG, encoded) + + @override + @classmethod + def deserialize(cls, buf: Buffer) -> Position: + encoded = buf.read_value(StructFormat.LONGLONG) + x = (encoded >> 38) & 0x3FFFFFF + z = (encoded >> 12) & 0x3FFFFFF + y = encoded & 0xFFF + + # Convert back to signed integers. + if x >= 1 << 25: + x -= 1 << 26 + if y >= 1 << 11: + y -= 1 << 12 + if z >= 1 << 25: + z -= 1 << 26 + + return cls(x=x, y=y, z=z) + + +POS_UP = Position(0, 1, 0) +POS_DOWN = Position(0, -1, 0) +POS_NORTH = Position(0, 0, -1) +POS_SOUTH = Position(0, 0, 1) +POS_EAST = Position(1, 0, 0) +POS_WEST = Position(-1, 0, 0) + +POS_ZERO = Position(0, 0, 0) diff --git a/mcproto/utils/abc.py b/mcproto/utils/abc.py index a03f73d4..cc2f578a 100644 --- a/mcproto/utils/abc.py +++ b/mcproto/utils/abc.py @@ -68,21 +68,17 @@ class Serializable(ABC): Any class that inherits from this class and adds parameters should use the :func:`~mcproto.utils.abc.define` decorator. - """ - - __slots__ = () - def __attrs_post_init__(self) -> None: - """Run the validation method after the object is initialized. + Example usage: - This function is responsible for conversion/transformation of given values right after initialization (often - for example to convert an int initialization param into a specific enum variant) + .. literalinclude:: /../tests/mcproto/utils/test_serializable.py + :start-after: # region ToyClass + :end-before: # endregion + :linenos: + :language: python + """ - .. note:: - If you override this method, make sure to call the superclass method at some point to ensure that the - validation is run. - """ - self.validate() + __slots__ = () def serialize(self) -> Buffer: """Represent the object as a :class:`~mcproto.Buffer` (transmittable sequence of bytes).""" @@ -92,21 +88,11 @@ def serialize(self) -> Buffer: @abstractmethod def serialize_to(self, buf: Buffer, /) -> None: - """Write the object to a :class:`~mcproto.Buffer`.""" + """Write the object to a :class:`~mcproto.buffer.Buffer`.""" raise NotImplementedError - def validate(self) -> None: - """Validate the object's attributes, raising an exception if they are invalid. - - By default, this method does nothing. Override it in your subclass to add validation logic. - - .. note:: - This method is called by :meth:`~mcproto.utils.abc.Serializable.__attrs_post_init__` - """ - return - @classmethod @abstractmethod def deserialize(cls, buf: Buffer, /) -> Self: - """Construct the object from a :class:`~mcproto.Buffer` (transmittable sequence of bytes).""" + """Construct the object from a :class:`~mcproto.buffer.Buffer` (transmittable sequence of bytes).""" raise NotImplementedError diff --git a/scripts/__init__.py b/scripts/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/scripts/entity_generator.py b/scripts/entity_generator.py new file mode 100644 index 00000000..6fbcf76b --- /dev/null +++ b/scripts/entity_generator.py @@ -0,0 +1,282 @@ +from __future__ import annotations + +import subprocess +import sys +from pathlib import Path +from typing import Dict, List, Union, cast + +from scripts.entity_generator_data import ENTITY_DATA, EntityData, Field + +BASE_CLASS = ''' +class {name}({base}): + """{class_description} + + {fields_docstring} + + """ + + {fields} + + __slots__ = () + +''' + + +ENTRY_FIELD = """{name}: {input} = entry({type}, {default})""" +INPUT_UNAVAILABLE = """ClassVar[{input}]""" +# Mark as ignore by sphinx +PROXY_FIELD = """{name}: {input} = proxy({target}, {type}, {kwargs})""" + +FIELD_DESCRIPTION = """:param {name}: {description} +:type {name}: {input}, optional, default: {default}""" +PROXY_DESCRIPTION = """:param {name}: {description} (this affects :attr:`{target}`) +:type {name}: {input}, optional""" +UNAVAILABLE_PREFIX = "_" +TYPE_SUFFIX = "EME" # EntityMetadataEntry +NAME_SUFFIX = "EM" # EntityMetadata + + +FILE_HEADER = """ +###################################################################### +# This file is automatically generated by the entity generator script. +# You can modify it by changing what you want in the script. +###################################################################### + +from mcproto.types.entity.enums import {enums} + +__all__ = [ + {all} +] +""" + +BASE_FILE = """ +from __future__ import annotations +{header} +from typing import ClassVar, Any + +from mcproto.types.entity.metadata import ( + proxy, + entry, + EntityMetadata, +) +from mcproto.types.entity.metadata_types import {types} +from mcproto.types.slot import Slot, SlotData +from mcproto.types.chat import TextComponent +from mcproto.types.nbt import NBTag, EndNBT +from mcproto.types.particle_data import ParticleData +from mcproto.types.vec3 import Position, Vec3 +from mcproto.types.quaternion import Quaternion +from mcproto.types.uuid import UUID + +{classes} +""" +INIT_FILE = """ +{header} +from mcproto.types.entity.metadata import EntityMetadata +from mcproto.types.entity.generated import {generated} +""" + +FILE_PATH = "mcproto/types/entity/generated.py" +INIT_PATH = "mcproto/types/entity/__init__.py" + +# This dictionary holds the decumentation for each entity to allow it to be appended to inherited classes +main_doc_repo: dict[str, str] = {} + + +def generate_class(entity_description: EntityData) -> tuple[str, set[str], set[str]]: # noqa: PLR0912 + """Generate a class from the entity description. + + :param entity_description: The entity description to generate the class from. + + :return: The generated string for the class, a set of used enums, and a set of used types. + """ + field_docs: list[str] = [] + fields: list[str] = [] + used_enums: set[str] = set() + used_types: set[str] = set() + name = entity_description["name"] + name = cast(str, name) + NAME_SUFFIX # EntityMetadata + base = entity_description.get("base", "EntityMetadata") + base = cast(str, base) + if base != "EntityMetadata": + base += NAME_SUFFIX + for variable in entity_description["fields"]: + variable = cast(Field, variable) + v_type = cast(str, variable["type"]) + v_name = cast(str, variable["name"]) + v_default = variable["default"] + v_input = variable["input"] + v_description = variable.get("description", "") + v_proxy = cast(List[Dict[str, Union[type, str, int]]], variable.get("proxy", [])) + v_available = variable.get("available", True) + v_enum = variable.get("enum", False) + + if v_enum: + used_enums.add(v_type) + v_default = f"{v_type}.{v_default}" + + v_type = v_type + TYPE_SUFFIX + used_types.add(v_type) + + if not v_available: + v_name = UNAVAILABLE_PREFIX + v_name + + if isinstance(v_input, type): + v_input = v_input.__name__ + v_input = cast(str, v_input) + + if v_input == "str": + v_default = f'"{v_default}"' + + if v_available: + if v_description: + if v_enum or not v_input.startswith(("str", "tuple", "float", "int", "bool")): + v_default_desc = f":attr:`{v_default}`" + v_input_desc = f":class:`{v_input}`" + else: + v_default_desc = v_default + v_input_desc = v_input + + field_docs.append( + FIELD_DESCRIPTION.format( + name=v_name, description=v_description, input=v_input_desc, default=v_default_desc + ) + ) + else: + v_input = INPUT_UNAVAILABLE.format(input=v_input) + + fields.append( + ENTRY_FIELD.format( + name=v_name, + input=v_input, + type=v_type, + default=v_default, + ) + ) + for proxy_field in v_proxy: + proxy_name = cast(str, proxy_field["name"]) + proxy_type = cast(str, proxy_field["type"]) + proxy_input = proxy_field.get("input", int) + proxy_description = proxy_field.get("description", "") + proxy_target = v_name + + if isinstance(proxy_input, type): + proxy_input = proxy_input.__name__ # convert the str type to "str" ... + + used_types.add(proxy_type) + + proxy_kwargs = "" + for k, v in proxy_field.items(): + if k not in ("name", "type", "input", "description"): + if k == "mask": + v = cast(int, v) + v = hex(v) # noqa: PLW2901 + proxy_kwargs += f"{k}={v}," + if proxy_kwargs: + proxy_kwargs = proxy_kwargs[:-1] # remove the last comma + + if proxy_description: + field_docs.append( + PROXY_DESCRIPTION.format( + name=proxy_name, + description=proxy_description, + target=proxy_target, + input=proxy_input, + ) + ) + + fields.append( + PROXY_FIELD.format( + name=proxy_name, + input=proxy_input, + target=proxy_target, + type=proxy_type, + kwargs=proxy_kwargs, + ) + ) + + # Split lines inside docstrings + + if base in main_doc_repo: + field_docs += ["", f"Inherited from :class:`{base}`:", ""] + [ + line.strip("\n\r\t").replace(" " * 4, "", 1) for line in main_doc_repo[base].split("\n") + ] + else: + print(f"Warning: {base} not found in main_doc_repo") # noqa: T201 + + if field_docs[0] == "": + field_docs = field_docs[1:] + field_docs_str = "\n ".join("\n".join(field_docs).split("\n")) + main_doc_repo[name] = field_docs_str + return ( + BASE_CLASS.format( + name=name, + base=base, + class_description=entity_description["description"], + fields_docstring=field_docs_str, + fields="\n ".join(fields), + ), + used_enums, + used_types, + ) + + +def write_files(entity_data: list[EntityData]) -> None: + """Generate the base file for the entities. + + :param entity_data: The entity data to generate the base file from. + + :return: The generated string for the base file. + """ + types: set[str] = set() + enums: set[str] = set() + all_classes: list[str] = ["EntityMetadata"] + class_code: list[str] = [] + generated: list[str] = [] + for entity in entity_data: + class_str, used_enums, used_types = generate_class(entity) + entity_name = cast(str, entity["name"]) + NAME_SUFFIX + types.update(used_types) + enums.update(used_enums) + all_classes.append(entity_name) + class_code.append(class_str) + generated.append(entity_name) + + all_classes_str = ",\n ".join(f'"{c}"' for c in sorted(all_classes + list(enums))) + types_str = ", ".join(sorted(types)) + enums_str = ", ".join(sorted(enums)) + generated_str = ", ".join(sorted(generated)) + + header = FILE_HEADER.format( + enums=enums_str, + all=all_classes_str, + ) + with Path(FILE_PATH).open("w") as file: + file.write( + BASE_FILE.format( + types=types_str, + header=header, + classes="\n\n".join(class_code), + ) + ) + + with Path(INIT_PATH).open("w") as file: + file.write(INIT_FILE.format(header=header, generated=generated_str)) + + +def format_ruff(path: Path) -> None: + """Format the generated files with ruff. + + :param path: The path to the file to format. + """ + # This will only be called from the script with a trusted predefined path + subprocess.run( # noqa: S603 + [sys.executable, "-m", "ruff", "format", str(path.absolute())], + check=True, + ) + + +if __name__ == "__main__": + write_files(ENTITY_DATA) + format_ruff(Path(FILE_PATH)) + format_ruff(Path(INIT_PATH)) diff --git a/scripts/entity_generator_data.py b/scripts/entity_generator_data.py new file mode 100644 index 00000000..d95d91a9 --- /dev/null +++ b/scripts/entity_generator_data.py @@ -0,0 +1,2878 @@ +from __future__ import annotations + +from typing import Dict, List, Union + +# Define a type for a single field in the entity data +Field = Dict[str, Union[type, str, int, bool, float, List[Dict[str, Union[type, str, int]]]]] + +# Define a type for the entire entity data dictionary +EntityData = Dict[str, Union[str, List[Field]]] + +ENTITY_DATA: list[EntityData] = [ + { # Entity + "name": "Entity", + "description": "Base for all Entity classes.", + "base": "EntityMetadata", + "fields": [ + { + "type": "Byte", + "name": "entity_flags", + "available": False, + "default": 0, + "input": int, + "proxy": [ + { + "type": "BoolMasked", + "name": "is_on_fire", + "input": bool, + "description": "Whether the entity is on fire.", + "mask": 0x01, + }, + { + "type": "BoolMasked", + "name": "is_crouching", + "input": bool, + "description": "Whether the entity is crouching.", + "mask": 0x02, + }, + { + "type": "BoolMasked", + "name": "is_riding", + "input": bool, + "description": "[UNUSED] Whether the entity is riding something.", + "mask": 0x04, + }, + { + "type": "BoolMasked", + "name": "is_sprinting", + "input": bool, + "description": "Whether the entity is sprinting.", + "mask": 0x08, + }, + { + "type": "BoolMasked", + "name": "is_swimming", + "input": bool, + "description": "Whether the entity is swimming.", + "mask": 0x10, + }, + { + "type": "BoolMasked", + "name": "is_invisible", + "input": bool, + "description": "Whether the entity is invisible.", + "mask": 0x20, + }, + { + "type": "BoolMasked", + "name": "is_glowing", + "input": bool, + "description": "Whether the entity has a glowing effect.", + "mask": 0x40, + }, + { + "type": "BoolMasked", + "name": "is_flying", + "input": bool, + "description": "Whether the entity is flying.", + "mask": 0x80, + }, + ], + "description": "Flags for the entity.", + }, + { + "type": "VarInt", + "name": "air", + "default": 300, + "input": int, + "description": "The amount of air the entity has.", + }, + { + "type": "String", + "name": "custom_name", + "default": "", + "input": str, + "description": "The custom name of the entity.", + }, + { + "type": "Boolean", + "name": "is_custom_name_visible", + "default": False, + "input": bool, + "description": "Whether the custom name is visible.", + }, + { + "type": "Boolean", + "name": "is_silent", + "default": False, + "input": bool, + "description": "Whether the entity is silent.", + }, + { + "type": "Boolean", + "name": "no_gravity", + "default": False, + "input": bool, + "description": "Whether the entity should ignore gravity.", + }, + { + "type": "Pose", + "name": "pose", + "default": "STANDING", + "input": "Pose", + "enum": True, + "description": "The pose of the entity. Can be one of the following: STANDING, FALL_FLYING,\n" + " SLEEPING, SWIMMING, SPIN_ATTACK, SNEAKING, DYING.", + }, + { + "type": "VarInt", + "name": "ticks_frozen", + "default": 0, + "input": int, + "description": "The amount of ticks the entity has been in powdered snow for.", + }, + ], + }, # End of Entity + { # Interaction + "name": "Interaction", + "description": "Entity that can be interacted with.", + "base": "Entity", + "fields": [ + { + "type": "Float", + "name": "width", + "default": 1.0, + "input": float, + "description": "The width of the entity.", + }, + { + "type": "Float", + "name": "height", + "default": 1.0, + "input": float, + "description": "The height of the entity.", + }, + { + "type": "Boolean", + "name": "responsive", + "default": False, + "input": bool, + "description": "Whether the entity can be interacted with/attached", + }, + ], + }, # End of Interaction + { # Display + "name": "Display", + "description": "Entity that are used to render something on the client.\n\n" + " https://minecraft.wiki/w/Display", + "base": "Entity", + "fields": [ + { + "type": "VarInt", + "name": "interpolation_delay", + "default": 0, + "input": int, + "description": "Delay before starting interpolation.\n If 0, interpolation starts immediately." + "(doesn't exist in newest snapshot)", + }, + { + "type": "VarInt", + "name": "interpolation_translation_duration", + "default": 0, + "input": int, + "description": "Transformation interpolation duration.", + }, + { + "type": "VarInt", + "name": "interpolation_rotation_duration", + "default": 0, + "input": int, + "description": "Rotation interpolation duration.", + }, + { + "type": "Vector3", + "name": "translation", + "default": "Vec3(0.0, 0.0, 0.0)", + "input": "Vec3", + "description": "Translation vector", + }, + { + "type": "Vector3", + "name": "scale", + "default": "Vec3(1.0, 1.0, 1.0)", + "input": "Vec3", + "description": "Scaling vector", + }, + { + "type": "Quaternion", + "name": "rotation_left", + "default": "Quaternion(0.0, 0.0, 0.0, 1.0)", + "input": "Quaternion", + "description": "See :attr:`rotation_right`", + }, + { + "type": "Quaternion", + "name": "rotation_right", + "default": "Quaternion(0.0, 0.0, 0.0, 1.0)", + "input": "Quaternion", + "description": "Initial rotation. This tag corresponds to the right-singular vector matrix after the\n" + " matrix singular value decomposition. ", + }, + { + "type": "Byte", + "name": "billboard_constraint", + "default": 0, + "input": int, + "description": "Billboard Constraints (0 = FIXED, 1 = VERTICAL, 2 = HORIZONTAL, 3 = CENTER)\n" + " Controls if this entity should pivot to face player when rendered.", + }, + { # Might need a proxy later for the components + "type": "VarInt", + "name": "brightness_override", + "default": -1, + "input": int, + "description": "Brightness override (blockLight << 4 | skyLight << 20). By default the brightness\n" + " value is calculated from the light level of the block the entity is in.", + }, + { + "type": "Float", + "name": "view_range", + "default": 1.0, + "input": float, + "description": "View range", + }, + { + "type": "Float", + "name": "shadow_radius", + "default": 0.0, + "input": float, + "description": "Shadow radius. Value is treated as 64 when higher than 64.\n" + " If less than or equal to 0, the entity has no shadow. Interpolated", + }, + { + "type": "Float", + "name": "shadow_strength", + "default": 0.0, + "input": float, + "description": "Shadow strength. Interpolated", + }, + { + "type": "Float", + "name": "width", + "default": 0.0, + "input": float, + "description": "The maximum width of the entity. Rendering culling bounding box spans horizontally\n" + " `width/2` from entity position, and the part beyond will be culled. If set to 0, no culling on\n" + " both vertical and horizontal directions.", + }, + { + "type": "Float", + "name": "height", + "default": 0.0, + "input": float, + "description": "The maximum height of the entity. Rendering culling bounding box spans vertically\n" + " `y` to `y+height`, and the part beyond will be culled. If set to 0, no culling on both\n" + " vertical and horizontal directions.", + }, + { + "type": "VarInt", + "name": "glow_color_override", + "default": 0, + "input": int, + "description": "Overrides the glow border color. If 0, uses the color of the team that the display\n" + " entity is in.", + }, + ], + }, # End of Display + { # Block Display + "name": "BlockDisplay", + "description": "Entity that are used to render a block on the client as a Display entity.\n\n" + " https://minecraft.wiki/w/Display#Block_Displays", + "base": "Display", + "fields": [ + { + "type": "BlockState", + "name": "block", + "default": 0, # minecraft:air + "input": int, + "description": "The block state to display. Default is air.", + }, + ], + }, # End of Block Display + { # Item Display + "name": "ItemDisplay", + "description": "Entity that are used to render an item on the client as a Display entity.\n\n" + " https://minecraft.wiki/w/Display#Item_Displays", + "base": "Display", + "fields": [ + { + "type": "Slot", + "name": "item", + "default": "Slot(None)", # empty + "input": "Slot", + "description": "The item to display. Default is an empty slot.", + }, + { + "type": "Byte", + "name": "display_type", + "default": 0, + "input": int, + "description": "Display type: (NONE, THIRD_PERSON_LEFT_HAND, THIRD_PERSON_RIGHT_HAND,\n" + " FIRST_PERSON_LEFT_HAND, FIRST_PERSON_RIGHT_HAND, HEAD, GUI, GROUND, FIXED).", + }, + ], + }, # End of Item Display + { # Text Display + "name": "TextDisplay", + "description": "Entity that are used to render text on the client as a Display entity.\n\n" + " https://minecraft.wiki/w/Display#Text_Displays", + "base": "Display", + "fields": [ + { + "type": "TextComponent", + "name": "text", + "default": 'TextComponent("")', # empty + "input": "TextComponent", + "description": "The text to display. Default is an empty text component.", + }, + { + "type": "VarInt", + "name": "line_width", + "default": 200, + "input": int, + "description": ": Maximum line width used to split lines (note: new line can also\n" + " be added with \\\\n characters).", + }, + { + "type": "VarInt", + "name": "background_color", + "default": 1073741824, + "input": int, + "description": "Background color of the text. Default is 0x40000000.", + }, + { + "name": "display_flags", + "type": "Byte", + "default": 0, + "input": int, + "available": False, + "proxy": [ + { + "type": "BoolMasked", + "name": "has_shadow", + "input": bool, + "description": "Whether the text is displayed with shadow.", + "mask": 0x01, + }, + { + "type": "BoolMasked", + "name": "is_see_through", + "input": bool, + "description": "Whether the text is displayed as see-through.", + "mask": 0x02, + }, + { + "type": "BoolMasked", + "name": "use_default_background", + "input": bool, + "description": "Whether to use the default background color for the text\n display.", + "mask": 0x04, + }, + { + "type": "BoolMasked", + "name": "align_left", + "input": bool, + "description": "Whether the text is aligned to the left.\n" + " Has priority over right (see also :attr:`align_right`)", + "mask": 0x08, + }, + { + "type": "BoolMasked", + "name": "align_right", + "input": bool, + "description": "Whether the text is aligned to the right.\n" + " Set both to false for center alignment.", + "mask": 0x10, + }, + ], + "description": "Flags for the text display.", + }, + ], + }, + { # Thrown Item Projectile + "name": "ThrownItemProjectile", + "description": "Entity that represents a thrown item projectile.", + "base": "Entity", + "fields": [ + { + "type": "Slot", + "name": "item", + "default": "Slot(None)", # empty + "input": "Slot", + "description": "The item that the projectile represents", + } + ], + }, + { # Thrown Egg + "name": "ThrownEgg", + "description": "Entity that represents a thrown egg projectile.", + "base": "ThrownItemProjectile", + "fields": [ + { + "type": "Slot", + "name": "item", + # Registries not implemented yet + "default": "Slot(SlotData(NotImplemented, 1))", + "input": "Slot", + } + ], + }, + { # Thrown Ender Pearl + "name": "ThrownEnderPearl", + "description": "Entity that represents a thrown ender pearl projectile.", + "base": "ThrownItemProjectile", + "fields": [ + { + "type": "Slot", + "name": "item", + "default": "Slot(SlotData(NotImplemented, 1))", # same + "input": "Slot", + } + ], + }, + { # Thrown Experience Bottle + "name": "ThrownExperienceBottle", + "description": "Entity that represents a thrown experience bottle projectile.", + "base": "ThrownItemProjectile", + "fields": [ + { + "type": "Slot", + "name": "item", + "default": "Slot(SlotData(NotImplemented, 1))", # same + "input": "Slot", + } + ], + }, + { # Thrown Potion + "name": "ThrownPotion", + "description": "Entity that represents a thrown potion projectile.", + "base": "ThrownItemProjectile", + "fields": [ + { + "type": "Slot", + "name": "item", + "default": "Slot(SlotData(NotImplemented, 1))", # same + "input": "Slot", + } + ], + }, + { # Thrown Snowball + "name": "ThrownSnowball", + "description": "Entity that represents a thrown snowball projectile.", + "base": "ThrownItemProjectile", + "fields": [ + { + "type": "Slot", + "name": "item", + "default": "Slot(SlotData(NotImplemented, 1))", # same + "input": "Slot", + } + ], + }, + { # Eye of Ender + "name": "EyeOfEnder", + "description": "Entity that represents an eye of ender.", + "base": "Entity", + "fields": [ + { + "type": "Slot", + "name": "item", + "default": "Slot(None)", # behaves like a minecraft:ender_eye + "input": "Slot", + "description": "The item that the entity represents (usually an ender eye)", + } + ], + }, + { # Falling Block + "name": "FallingBlock", + "description": "Entity that represents a falling block.", + "base": "Entity", + "fields": [ + { + "type": "Position", + "name": "position", + "default": "Position(0, 0, 0)", + "input": "Position", + "description": "The spawn position of the falling block", + }, + ], + }, + { + "name": "AreaEffectCloud", + "description": "Entity that represents an area effect cloud.", + "base": "Entity", + "fields": [ + { + "type": "Float", + "name": "radius", + "default": 0.5, + "input": float, + "description": "The radius of the area effect cloud.", + }, + { + "type": "VarInt", + "name": "color", + "default": 0, + "input": int, + "description": "Color of the cloud's particle effect. Only applicable for mob spell particles.", + }, + { + "type": "Boolean", + "name": "single_point_effect", + "default": False, + "input": bool, + "description": "Whether to ignore the radius and show the effect as a single point, not an area.", + }, + { + "type": "Particle", + "name": "effect", + "default": "ParticleData(15)", # minecraft:effect + "input": "ParticleData", + "description": "The particle effect of the area effect cloud (default: `minecraft:effect`).", + }, + ], + }, + { # Fishing Hook + "name": "FishingHook", + "description": "Entity that represents a fishing hook.", + "base": "Entity", + "fields": [ + { + "type": "VarInt", + "name": "hooked_entity_id", + "default": 0, + "input": int, + "description": "The ID of the hooked entity plus one, or 0 if there is no hooked entity.", + }, + { + "type": "Boolean", + "name": "is_catchable", + "default": False, + "input": bool, + "description": "Whether the fishing hook is catchable.", + }, + ], + }, + { # Abstract Arrow + "name": "AbstractArrow", + "description": "Entity that represents an abstract arrow.", + "base": "Entity", + "fields": [ + { + "type": "Byte", + "name": "arrow_flags", + "default": 0, + "input": int, + "available": False, + "proxy": [ + { + "type": "BoolMasked", + "name": "is_critical", + "input": bool, + "description": "Whether the arrow is critical.", + "mask": 0x01, + }, + { + "type": "BoolMasked", + "name": "is_noclip", + "input": bool, + "description": "Whether the arrow is noclip (used by loyalty tridents when\n returning).", + "mask": 0x02, + }, + ], + "description": "Flags for the arrow.", + }, + { + "type": "Byte", + "name": "piercing_level", + "default": 0, + "input": int, + "description": "The piercing level of the arrow.", + }, + ], + }, + { # Arrow + "name": "Arrow", + "description": "Entity that represents an arrow.", + "base": "AbstractArrow", + "fields": [ + { + "type": "VarInt", + "name": "color", + "default": -1, + "input": int, + "description": "Color of the arrow's particles. Set to -1 for no particles.", + } + ], + }, + { # Spectral Arrow + "name": "SpectralArrow", + "description": "Entity that represents a spectral arrow.", + "base": "AbstractArrow", + "fields": [], + }, + { # Thrown Trident + "name": "ThrownTrident", + "description": "Entity that represents a thrown trident.", + "base": "AbstractArrow", + "fields": [ + { + "type": "VarInt", + "name": "loyalty_level", + "default": 0, + "input": int, + "description": "The loyalty level of the thrown trident (enchantment).", + }, + { + "type": "Boolean", + "name": "has_enchantment_glint", + "default": False, + "input": bool, + "description": "Whether the thrown trident has an enchantment glint.", + }, + ], + }, + { + "name": "AbstractVehicle", + "description": "Entity that represents an abstract vehicle.", + "base": "Entity", + "fields": [ + { + "type": "VarInt", + "name": "shaking_power", + "default": 0, + "input": int, + "description": "The shaking power of the vehicle.", + }, + { + "type": "VarInt", + "name": "shaking_direction", + "default": 1, + "input": int, + "description": "The shaking direction of the vehicle.", + }, + { + "type": "Float", + "name": "shaking_multiplier", + "default": 0.0, + "input": float, + "description": "The shaking multiplier of the vehicle.", + }, + ], + }, + { + "name": "Boat", + "description": "Entity that represents a boat.", + "base": "AbstractVehicle", + "fields": [ + { + "type": "VarInt", + "name": "boat_type", + "default": 0, + "input": int, + "description": "The type of the boat. (0 = oak, 1 = spruce, 2 = birch, 3 = jungle,\n" + " 4 = acacia, 5 = dark oak)", + }, + { + "type": "Boolean", + "name": "is_left_paddle_turning", + "default": False, + "input": bool, + "description": "Whether the left paddle of the boat is turning.", + }, + { + "type": "Boolean", + "name": "is_right_paddle_turning", + "default": False, + "input": bool, + "description": "Whether the right paddle of the boat is turning.", + }, + { + "type": "VarInt", + "name": "splash_timer", + "default": 0, + "input": int, + "description": "The splash timer of the boat.", + }, + ], + }, + { + "name": "ChestBoat", + "description": "Entity that represents a chest boat.", + "base": "Boat", + "fields": [], + }, + { + "name": "AbstractMinecart", + "description": "Entity that represents an abstract minecart.", + "base": "AbstractVehicle", + "fields": [ + { + "type": "VarInt", + "name": "custom_block_id_and_damage", + "default": 0, + "input": int, + "description": "The custom block ID and damage of the minecart.", + }, + { + "type": "VarInt", + "name": "custom_block_y_position", + "default": 6, + "input": int, + "description": "The custom block Y position (in 16ths of a block) of the minecart.", + }, + { + "type": "Boolean", + "name": "show_custom_block", + "default": False, + "input": bool, + "description": "Whether to show the custom block of the minecart.", + }, + ], + }, + { + "name": "Minecart", + "description": "Entity that represents a minecart.", + "base": "AbstractMinecart", + "fields": [], + }, + { + "name": "AbstractMinecartContainer", + "description": "Entity that represents an abstract minecart container.", + "base": "AbstractMinecart", + "fields": [], + }, + { + "name": "MinecartHopper", + "description": "Entity that represents a minecart hopper.", + "base": "AbstractMinecartContainer", + "fields": [], + }, + { + "name": "MinecartChest", + "description": "Entity that represents a minecart chest.", + "base": "AbstractMinecartContainer", + "fields": [], + }, + { + "name": "MinecartFurnace", + "description": "Entity that represents a minecart furnace.", + "base": "AbstractMinecart", + "fields": [ + { + "type": "Boolean", + "name": "has_fuel", + "default": False, + "input": bool, + "description": "Whether the furnace minecart has fuel.", + } + ], + }, + { + "name": "MinecartTNT", + "description": "Entity that represents a minecart TNT.", + "base": "AbstractMinecart", + "fields": [], + }, + { + "name": "MinecartSpawner", + "description": "Entity that represents a minecart spawner.", + "base": "AbstractMinecart", + "fields": [], + }, + { + "name": "MinecartCommandBlock", + "description": "Entity that represents a minecart command block.", + "base": "AbstractMinecart", + "fields": [ + { + "type": "String", + "name": "command", + "default": "", + "input": str, + "description": "The command stored in the command block.", + }, + { + "type": "TextComponent", + "name": "last_output", + "default": 'TextComponent("")', + "input": "TextComponent", + "description": "The last output from the command block.", + }, + ], + }, + { + "name": "EndCrystal", + "description": "Entity that represents an end crystal.", + "base": "Entity", + "fields": [ + { + "type": "OptPosition", + "name": "beam_target", + "default": "None", + "input": "Position | None", + "description": "The position of the beam target.", + }, + { + "type": "Boolean", + "name": "show_bottom", + "default": True, + "input": bool, + "description": "Whether the bottom of the end crystal is shown.", + }, + ], + }, + { + "name": "DragonFireball", + "description": "Entity that represents a dragon fireball.", + "base": "Entity", + "fields": [], + }, + { + "name": "SmallFireball", + "description": "Entity that represents a small fireball.", + "base": "Entity", + "fields": [ + { + "type": "Slot", + "name": "item", + "default": "Slot(None)", + "input": "Slot", + "description": "The item representing the small fireball.", + } + ], + }, + { + "name": "Fireball", + "description": "Entity that represents a fireball.", + "base": "Entity", + "fields": [ + { + "type": "Slot", + "name": "item", + "default": "Slot(None)", + "input": "Slot", + "description": "The item representing the fireball.", + } + ], + }, + { + "name": "WitherSkull", + "description": "Entity that represents a wither skull.", + "base": "Entity", + "fields": [ + { + "type": "Boolean", + "name": "is_invulnerable", + "default": False, + "input": bool, + "description": "Whether the wither skull is invulnerable.", + } + ], + }, + { + "name": "FireworkRocket", + "description": "Entity representing a firework rocket.", + "base": "Entity", + "fields": [ + { + "type": "Slot", + "name": "firework_info", + "default": "Slot(None)", + "input": "Slot", + "description": "The information about the firework.", + }, + { + "type": "OptVarInt", + "name": "shooter_entity_id", + "default": "None", + "input": "int|None", + "description": "The entity ID of the entity that used the firework (for elytra boosting).", + }, + { + "type": "Boolean", + "name": "shot_at_angle", + "default": False, + "input": bool, + "description": "Whether the firework rocket was shot at an angle (from a crossbow).", + }, + ], + }, + { + "name": "ItemFrame", + "description": "Entity representing an item frame.", + "base": "Entity", + "fields": [ + { + "type": "Slot", + "name": "item", + "default": "Slot(None)", + "input": "Slot", + "description": "The item in the item frame.", + }, + { + "type": "VarInt", + "name": "rotation", + "default": 0, + "input": int, + "description": "The rotation of the item frame.", + }, + ], + }, + { + "name": "GlowingItemFrame", + "description": "Entity representing a glowing item frame.", + "base": "ItemFrame", + "fields": [], + }, + { + "name": "Painting", + "description": "Entity representing a painting.", + "base": "Entity", + "fields": [ + { + "type": "PaintingVariant", + "name": "painting_type", + "default": 0, + "input": "int", + "description": "The type of painting variant.", + } + ], + }, + { + "name": "ItemEntity", + "description": "Entity representing an item.", + "base": "Entity", + "fields": [ + { + "type": "Slot", + "name": "item", + "default": "Slot(None)", + "input": "Slot", + "description": "The item in the item entity.", + } + ], + }, + { + "name": "LivingEntity", + "description": "Entity that represents a living entity.", + "base": "Entity", + "fields": [ + { + "type": "Byte", + "name": "hand_states", + "default": 0, + "input": int, + "available": False, + "proxy": [ + { + "type": "BoolMasked", + "name": "is_hand_active", + "input": bool, + "description": "Whether the hand is active.", + "mask": 0x01, + }, + { + "type": "BoolMasked", + "name": "active_hand", + "input": int, + "description": "Which hand is active (0 = main hand, 1 = offhand).", + "mask": 0x02, + }, + { + "type": "BoolMasked", + "name": "is_riptide_spin_attack", + "input": bool, + "description": "Whether the entity is in riptide spin attack.", + "mask": 0x04, + }, + ], + "description": "Bit mask indicating hand states.", + }, + { + "type": "Float", + "name": "health", + "default": 1.0, + "input": float, + "description": "The health of the living entity.", + }, + { + "type": "VarInt", + "name": "potion_effect_color", + "default": 0, + "input": int, + "description": "Color of the potion effect (or 0 if there is no effect).", + }, + { + "type": "Boolean", + "name": "is_potion_effect_ambient", + "default": False, + "input": bool, + "description": "Whether the potion effect is ambient: reduces the number of particles generated by\n" + " potions to 1/5 the normal amount.", + }, + { + "type": "VarInt", + "name": "num_arrows", + "default": 0, + "input": int, + "description": "Number of arrows in the entity.", + }, + { + "type": "VarInt", + "name": "num_bee_stingers", + "default": 0, + "input": int, + "description": "Number of bee stingers in the entity.", + }, + { + "type": "OptPosition", + "name": "sleeping_bed_location", + "default": "None", + "input": "Position|None", + "description": "Location of the bed that the entity is currently sleeping\n" + " in (Empty if it isn't sleeping).", + }, + ], + }, + { + "name": "Player", + "description": "Player entity.", + "base": "LivingEntity", + "fields": [ + { + "type": "Float", + "name": "additional_hearts", + "default": 0.0, + "input": float, + "description": "Additional hearts of the player.", + }, + { + "type": "VarInt", + "name": "score", + "default": 0, + "input": int, + "description": "The score of the player.", + }, + { + "type": "Byte", + "name": "displayed_skin_parts", + "default": 0, + "input": int, + "available": False, + "proxy": [ + { + "type": "BoolMasked", + "name": "cape_enabled", + "input": bool, + "description": "Whether the cape is enabled.", + "mask": 0x01, + }, + { + "type": "BoolMasked", + "name": "jacket_enabled", + "input": bool, + "description": "Whether the jacket is enabled.", + "mask": 0x02, + }, + { + "type": "BoolMasked", + "name": "left_sleeve_enabled", + "input": bool, + "description": "Whether the left sleeve is enabled.", + "mask": 0x04, + }, + { + "type": "BoolMasked", + "name": "right_sleeve_enabled", + "input": bool, + "description": "Whether the right sleeve is enabled.", + "mask": 0x08, + }, + { + "type": "BoolMasked", + "name": "left_pants_leg_enabled", + "input": bool, + "description": "Whether the left pants leg is enabled.", + "mask": 0x10, + }, + { + "type": "BoolMasked", + "name": "right_pants_leg_enabled", + "input": bool, + "description": "Whether the right pants leg is enabled.\n" " ", + "mask": 0x20, + }, + { + "type": "BoolMasked", + "name": "hat_enabled", + "input": bool, + "description": "Whether the hat is enabled.", + "mask": 0x40, + }, + ], + "description": "Bit mask indicating displayed skin parts.", + }, + { + "type": "Byte", + "name": "main_hand", + "default": 1, + "input": int, + "description": "The main hand of the player (0: Left, 1: Right).", + }, + { + "type": "NBTag", + "name": "left_shoulder_entity_data", + "default": "EndNBT()", + "input": "NBTag", + "description": "Left shoulder entity data (for occupying parrot).", + }, + { + "type": "NBTag", + "name": "right_shoulder_entity_data", + "default": "EndNBT()", + "input": "NBTag", + "description": "Right shoulder entity data (for occupying parrot).", + }, + ], + }, + { + "name": "ArmorStand", + "description": "Entity representing an armor stand.", + "base": "LivingEntity", + "fields": [ + { + "type": "Byte", + "name": "armorstand_flags", + "default": 0, + "input": int, + "available": False, + "proxy": [ + { + "type": "BoolMasked", + "name": "is_small", + "input": bool, + "description": "Whether the armor stand is small.", + "mask": 0x01, + }, + { + "type": "BoolMasked", + "name": "has_arms", + "input": bool, + "description": "Whether the armor stand has arms.", + "mask": 0x04, + }, + { + "type": "BoolMasked", + "name": "has_no_base_plate", + "input": bool, + "description": "Whether the armor stand has no base plate.", + "mask": 0x08, + }, + { + "type": "BoolMasked", + "name": "is_marker", + "input": bool, + "description": "Whether the armor stand is a marker.", + "mask": 0x10, + }, + ], + "description": "Bit mask indicating various properties of the armor stand.", + }, + { + "type": "Rotation", + "name": "head_rotation", + "default": "Vec3(0.0, 0.0, 0.0)", + "input": "Vec3", + "description": "Rotation of the armor stand's head.", + }, + { + "type": "Rotation", + "name": "body_rotation", + "default": "Vec3(0.0, 0.0, 0.0)", + "input": "Vec3", + "description": "Rotation of the armor stand's body.", + }, + { + "type": "Rotation", + "name": "left_arm_rotation", + "default": "Vec3(-10.0, 0.0, -10.0)", + "input": "Vec3", + "description": "Rotation of the armor stand's left arm.", + }, + { + "type": "Rotation", + "name": "right_arm_rotation", + "default": "Vec3(-15.0, 0.0, 10.0)", + "input": "Vec3", + "description": "Rotation of the armor stand's right arm.", + }, + { + "type": "Rotation", + "name": "left_leg_rotation", + "default": "Vec3(-1.0, 0.0, -1.0)", + "input": "Vec3", + "description": "Rotation of the armor stand's left leg.", + }, + { + "type": "Rotation", + "name": "right_leg_rotation", + "default": "Vec3(1.0, 0.0, 1.0)", + "input": "Vec3", + "description": "Rotation of the armor stand's right leg.", + }, + ], + }, + { + "name": "Mob", + "description": "Generic mobile entity.", + "base": "LivingEntity", + "fields": [ + { + "type": "Byte", + "name": "mob_flags", + "default": 0, + "input": int, + "available": False, + "proxy": [ + { + "type": "BoolMasked", + "name": "no_ai", + "input": bool, + "description": "Whether the mob has AI.", + "mask": 0x01, + }, + { + "type": "BoolMasked", + "name": "is_left_handed", + "input": bool, + "description": "Whether the mob is left-handed.", + "mask": 0x02, + }, + { + "type": "BoolMasked", + "name": "is_aggressive", + "input": bool, + "description": "Whether the mob is aggressive.", + "mask": 0x04, + }, + ], + "description": "Bit mask indicating various properties of the mob.", + } + ], + }, + { + "name": "AmbientCreature", + "description": "Entity that represents an ambient creature.", + "base": "Mob", + "fields": [], + }, + { + "name": "Bat", + "description": "Entity that represents a bat.", + "base": "AmbientCreature", + "fields": [ + { + "type": "Byte", + "name": "bat_flags", + "default": 0, + "input": int, + "available": False, + "proxy": [ + { + "type": "BoolMasked", + "name": "is_hanging", + "input": bool, + "description": "Whether the bat is hanging upside down.", + "mask": 0x01, + } + ], + "description": "Flags of the bat.", + } + ], + }, + { + "name": "PathfinderMob", + "description": "Entity that represents a pathfinder mob.", + "base": "Mob", + "fields": [], + }, + { + "name": "WaterAnimal", + "description": "Entity that represents a water-dwelling animal.", + "base": "PathfinderMob", + "fields": [], + }, + { + "name": "Squid", + "description": "Entity that represents a squid.", + "base": "WaterAnimal", + "fields": [], + }, + { + "name": "Dolphin", + "description": "Entity that represents a dolphin.", + "base": "WaterAnimal", + "fields": [ + { + "type": "Position", + "name": "treasure_position", + "default": "Position(0, 0, 0)", + "input": "Position", + "description": "The position of the dolphin's treasure.", + }, + { + "type": "Boolean", + "name": "has_fish", + "default": False, + "input": bool, + "description": "Whether the dolphin has fish.", + }, + { + "type": "VarInt", + "name": "moisture_level", + "default": 2400, + "input": int, + "description": "The moisture level of the dolphin.", + }, + ], + }, + { + "name": "AbstractFish", + "description": "Entity that represents an abstract fish.", + "base": "WaterAnimal", + "fields": [ + { + "type": "Boolean", + "name": "from_bucket", + "default": False, + "input": bool, + "description": "Whether the fish is from a bucket.", + } + ], + }, + { + "name": "Cod", + "description": "Entity that represents a cod fish.", + "base": "AbstractFish", + "fields": [], + }, + { + "name": "PufferFish", + "description": "Entity that represents a puffer fish.", + "base": "AbstractFish", + "fields": [ + { + "type": "VarInt", + "name": "puff_state", + "default": 0, + "input": int, + "description": "The state of puffing of the puffer fish, varies from 0 to 2.", + } + ], + }, + {"name": "Salmon", "description": "Entity that represents a salmon fish.", "base": "AbstractFish", "fields": []}, + { + "name": "TropicalFish", + "description": "Entity that represents a tropical fish.", + "base": "AbstractFish", + "fields": [ + { + "type": "VarInt", + "name": "variant", + "default": 0, + "input": int, + "description": "The variant of the tropical fish.", + } + ], + }, + {"name": "Tadpole", "description": "Entity that represents a tadpole.", "base": "AbstractFish", "fields": []}, + { + "name": "AgeableMob", + "description": "Entity that represents an ageable mob.", + "base": "PathfinderMob", + "fields": [ + { + "type": "Boolean", + "name": "is_baby", + "default": False, + "input": bool, + "description": "Whether the mob is a baby.", + } + ], + }, + { + "name": "Animal", + "description": "Entity that represents an animal.", + "base": "AgeableMob", + "fields": [], + }, + { + "name": "Sniffer", + "description": "Entity that represents a sniffer.", + "base": "Animal", + "fields": [ + { + "type": "SnifferState", + "name": "sniffer_state", + "default": "IDLING", + "input": "SnifferState", + "enum": True, + "description": "The state of the sniffer.", + }, + { + "type": "VarInt", + "name": "drop_seed_at_tick", + "default": 0, + "input": int, + "description": "The tick at which the sniffer will drop seed.", + }, + ], + }, + { + "name": "AbstractHorse", + "description": "Entity that represents an abstract horse.", + "base": "Animal", + "fields": [ + { + "type": "Byte", + "name": "horse_flags", + "default": 0, + "input": int, + "available": False, + "proxy": [ + { + "type": "BoolMasked", + "name": "is_tame", + "input": bool, + "description": "Whether the horse is tame.", + "mask": 0x02, + }, + { + "type": "BoolMasked", + "name": "is_saddled", + "input": bool, + "description": "Whether the horse is saddled.", + "mask": 0x04, + }, + { + "type": "BoolMasked", + "name": "has_bred", + "input": bool, + "description": "Whether the horse has bred.", + "mask": 0x08, + }, + { + "type": "BoolMasked", + "name": "is_eating", + "input": bool, + "description": "Whether the horse is eating.", + "mask": 0x10, + }, + { + "type": "BoolMasked", + "name": "is_rearing", + "input": bool, + "description": "Whether the horse is rearing (on hind legs).", + "mask": 0x20, + }, + { + "type": "BoolMasked", + "name": "is_mouth_open", + "input": bool, + "description": "Whether the horse's mouth is open.", + "mask": 0x40, + }, + ], + "description": "Flags for the horse.", + } + ], + }, + { + "name": "Horse", + "description": "Entity that represents a horse.", + "base": "AbstractHorse", + "fields": [ + { + "type": "VarInt", + "name": "variant", + "default": 0, + "input": int, + "description": "The variant of the horse representing its color and style.", + } + ], + }, + { + "name": "ZombieHorse", + "description": "Entity that represents a zombie horse.", + "base": "AbstractHorse", + "fields": [], + }, + { + "name": "SkeletonHorse", + "description": "Entity that represents a skeleton horse.", + "base": "AbstractHorse", + "fields": [], + }, + { + "name": "Camel", + "description": "Entity that represents a camel.", + "base": "AbstractHorse", + "fields": [ + { + "type": "Boolean", + "name": "is_dashing", + "default": False, + "input": bool, + "description": "Whether the camel is dashing.", + }, + { + "type": "VarLong", + "name": "last_pose_change_tick", + "default": 0, + "input": int, + "description": "The tick at which the camel's pose was last changed.", + }, + ], + }, + { + "name": "ChestedHorse", + "description": "Entity that represents a horse with a chest.", + "base": "AbstractHorse", + "fields": [ + { + "type": "Boolean", + "name": "has_chest", + "default": False, + "input": bool, + "description": "Whether the horse has a chest.", + } + ], + }, + { + "name": "Donkey", + "description": "Entity that represents a donkey.", + "base": "ChestedHorse", + "fields": [], + }, + { + "name": "Llama", + "description": "Entity that represents a llama.", + "base": "ChestedHorse", + "fields": [ + { + "type": "VarInt", + "name": "strength", + "default": 0, + "input": int, + "description": "The strength of the llama, representing the number of columns of 3 slots in its\n" + " inventory once a chest is equipped.", + }, + { + "type": "VarInt", + "name": "carpet_color", + "default": -1, + "input": int, + "description": "The color of the carpet equipped on the llama, represented as a dye color. -1 if no\n" + " carpet is equipped.", + }, + { + "type": "VarInt", + "name": "variant", + "default": 0, + "input": int, + "description": "The variant of the llama.", + }, + ], + }, + {"name": "TraderLlama", "description": "Entity that represents a trader llama.", "base": "Llama", "fields": []}, + {"name": "Mule", "description": "Entity that represents a mule.", "base": "ChestedHorse", "fields": []}, + { + "name": "Axolotl", + "description": "Entity that represents an axolotl.", + "base": "Animal", + "fields": [ + { + "type": "VarInt", + "name": "variant", + "default": 0, + "input": int, + "description": "The variant of the axolotl.", + }, + { + "type": "Boolean", + "name": "is_playing_dead", + "default": False, + "input": bool, + "description": "Whether the axolotl is currently playing dead.", + }, + { + "type": "Boolean", + "name": "is_spawned_from_bucket", + "default": False, + "input": bool, + "description": "Whether the axolotl was spawned from a bucket.", + }, + ], + }, + { + "name": "Bee", + "description": "Entity that represents a bee.", + "base": "Animal", + "fields": [ + { + "type": "Byte", + "name": "bee_flags", + "default": 0, + "input": int, + "available": False, + "description": "Flags representing various properties of the bee.", + "proxy": [ + { + "type": "BoolMasked", + "name": "is_angry", + "input": bool, + "description": "Whether the bee is angry.", + "mask": 0x02, + }, + { + "type": "BoolMasked", + "name": "has_stung", + "input": bool, + "description": "Whether the bee has stung.", + "mask": 0x04, + }, + { + "type": "BoolMasked", + "name": "has_nectar", + "input": bool, + "description": "Whether the bee has nectar.", + "mask": 0x08, + }, + ], + }, + { + "type": "VarInt", + "name": "anger_time", + "default": 0, + "input": int, + "description": "The time in ticks for which the bee remains angry.", + }, + ], + }, + { + "name": "Fox", + "description": "Entity that represents a fox.", + "base": "Animal", + "fields": [ + { + "type": "VarInt", + "name": "fox_type", + "default": 0, + "input": int, + "description": "The type of the fox.", + }, + { + "type": "Byte", + "name": "fox_flags", + "default": 0, + "input": int, + "available": False, + "description": "Bit mask representing various states of the fox.", + "proxy": [ + { + "type": "BoolMasked", + "name": "is_sitting", + "input": bool, + "description": "Whether the fox is sitting.", + "mask": 0x01, + }, + { + "type": "BoolMasked", + "name": "is_fox_crouching", + "input": bool, + "description": "Whether the fox is crouching.", + "mask": 0x04, + }, + { + "type": "BoolMasked", + "name": "is_interested", + "input": bool, + "description": "Whether the fox is interested.", + "mask": 0x08, + }, + { + "type": "BoolMasked", + "name": "is_pouncing", + "input": bool, + "description": "Whether the fox is pouncing.", + "mask": 0x10, + }, + { + "type": "BoolMasked", + "name": "is_sleeping", + "input": bool, + "description": "Whether the fox is sleeping.", + "mask": 0x20, + }, + { + "type": "BoolMasked", + "name": "is_faceplanted", + "input": bool, + "description": "Whether the fox is faceplanted.", + "mask": 0x40, + }, + { + "type": "BoolMasked", + "name": "is_defending", + "input": bool, + "description": "Whether the fox is defending.", + "mask": 0x80, + }, + ], + }, + { + "type": "OptUUID", + "name": "trusted_uuid", + "default": "None", + "input": "UUID|None", + "description": "The UUID of the player that the fox trusts.", + }, + { + "type": "OptUUID", + "name": "trusted_uuid_2", + "default": "None", + "input": "UUID|None", + "description": "Another player that the fox trusts.", + }, + ], + }, + { + "name": "Frog", + "description": "Entity that represents a frog.", + "base": "Animal", + "fields": [ + { + "type": "FrogVariant", + "name": "variant", + "default": 0, # No registry yet + "input": "int", + "description": "The variant of the frog.", + }, + { + "type": "OptVarInt", + "name": "tongue_target", + "default": 0, + "input": "int | None", + "description": "The target of the frog's tongue.", + }, + ], + }, + { + "name": "Ocelot", + "description": "Entity that represents an ocelot.", + "base": "Animal", + "fields": [ + { + "type": "Boolean", + "name": "is_trusting", + "default": False, + "input": bool, + "description": "Whether the ocelot is trusting.", + } + ], + }, + { + "name": "Panda", + "description": "Entity that represents a panda.", + "base": "Animal", + "fields": [ + { + "type": "VarInt", + "name": "breed_timer", + "default": 0, + "input": int, + "description": "The breed timer of the panda.", + }, + { + "type": "VarInt", + "name": "sneeze_timer", + "default": 0, + "input": int, + "description": "The sneeze timer of the panda.", + }, + { + "type": "VarInt", + "name": "eat_timer", + "default": 0, + "input": int, + "description": "The eat timer of the panda.", + }, + { + "type": "Byte", + "name": "main_gene", + "default": 0, + "input": int, + "description": "The main gene of the panda.", + }, + { + "type": "Byte", + "name": "hidden_gene", + "default": 0, + "input": int, + "description": "The hidden gene of the panda.", + }, + { + "type": "Byte", + "name": "panda_flags", + "default": 0, + "input": int, + "available": False, + "description": "Bit mask representing various states of the panda.", + "proxy": [ + { + "type": "BoolMasked", + "name": "is_sneezing", + "input": bool, + "description": "Whether the panda is sneezing.", + "mask": 0x02, + }, + { + "type": "BoolMasked", + "name": "is_rolling", + "input": bool, + "description": "Whether the panda is rolling.", + "mask": 0x04, + }, + { + "type": "BoolMasked", + "name": "is_sitting", + "input": bool, + "description": "Whether the panda is sitting.", + "mask": 0x08, + }, + { + "type": "BoolMasked", + "name": "is_on_back", + "input": bool, + "description": "Whether the panda is on its back.", + "mask": 0x10, + }, + ], + }, + ], + }, + { + "name": "Pig", + "description": "Entity that represents a pig.", + "base": "Animal", + "fields": [ + { + "type": "Boolean", + "name": "has_saddle", + "default": False, + "input": bool, + "description": "Whether the pig has a saddle.", + }, + { + "type": "VarInt", + "name": "boost_time", + "default": 0, + "input": int, + "description": "Total time to 'boost' with a carrot on a stick for.", + }, + ], + }, + { + "name": "Rabbit", + "description": "Entity that represents a rabbit.", + "base": "Animal", + "fields": [ + { + "type": "VarInt", + "name": "rabbit_type", + "default": 0, + "input": int, + "description": "The type of the rabbit.", + } + ], + }, + { + "name": "Turtle", + "description": "Entity that represents a turtle.", + "base": "Animal", + "fields": [ + { + "type": "Position", + "name": "home_pos", + "default": "Position(0, 0, 0)", + "input": "Position", + "description": "The home position of the turtle.", + }, + { + "type": "Boolean", + "name": "has_egg", + "default": False, + "input": bool, + "description": "Whether the turtle has an egg.", + }, + { + "type": "Boolean", + "name": "is_laying_egg", + "default": False, + "input": bool, + "description": "Whether the turtle is laying an egg.", + }, + { + "type": "Position", + "name": "travel_pos", + "default": "Position(0, 0, 0)", + "input": "Position", + "description": "The travel position of the turtle.", + }, + { + "type": "Boolean", + "name": "is_going_home", + "default": False, + "input": bool, + "description": "Whether the turtle is going home.", + }, + { + "type": "Boolean", + "name": "is_traveling", + "default": False, + "input": bool, + "description": "Whether the turtle is traveling.", + }, + ], + }, + { + "name": "PolarBear", + "description": "Entity that represents a polar bear.", + "base": "Animal", + "fields": [ + { + "type": "Boolean", + "name": "is_standing_up", + "default": False, + "input": bool, + "description": "Whether the polar bear is standing up.", + } + ], + }, + { # Chicken + "name": "Chicken", + "description": "Entity representing a chicken.", + "base": "Animal", + "fields": [], + }, + { # Cow + "name": "Cow", + "description": "Entity representing a cow.", + "base": "Animal", + "fields": [], + }, + { # Mooshroom + "name": "Mooshroom", + "description": "Entity representing a mooshroom.", + "base": "Cow", + "fields": [ + { + "type": "String", + "name": "variant", + "default": "red", + "input": str, + "description": "The variant of the mooshroom: 'red' or 'brown'.", + } + ], + }, + { # Hoglin + "name": "Hoglin", + "description": "Entity representing a hoglin.", + "base": "Animal", + "fields": [ + { + "type": "Boolean", + "name": "immune_to_zombification", + "default": False, + "input": bool, + "description": "Whether the hoglin is immune to zombification.", + } + ], + }, + { # Sheep + "name": "Sheep", + "description": "Entity representing a sheep.", + "base": "Animal", + "fields": [ + { + "type": "Byte", + "name": "sheep_data", + "default": 0, + "input": int, + "available": False, + "proxy": [ + { + "type": "BoolMasked", + "name": "color_id", + "input": int, + "description": "The color of the sheep.", + "mask": 0x0F, + }, + { + "type": "BoolMasked", + "name": "is_sheared", + "input": bool, + "description": "Whether the sheep is sheared.", + "mask": 0x10, + }, + ], + "description": "Data of the sheep.", + } + ], + }, + { # Strider + "name": "Strider", + "description": "Entity representing a strider.", + "base": "Animal", + "fields": [ + { + "type": "VarInt", + "name": "boost_duration", + "default": 0, + "input": int, + "description": "Total time to 'boost' with warped fungus on a stick.", + }, + { + "type": "Boolean", + "name": "is_shaking", + "default": False, + "input": bool, + "description": "Whether the strider is shaking. (True unless riding a vehicle or on or in a block\n" + " tagged with strider_warm_blocks (default: lava))", + }, + { + "type": "Boolean", + "name": "has_saddle", + "default": False, + "input": bool, + "description": "Whether the strider has a saddle.", + }, + ], + }, + { # Goat + "name": "Goat", + "description": "Entity representing a goat.", + "base": "Animal", + "fields": [ + { + "type": "Boolean", + "name": "is_screaming_goat", + "default": False, + "input": bool, + "description": "Whether the goat is a screaming goat.", + }, + { + "type": "Boolean", + "name": "has_left_horn", + "default": True, + "input": bool, + "description": "Whether the goat has a left horn.", + }, + { + "type": "Boolean", + "name": "has_right_horn", + "default": True, + "input": bool, + "description": "Whether the goat has a right horn.", + }, + ], + }, + { # Tameable Animal + "name": "TameableAnimal", + "description": "Entity representing a tameable animal.", + "base": "Animal", + "fields": [ + { + "type": "Byte", + "name": "tameable_data", + "default": 0, + "input": int, + "available": False, + "proxy": [ + { + "type": "BoolMasked", + "name": "is_sitting", + "input": bool, + "description": "Whether the animal is sitting.", + "mask": 0x01, + }, + { + "type": "BoolMasked", + "name": "is_tamed", + "input": bool, + "description": "Whether the animal is tamed.", + "mask": 0x04, + }, + ], + "description": "Data of the tameable animal.", + }, + { + "type": "OptUUID", + "name": "owner_uuid", + "default": "None", + "input": "UUID|None", + "description": "The UUID of the owner, if the animal is tamed.", + }, + ], + }, + { # Cat + "name": "Cat", + "description": "Entity representing a cat.", + "base": "TameableAnimal", + "fields": [ + { + "type": "CatVariant", + "name": "cat_variant", + "default": 0, # No registry yet + "input": int, + "description": "The variant of the cat.", + }, + { + "type": "Boolean", + "name": "is_lying", + "default": False, + "input": bool, + "description": "Whether the cat is lying down.", + }, + { + "type": "Boolean", + "name": "is_relaxed", + "default": False, + "input": bool, + "description": "Unknown use. When true, the cat's head goes slightly upwards.", + }, + { + "type": "VarInt", + "name": "collar_color", + "default": 14, + "input": int, + "description": "The color of the cat's collar, using dye values.", + }, + ], + }, + { # Wolf + "name": "Wolf", + "description": "Entity representing a wolf.", + "base": "TameableAnimal", + "fields": [ + { + "type": "Boolean", + "name": "is_begging", + "default": False, + "input": bool, + "description": "Whether the wolf is begging.", + }, + { + "type": "VarInt", + "name": "collar_color", + "default": 14, + "input": int, + "description": "The color of the wolf's collar, using dye values.", + }, + { + "type": "VarInt", + "name": "anger_time", + "default": 0, + "input": int, + "description": "The time for which the wolf remains angry.", + }, + ], + }, + { # Parrot + "name": "Parrot", + "description": "Entity representing a parrot.", + "base": "TameableAnimal", + "fields": [ + { + "type": "VarInt", + "name": "variant", + "default": 0, + "input": int, + "description": "The variant of the parrot.", + } + ], + }, + { # Abstract Villager + "name": "AbstractVillager", + "description": "Entity representing an abstract villager.", + "base": "AgeableMob", + "fields": [ + { + "type": "VarInt", + "name": "head_shake_timer", + "default": 0, + "input": int, + "description": "The head shake timer of the villager, starting at 40 and decrementing each tick.", + } + ], + }, + { # Villager + "name": "Villager", + "description": "Entity representing a villager.", + "base": "AbstractVillager", + "fields": [ + { + "type": "VillagerData", + "name": "villager_data", + "default": "(0, 0, 0)", + "input": "tuple[int, int, int]", + "description": "The data associated with the villager.", + } + ], + }, + { # Wandering Trader + "name": "WanderingTrader", + "description": "Entity representing a wandering trader.", + "base": "AbstractVillager", + "fields": [], + }, + { # Abstract Golem + "name": "AbstractGolem", + "description": "Entity representing an abstract golem.", + "base": "PathfinderMob", + "fields": [], + }, + { # Iron Golem + "name": "IronGolem", + "description": "Entity representing an iron golem.", + "base": "AbstractGolem", + "fields": [ + { + "type": "Byte", + "name": "iron_golem_flags", + "default": 0, + "input": int, + "available": False, + "proxy": [ + { + "type": "BoolMasked", + "name": "is_player_created", + "input": bool, + "description": "Whether the iron golem was created by a player.", + "mask": 0x01, + } + ], + "description": "Flags of the iron golem.", + } + ], + }, + { # Snow Golem + "name": "SnowGolem", + "description": "Entity representing a snow golem.", + "base": "AbstractGolem", + "fields": [ + { + "type": "Byte", + "name": "snow_golem_flags", + "default": 0x10, + "input": int, + "available": False, + "proxy": [ + { + "type": "BoolMasked", + "name": "has_pumpkin", + "input": bool, + "description": "Whether the snow golem has a pumpkin on its head.", + "mask": 0x10, + }, + ], + "description": "Flags of the snow golem.", + } + ], + }, + { # Shulker + "name": "Shulker", + "description": "Entity representing a shulker.", + "base": "AbstractGolem", + "fields": [ + { + "type": "Direction", + "name": "attach_face", + "default": "DOWN", + "enum": True, + "input": "Direction", + "description": "The face to which the shulker is attached.", + }, + { + "type": "Byte", + "name": "shield_height", + "default": 0, + "input": int, + "description": "The shield height of the shulker.", + }, + { + "type": "Byte", + "name": "color", + "default": 16, + "input": int, + "description": "The color of the shulker, using dye color values.", + }, + ], + }, + { # Monster + "name": "Monster", + "description": "Entity representing a monster.", + "base": "PathfinderMob", + "fields": [], + }, + { # Base Piglin + "name": "BasePiglin", + "description": "Entity representing a base piglin.", + "base": "Monster", + "fields": [ + { + "type": "Boolean", + "name": "is_immune_to_zombification", + "default": False, + "input": bool, + "description": "Indicates if the piglin is immune to zombification.", + } + ], + }, + { # Piglin + "name": "Piglin", + "description": "Entity representing a piglin.", + "base": "BasePiglin", + "fields": [ + { + "type": "Boolean", + "name": "is_baby", + "default": False, + "input": bool, + "description": "Indicates if the piglin is a baby.", + }, + { + "type": "Boolean", + "name": "is_charging_crossbow", + "default": False, + "input": bool, + "description": "Indicates if the piglin is charging a crossbow.", + }, + { + "type": "Boolean", + "name": "is_dancing", + "default": False, + "input": bool, + "description": "Indicates if the piglin is dancing.", + }, + ], + }, + { # Piglin Brute + "name": "PiglinBrute", + "description": "Entity representing a piglin brute.", + "base": "BasePiglin", + "fields": [], + }, + { # Blaze + "name": "Blaze", + "description": "Entity representing a blaze.", + "base": "Monster", + "fields": [ + { + "type": "Byte", + "name": "blaze_flags", + "default": 0, + "input": int, + "available": False, + "proxy": [ + { + "type": "BoolMasked", + "name": "is_blaze_on_fire", + "input": bool, + "description": "Whether the blaze is on fire.", + "mask": 0x01, + }, + ], + "description": "Flags of the blaze.", + } + ], + }, + { # Creeper + "name": "Creeper", + "description": "Entity representing a creeper.", + "base": "Monster", + "fields": [ + { + "type": "VarInt", + "name": "state", + "default": -1, + "input": int, + "description": "The state of the creeper (-1 = idle, 1 = fuse).", + }, + { + "type": "Boolean", + "name": "is_charged", + "default": False, + "input": bool, + "description": "Indicates if the creeper is charged.", + }, + { + "type": "Boolean", + "name": "is_ignited", + "default": False, + "input": bool, + "description": "Indicates if the creeper is ignited.", + }, + ], + }, + { # Endermite + "name": "Endermite", + "description": "Entity representing an endermite.", + "base": "Monster", + "fields": [], + }, + { # Giant + "name": "Giant", + "description": "Entity representing a giant.", + "base": "Monster", + "fields": [], + }, + { # Guardian + "name": "Guardian", + "description": "Entity representing a guardian.", + "base": "Monster", + "fields": [ + { + "type": "Boolean", + "name": "is_retracting_spikes", + "default": False, + "input": bool, + "description": "Indicates if the guardian is retracting spikes.", + }, + { + "type": "VarInt", + "name": "target_eid", + "default": 0, + "input": int, + "description": "The Entity ID of the target.", + }, + ], + }, + { # Elder Guardian + "name": "ElderGuardian", + "description": "Entity representing an elder guardian.", + "base": "Guardian", + "fields": [], + }, + { # Silverfish + "name": "Silverfish", + "description": "Entity representing a silverfish.", + "base": "Monster", + "fields": [], + }, + { # Raider + "name": "Raider", + "description": "Entity representing a raider.", + "base": "Monster", + "fields": [ + { + "type": "Boolean", + "name": "is_celebrating", + "default": False, + "input": bool, + "description": "Indicates if the raider is celebrating.", + } + ], + }, + { # Abstract Illager + "name": "AbstractIllager", + "description": "Entity representing an abstract illager.", + "base": "Raider", + "fields": [], + }, + { # Vindicator + "name": "Vindicator", + "description": "Entity representing a vindicator.", + "base": "AbstractIllager", + "fields": [], + }, + { # Pillager + "name": "Pillager", + "description": "Entity representing a pillager.", + "base": "AbstractIllager", + "fields": [ + { + "type": "Boolean", + "name": "is_charging", + "default": False, + "input": bool, + "description": "Indicates if the pillager is charging.", + } + ], + }, + { # Spellcaster Illager + "name": "SpellcasterIllager", + "description": "Entity representing a spellcaster illager.", + "base": "AbstractIllager", + "fields": [ + { + "type": "Byte", + "name": "spell", + "default": 0, + "input": int, + "description": "The type of spell the illager is casting. (0: none, 1: summon vex, 2: attack,\n" + " 3: wololo, 4: disappear, 5: blindness)", + } + ], + }, + { # Evoker + "name": "Evoker", + "description": "Entity representing an evoker.", + "base": "SpellcasterIllager", + "fields": [], + }, + { # Illusioner + "name": "Illusioner", + "description": "Entity representing an illusioner.", + "base": "SpellcasterIllager", + "fields": [], + }, + { # Ravager + "name": "Ravager", + "description": "Entity representing a ravager.", + "base": "Raider", + "fields": [], + }, + { # Witch + "name": "Witch", + "description": "Entity representing a witch.", + "base": "Raider", + "fields": [ + { + "type": "Boolean", + "name": "is_drinking_potion", + "default": False, + "input": bool, + "description": "Indicates if the witch is drinking a potion.", + } + ], + }, + { # Evoker Fangs + "name": "EvokerFangs", + "description": "Entity representing evoker fangs.", + "base": "Entity", + "fields": [], + }, + { # Vex + "name": "Vex", + "description": "Entity representing a vex.", + "base": "Monster", + "fields": [ + { + "type": "Byte", + "name": "vex_flags", + "default": 0, + "input": int, + "available": False, + "proxy": [ + { + "type": "BoolMasked", + "name": "is_attacking", + "input": bool, + "description": "Indicates if the vex is charging.", + "mask": 0x01, + }, + ], + "description": "Flags of the vex.", + } + ], + }, + { # Abstract Skeleton + "name": "AbstractSkeleton", + "description": "Entity representing an abstract skeleton.", + "base": "Monster", + "fields": [], + }, + { # Skeleton + "name": "Skeleton", + "description": "Entity representing a skeleton.", + "base": "AbstractSkeleton", + "fields": [], + }, + { # Wither Skeleton + "name": "WitherSkeleton", + "description": "Entity representing a wither skeleton.", + "base": "AbstractSkeleton", + "fields": [], + }, + { # Stray + "name": "Stray", + "description": "Entity representing a stray skeleton.", + "base": "AbstractSkeleton", + "fields": [], + }, + { # Spider + "name": "Spider", + "description": "Entity representing a spider.", + "base": "Monster", + "fields": [ + { + "type": "Byte", + "name": "spider_flags", + "default": 0, + "input": int, + "available": False, + "proxy": [ + { + "type": "BoolMasked", + "name": "is_climbing", + "input": bool, + "description": "Whether the spider is climbing.", + "mask": 0x01, + }, + ], + "description": "Flags of the spider.", + } + ], + }, + { # Warden + "name": "Warden", + "description": "Entity representing a warden.", + "base": "Monster", + "fields": [ + { + "type": "VarInt", + "name": "anger_level", + "default": 0, + "input": int, + "description": "The level of anger of the warden.", + } + ], + }, + { # Wither + "name": "Wither", + "description": "Entity representing a wither.", + "base": "Monster", + "fields": [ + { + "type": "VarInt", + "name": "center_head_target", + "default": 0, + "input": int, + "description": "The entity ID of the target for the center head. (0 if no target)", + }, + { + "type": "VarInt", + "name": "left_head_target", + "default": 0, + "input": int, + "description": "The entity ID of the target for the left head. (0 if no target)", + }, + { + "type": "VarInt", + "name": "right_head_target", + "default": 0, + "input": int, + "description": "The entity ID of the target for the right head. (0 if no target)", + }, + { + "type": "VarInt", + "name": "invulnerable_time", + "default": 0, + "input": int, + "description": "The amount of time the wither is invulnerable.", + }, + ], + }, + { # Zoglin + "name": "Zoglin", + "description": "Entity representing a zoglin.", + "base": "Monster", + "fields": [ + { + "type": "Boolean", + "name": "is_baby", + "default": False, + "input": bool, + "description": "Indicates whether the zoglin is a baby.", + } + ], + }, + { # Zombie + "name": "Zombie", + "description": "Entity representing a zombie.", + "base": "Monster", + "fields": [ + { + "type": "Boolean", + "name": "is_baby", + "default": False, + "input": bool, + "description": "Indicates whether the zombie is a baby.", + }, + { + "type": "VarInt", + "name": "_zombie_type", + "default": 0, + "input": int, + "description": "Unused metadata. (Previously used for zombie type)", + }, + { + "type": "Boolean", + "name": "is_becoming_drowned", + "default": False, + "input": bool, + "description": "Indicates whether the zombie is in the process of becoming a drowned.", + }, + ], + }, + { # Zombie Villager + "name": "ZombieVillager", + "description": "Entity representing a zombie villager.", + "base": "Zombie", + "fields": [ + { + "type": "Boolean", + "name": "is_converting", + "default": False, + "input": bool, + "description": "Indicates whether the zombie villager is currently converting.", + }, + { + "type": "VillagerData", + "name": "villager_data", + "default": "(0, 0, 0)", + "input": "tuple[int, int, int]", + "description": "The data of the villager associated with the zombie villager.", + }, + ], + }, + { # Husk + "name": "Husk", + "description": "Entity representing a husk.", + "base": "Zombie", + "fields": [], + }, + { # Drowned + "name": "Drowned", + "description": "Entity representing a drowned.", + "base": "Zombie", + "fields": [], + }, + { # Zombified Piglin + "name": "ZombifiedPiglin", + "description": "Entity representing a zombified piglin.", + "base": "Zombie", + "fields": [], + }, + { # Enderman + "name": "Enderman", + "description": "Entity representing an enderman.", + "base": "Monster", + "fields": [ + { + "type": "OptBlockState", + "name": "carried_block", + "default": "None", + "input": "int | None", + "description": "The block the enderman is carrying.", + }, + { + "type": "Boolean", + "name": "is_screaming", + "default": False, + "input": bool, + "description": "Indicates if the enderman is screaming.", + }, + { + "type": "Boolean", + "name": "is_staring", + "default": False, + "input": bool, + "description": "Indicates if the enderman is staring.", + }, + ], + }, + { # Ender Dragon + "name": "EnderDragon", + "description": "Entity representing an ender dragon.", + "base": "Mob", + "fields": [ + { + "type": "DragonPhase", + "name": "dragon_phase", + "default": "HOVERING_NO_AI", + "enum": True, + "input": "DragonPhase", + "description": "The current phase of the ender dragon.", + } + ], + }, + { # Flying + "name": "Flying", + "description": "Base entity for flying mobs.", + "base": "Mob", + "fields": [], + }, + { # Ghast + "name": "Ghast", + "description": "Entity representing a ghast.", + "base": "Flying", + "fields": [ + { + "type": "Boolean", + "name": "is_attacking", + "default": False, + "input": bool, + "description": "Indicates if the ghast is attacking.", + } + ], + }, + { # Phantom + "name": "Phantom", + "description": "Entity representing a phantom.", + "base": "Flying", + "fields": [ + {"type": "VarInt", "name": "size", "default": 0, "input": int, "description": "The size of the phantom."} + ], + }, + { # Slime + "name": "Slime", + "description": "Entity representing a slime.", + "base": "Mob", + "fields": [ + {"type": "VarInt", "name": "size", "default": 1, "input": int, "description": "The size of the slime."} + ], + }, + { # Llama Spit + "name": "LlamaSpit", + "description": "Entity representing spit from a llama.", + "base": "Entity", + "fields": [], + }, + { # Primed TNT + "name": "PrimedTnt", + "description": "Entity representing primed TNT.", + "base": "Entity", + "fields": [ + { + "type": "VarInt", + "name": "fuse_time", + "default": 80, + "input": int, + "description": "The fuse time for the primed TNT.", + } + ], + }, +] diff --git a/tests/helpers.py b/tests/helpers.py index 5d643b7b..01f91763 100644 --- a/tests/helpers.py +++ b/tests/helpers.py @@ -23,7 +23,7 @@ "UnpropagatingMockMixin", "CustomMockMixin", "gen_serializable_test", - "TestExc", + "ExcTest", ] @@ -176,12 +176,12 @@ def __init__(self, **kwargs): super().__init__(spec_set=self.spec_set, **kwargs) # type: ignore # Mixin class, this __init__ is valid -def isexception(obj: object) -> TypeGuard[type[Exception] | TestExc]: +def isexception(obj: object) -> TypeGuard[type[Exception] | ExcTest]: """Check if the object is an exception.""" - return (isinstance(obj, type) and issubclass(obj, Exception)) or isinstance(obj, TestExc) + return (isinstance(obj, type) and issubclass(obj, Exception)) or isinstance(obj, ExcTest) -class TestExc(NamedTuple): +class ExcTest(NamedTuple): """Named tuple to check if an exception is raised with a specific message. :param exception: The exception type. @@ -198,9 +198,9 @@ class TestExc(NamedTuple): kwargs: dict[str, Any] | None = None @classmethod - def from_exception(cls, exception: type[Exception] | tuple[type[Exception], ...] | TestExc) -> TestExc: - """Create a :class:`TestExc` from an exception, does nothing if the object is already a :class:`TestExc`.""" - if isinstance(exception, TestExc): + def from_exception(cls, exception: type[Exception] | tuple[type[Exception], ...] | ExcTest) -> ExcTest: + """Create a :class:`ExcTest` from an exception, does nothing if the object is already a :class:`ExcTest`.""" + if isinstance(exception, ExcTest): return exception return cls(exception) @@ -209,9 +209,11 @@ def gen_serializable_test( context: dict[str, Any], cls: type[Serializable], fields: list[tuple[str, type | str]], + *, serialize_deserialize: list[tuple[tuple[Any, ...], bytes]] | None = None, - validation_fail: list[tuple[tuple[Any, ...], type[Exception] | TestExc]] | None = None, - deserialization_fail: list[tuple[bytes, type[Exception] | TestExc]] | None = None, + validation_fail: list[tuple[tuple[Any, ...], type[Exception] | ExcTest]] | None = None, + deserialization_fail: list[tuple[bytes, type[Exception] | ExcTest]] | None = None, + test_suffix: str = "", ): """Generate tests for a serializable class. @@ -222,18 +224,20 @@ def gen_serializable_test( :param cls: The serializable class to test. :param fields: A list of tuples containing the field names and types of the serializable class. :param serialize_deserialize: A list of tuples containing: - - The tuple representing the arguments to pass to the :class:`mcproto.utils.abc.Serializable` class + - The tuple representing the arguments to pass to the :class:`~mcproto.utils.abc.Serializable` class - The expected bytes :param validation_fail: A list of tuples containing the arguments to pass to the - :class:`mcproto.utils.abc.Serializable` class and the expected exception, either as is or wrapped in a - :class:`TestExc` object. + :class:`~mcproto.utils.abc.Serializable` class and the expected exception, either as is or wrapped in a + :class:`ExcTest` object. :param deserialization_fail: A list of tuples containing the bytes to pass to the :meth:`deserialize` method of the - class and the expected exception, either as is or wrapped in a :class:`TestExc` object. + class and the expected exception, either as is or wrapped in a :class:`ExcTest` object. + :param test_suffix: The suffix to add to the test class name. Example usage: .. literalinclude:: /../tests/mcproto/utils/test_serializable.py - :start-after: # region ToyClass + :start-after: # region Test ToyClass + :end-before: # endregion :linenos: :language: python @@ -249,7 +253,7 @@ class and the expected exception, either as is or wrapped in a :class:`TestExc` parameters: list[tuple[dict[str, Any], bytes]] = [] # This holds the parameters for the validation tests - validation_fail_kw: list[tuple[dict[str, Any], TestExc]] = [] + validation_fail_kw: list[tuple[dict[str, Any], ExcTest]] = [] for data, exp_bytes in [] if serialize_deserialize is None else serialize_deserialize: kwargs = dict(zip([f[0] for f in fields], data)) @@ -257,14 +261,14 @@ class and the expected exception, either as is or wrapped in a :class:`TestExc` for data, exc in [] if validation_fail is None else validation_fail: kwargs = dict(zip([f[0] for f in fields], data)) - exc_wrapped = TestExc.from_exception(exc) + exc_wrapped = ExcTest.from_exception(exc) validation_fail_kw.append((kwargs, exc_wrapped)) - # Just make sure that the exceptions are wrapped in TestExc + # Just make sure that the exceptions are wrapped in ExcTest deserialization_fail = ( [] if deserialization_fail is None - else [(data, TestExc.from_exception(exc)) for data, exc in deserialization_fail] + else [(data, ExcTest.from_exception(exc)) for data, exc in deserialization_fail] ) def generate_name(param: dict[str, Any] | bytes, i: int) -> str: @@ -304,6 +308,7 @@ def test_serialization(self, kwargs: dict[str, Any], expected_bytes: bytes): def test_deserialization(self, kwargs: dict[str, Any], expected_bytes: bytes): """Test deserialization of the object.""" buf = Buffer(expected_bytes) + obj = cls.deserialize(buf) equality = cls(**kwargs) == obj error_message: list[str] = [] @@ -327,7 +332,7 @@ def test_deserialization(self, kwargs: dict[str, Any], expected_bytes: bytes): validation_fail_kw, ids=tuple(generate_name(kwargs, i) for i, (kwargs, _) in enumerate(validation_fail_kw)), ) - def test_validation(self, kwargs: dict[str, Any], exc: TestExc): + def test_validation(self, kwargs: dict[str, Any], exc: ExcTest): """Test validation of the object.""" with pytest.raises(exc.exception, match=exc.match) as exc_info: cls(**kwargs) @@ -344,7 +349,7 @@ def test_validation(self, kwargs: dict[str, Any], exc: TestExc): deserialization_fail, ids=tuple(generate_name(content, i) for i, (content, _) in enumerate(deserialization_fail)), ) - def test_deserialization_error(self, content: bytes, exc: TestExc): + def test_deserialization_error(self, content: bytes, exc: ExcTest): """Test deserialization error handling.""" buf = Buffer(content) with pytest.raises(exc.exception, match=exc.match) as exc_info: @@ -371,7 +376,7 @@ def test_deserialization_error(self, content: bytes, exc: TestExc): del TestClass.test_deserialization_error # Set the names of the class - TestClass.__name__ = f"TestGen{cls.__name__}" + TestClass.__name__ = f"TestGen{cls.__name__}{test_suffix}" # Add the test functions to the global context context[TestClass.__name__] = TestClass # BERK diff --git a/tests/mcproto/packets/handshaking/test_handshake.py b/tests/mcproto/packets/handshaking/test_handshake.py index 6fe0d525..59332d3f 100644 --- a/tests/mcproto/packets/handshaking/test_handshake.py +++ b/tests/mcproto/packets/handshaking/test_handshake.py @@ -30,8 +30,5 @@ bytes.fromhex("f5050b6879706978656c2e6e657463dd01"), ), ], - validation_fail=[ - # Invalid next state - ((757, "localhost", 25565, 3), ValueError), - ], + deserialization_fail=[(b"\xf5\x05\x0fmc.aircs.racingc\xdd\x0f", ValueError)], ) diff --git a/tests/mcproto/packets/login/test_login.py b/tests/mcproto/packets/login/test_login.py index 33ad8095..7d65bba3 100644 --- a/tests/mcproto/packets/login/test_login.py +++ b/tests/mcproto/packets/login/test_login.py @@ -11,7 +11,7 @@ LoginSuccess, ) from mcproto.packets.packet import InvalidPacketContentError -from mcproto.types.chat import ChatMessage +from mcproto.types.chat import JSONTextComponent from mcproto.types.uuid import UUID from tests.helpers import gen_serializable_test from tests.mcproto.test_encryption import RSA_PUBLIC_KEY @@ -57,7 +57,7 @@ def test_login_encryption_request_noid(): """Test LoginEncryptionRequest without server_id.""" - packet = LoginEncryptionRequest(server_id=None, public_key=RSA_PUBLIC_KEY, verify_token=bytes.fromhex("9bd416ef")) + packet = LoginEncryptionRequest(public_key=RSA_PUBLIC_KEY, verify_token=bytes.fromhex("9bd416ef")) assert packet.server_id == " " * 20 # None is converted to an empty server id @@ -92,10 +92,10 @@ def test_login_encryption_request_noid(): gen_serializable_test( context=globals(), cls=LoginDisconnect, - fields=[("reason", ChatMessage)], + fields=[("reason", JSONTextComponent)], serialize_deserialize=[ ( - (ChatMessage("You are banned."),), + (JSONTextComponent("You are banned."),), bytes.fromhex("1122596f75206172652062616e6e65642e22"), ), ], diff --git a/tests/mcproto/packets/status/test_status.py b/tests/mcproto/packets/status/test_status.py index 63459ba2..baa6c593 100644 --- a/tests/mcproto/packets/status/test_status.py +++ b/tests/mcproto/packets/status/test_status.py @@ -26,6 +26,6 @@ ], validation_fail=[ # Unserializable data for JSON - (({"data": object()},), ValueError), + (({"data": object()},), TypeError), ], ) diff --git a/tests/mcproto/types/entity/__init__.py b/tests/mcproto/types/entity/__init__.py new file mode 100644 index 00000000..9d48db4f --- /dev/null +++ b/tests/mcproto/types/entity/__init__.py @@ -0,0 +1 @@ +from __future__ import annotations diff --git a/tests/mcproto/types/entity/test_metadata.py b/tests/mcproto/types/entity/test_metadata.py new file mode 100644 index 00000000..7e0e0627 --- /dev/null +++ b/tests/mcproto/types/entity/test_metadata.py @@ -0,0 +1,101 @@ +import pytest + +from mcproto.buffer import Buffer +from mcproto.types.entity import DisplayEM, PandaEM +from mcproto.types.entity.metadata import EntityMetadata, EntityMetadataCreator, entry, proxy +from mcproto.types.entity.metadata_types import BoolMasked, ByteEME +from mcproto.types.vec3 import Vec3 + + +def test_panda(): + """Test the Panda entity (it has a lot of inherited fields, so it's a good test case).""" + panda = PandaEM() + + assert panda.serialize() == b"\xff" # No metadata + + panda.active_hand = 0 + panda.is_hand_active = True + panda.is_riptide_spin_attack = True + # Index 8, Type 0 (byte), Value 0b00000101 + assert panda.serialize() == b"\x08\x00\x05\xff" + # 0bxx1 hand active + # 0bx0x main hand active (1 for offhand) + # 0b1xx riptide spin attack + + panda.is_sneezing = True + # Index 8, Type 0 (byte), Value 0b00000101, Index 22, Type 0 (byte), Value 2 + assert panda.serialize() == b"\x08\x00\x05\x16\x00\x02\xff" + + panda.active_hand = 0 + panda.is_hand_active = False + panda.is_riptide_spin_attack = False + panda.eat_timer = -1 # VarInt 0xff 0xff 0xff 0xff 0x0f + # Index 22, Type 0 (byte), Value 2, Index 19, Type 1 (VarInt), Value -1 + assert panda.serialize() == b"\x13\x01\xff\xff\xff\xff\x0f\x16\x00\x02\xff" + + buf = Buffer(b"\x13\x01\x02\x16\x00\x02\x08\x00\x07\xff") + panda2 = PandaEM.deserialize(buf) + assert panda2.active_hand == 1 + assert panda2.is_hand_active + assert panda2.is_riptide_spin_attack + assert panda2.eat_timer == 2 + assert panda2.is_sneezing + assert not panda2.is_sitting + + +def test_assign_vec3(): + """Test assigning a Vec3 to an EntityMetadata. + + This is meant to test assigning a value to a field that is not a primitive type. + """ + display = DisplayEM() + + display.scale = Vec3(1.0, 2.0, 3.0) + display.scale.x = 4.0 + assert display.scale == Vec3(4.0, 2.0, 3.0) + + +def test_kwargs(): + """Test kwargs for EnitityMetadata.""" + panda = PandaEM(custom_name="test", is_custom_name_visible=True) + assert panda.custom_name == "test" + assert panda.is_custom_name_visible + + +def test_class_error(): + """Test errors for EntityMetadataCreator.""" + with pytest.raises(TypeError): + proxy("test", BoolMasked, mask=0x1) # type: ignore # wrong type + + with pytest.raises(TypeError): + proxy(object, BoolMasked, mask=0x1) # type: ignore # wrong type + + with pytest.raises(ValueError, match=r"Default value for .* is not set\."): + + class Test(metaclass=EntityMetadataCreator): # type: ignore + """Test class.""" + + test: int = None # type: ignore + + with pytest.raises(ValueError): + EntityMetadata(1, 1) # type: ignore + + with pytest.raises(ValueError, match=r"Bound entry for .* is not set\."): + + class Test(metaclass=EntityMetadataCreator): # noqa: F811 + """Test class.""" + + test: int = proxy(entry(ByteEME, 1), BoolMasked, mask=0x1) + + buf = Buffer(b"\x00\x02\x00") # Wrong metadata type + with pytest.raises(TypeError): + ByteEME.deserialize(buf) + + EntityMetadata() + + buf = Buffer(b"\x00\xff\x00") # Invalid metadata type + with pytest.raises(TypeError): + EntityMetadata.deserialize(buf) + + with pytest.raises(ValueError): + EntityMetadata(keyword="test") diff --git a/tests/mcproto/types/entity/test_metadata_types.py b/tests/mcproto/types/entity/test_metadata_types.py new file mode 100644 index 00000000..aa9da1eb --- /dev/null +++ b/tests/mcproto/types/entity/test_metadata_types.py @@ -0,0 +1,664 @@ +from typing import Union + +from mcproto.types import SlotData +from mcproto.types.chat import TextComponent +from mcproto.types.entity.enums import Direction, DragonPhase, Pose, SnifferState +from mcproto.types.entity.metadata_types import ( + BlockStateEME, + BoolMasked, + BooleanEME, + ByteEME, + CatVariantEME, + DirectionEME, + DragonPhaseEME, + FloatEME, + FrogVariantEME, + IntMasked, + NBTagEME, + OptBlockStateEME, + OptGlobalPositionEME, + OptPositionEME, + OptTextComponentEME, + OptUUIDEME, + OptVarIntEME, + PaintingVariantEME, + ParticleEME, + PoseEME, + PositionEME, + QuaternionEME, + RotationEME, + SlotEME, + SnifferStateEME, + StringEME, + TextComponentEME, + VarIntEME, + VarLongEME, + Vector3EME, + VillagerDataEME, +) +from mcproto.types.identifier import Identifier +from mcproto.types.nbt import ByteNBT, CompoundNBT, EndNBT, NBTag, StringNBT +from mcproto.types.particle_data import ParticleData +from mcproto.types.quaternion import Quaternion +from mcproto.types.slot import Slot +from mcproto.types.uuid import UUID +from mcproto.types.vec3 import Position, Vec3 +from tests.helpers import gen_serializable_test + +# ByteEME +gen_serializable_test( + context=globals(), + cls=ByteEME, + fields=[ + ("index", int), + ("value", int), + ], + serialize_deserialize=[ + ((54, 0), b"\x36\x00\x00"), + ((1, 1), b"\x01\x00\x01"), + ((2, 127), b"\x02\x00\x7f"), + ((3, -1), b"\x03\x00\xff"), + ((4, -128), b"\x04\x00\x80"), + ], + validation_fail=[ + ((-1, 0), ValueError), + ((54, 128), ValueError), + ((54, -129), ValueError), + ], + deserialization_fail=[ + (b"\xff\x00\x01", ValueError), # End of metadata + (b"\x01\x02", TypeError), # Wrong type + ], +) + +# VarIntEME +gen_serializable_test( + context=globals(), + cls=VarIntEME, + fields=[ + ("index", int), + ("value", int), + ], + serialize_deserialize=[ + ((54, 0), b"\x36\x01\x00"), + ((1, 1), b"\x01\x01\x01"), + ((2, 127), b"\x02\x01\x7f"), + ((3, -1), b"\x03\x01\xff\xff\xff\xff\x0f"), + ((4, 128), b"\x04\x01\x80\x01"), + ], + validation_fail=[ + ((-1, 0), ValueError), + ((54, 2**31), ValueError), + ((54, -(2**31 + 1)), ValueError), + ], +) + +# VarLongEME +gen_serializable_test( + context=globals(), + cls=VarLongEME, + fields=[ + ("index", int), + ("value", int), + ], + serialize_deserialize=[ + ((54, 0), b"\x36\x02\x00"), + ((1, 1), b"\x01\x02\x01"), + ((2, 127), b"\x02\x02\x7f"), + ((3, -1), b"\x03\x02\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01"), + ((4, 128), b"\x04\x02\x80\x01"), + ], + validation_fail=[ + ((-1, 0), ValueError), + ((54, 2**63), ValueError), + ((54, -(2**63 + 1)), ValueError), + ], +) + +# FloatEME +gen_serializable_test( + context=globals(), + cls=FloatEME, + fields=[ + ("index", int), + ("value", float), + ], + serialize_deserialize=[ + ((54, 0.0), b"\x36\x03\x00\x00\x00\x00"), + ((1, 2.0), b"\x01\x03\x40\x00\x00\x00"), + ((2, -1.0), b"\x02\x03\xbf\x80\x00\x00"), + ((3, 127.0), b"\x03\x03\x42\xfe\x00\x00"), + ((4, 0.5), b"\x04\x03\x3f\x00\x00\x00"), + ], + validation_fail=[ + ((-1, 0.0), ValueError), + ], +) + +# StringEME +gen_serializable_test( + context=globals(), + cls=StringEME, + fields=[ + ("index", int), + ("value", str), + ], + serialize_deserialize=[ + ((54, ""), b"\x36\x04\x00"), + ((1, "a"), b"\x01\x04\x01a"), + ((2, "abc"), b"\x02\x04\x03abc"), + ], + validation_fail=[ + ((-1, ""), ValueError), + ((54, "a" * 32768), ValueError), + ], +) + +# TextComponentEME +gen_serializable_test( + context=globals(), + cls=TextComponentEME, + fields=[ + ("index", int), + ("value", TextComponent), + ], + serialize_deserialize=[ + ((54, TextComponent("")), b"\x36\x05" + CompoundNBT([StringNBT("", name="text")]).serialize()), + ((1, TextComponent({"text": "a"})), b"\x01\x05" + CompoundNBT([StringNBT("a", name="text")]).serialize()), + ( + ( + 2, + TextComponent( + { + "text": "abc", + "italic": False, + "bold": True, # Order is not important in the result but it is in the test + } + ), + ), + b"\x02\x05" + + CompoundNBT([StringNBT("abc", name="text"), ByteNBT(0, "italic"), ByteNBT(1, "bold")]).serialize(), + ), + ], + validation_fail=[ + ((-1, TextComponent("")), ValueError), + ], +) + +# OptTextComponentEME +gen_serializable_test( + context=globals(), + cls=OptTextComponentEME, + fields=[ + ("index", int), + ("value", Union[TextComponent, None]), + ], + serialize_deserialize=[ + ((54, None), b"\x36\x06\x00"), + ((1, TextComponent("")), b"\x01\x06\x01" + CompoundNBT([StringNBT("", name="text")]).serialize()), + ((2, TextComponent("a")), b"\x02\x06\x01" + CompoundNBT([StringNBT("a", name="text")]).serialize()), + ], + validation_fail=[ + ((-1, None), ValueError), + ], +) + +# SlotEME +gen_serializable_test( + context=globals(), + cls=SlotEME, + fields=[ + ("index", int), + ("value", Slot), + ], + serialize_deserialize=[ + ( + (54, Slot(SlotData(1, 1))), + b"\x36\x07" + Slot(SlotData(1, 1)).serialize(), + ), + ], +) + +# BooleanEME +gen_serializable_test( + context=globals(), + cls=BooleanEME, + fields=[ + ("index", int), + ("value", bool), + ], + serialize_deserialize=[ + ((54, True), b"\x36\x08\x01"), + ((1, False), b"\x01\x08\x00"), + ], + validation_fail=[ + ((-1, True), ValueError), + ], +) + +# RotationEME +gen_serializable_test( + context=globals(), + cls=RotationEME, + fields=[ + ("index", int), + ("value", Vec3), + ], + serialize_deserialize=[ + ((54, Vec3(0.0, 0.0, 0.0)), b"\x36\x09" + Vec3(0.0, 0.0, 0.0).serialize()), + ((1, Vec3(1.0, 2.0, 3.0)), b"\x01\x09" + Vec3(1.0, 2.0, 3.0).serialize()), + ], + validation_fail=[ + ((-1, Vec3(0.0, 0.0, 0.0)), ValueError), + ], +) + +# PositionEME +gen_serializable_test( + context=globals(), + cls=PositionEME, + fields=[ + ("index", int), + ("value", Position), + ], + serialize_deserialize=[ + ((54, Position(0, 0, 0)), b"\x36\x0a" + Position(0, 0, 0).serialize()), + ((1, Position(1, 2, 3)), b"\x01\x0a" + Position(1, 2, 3).serialize()), + ], + validation_fail=[ + ((-1, Position(0, 0, 0)), ValueError), + ], +) + +# OptPositionEME +gen_serializable_test( + context=globals(), + cls=OptPositionEME, + fields=[ + ("index", int), + ("value", Union[Position, None]), + ], + serialize_deserialize=[ + ((54, None), b"\x36\x0b\x00"), + ((1, Position(0, 0, 0)), b"\x01\x0b\01" + Position(0, 0, 0).serialize()), + ], + validation_fail=[ + ((-1, Position(0, 0, 0)), ValueError), + ], +) + +# DirectionEME +gen_serializable_test( + context=globals(), + cls=DirectionEME, + fields=[ + ("index", int), + ("value", Direction), + ], + serialize_deserialize=[ + ((54, Direction.DOWN), b"\x36\x0c\x00"), + ((1, Direction.NORTH), b"\x01\x0c\x02"), + ((2, Direction.EAST), b"\x02\x0c\x05"), + ], + validation_fail=[ + ((-1, Direction.DOWN), ValueError), + ], + deserialization_fail=[ + (b"\x01\x0c\x0f", ValueError), + ], +) + +# OptUUIDEME +gen_serializable_test( + context=globals(), + cls=OptUUIDEME, + fields=[ + ("index", int), + ("value", Union[UUID, None]), + ], + serialize_deserialize=[ + ((54, None), b"\x36\r\x00"), + ((1, UUID("0" * 32)), b"\x01\r\x01" + UUID("0" * 32).serialize()), + ((2, UUID("f" * 32)), b"\x02\r\x01" + UUID("f" * 32).serialize()), + ], + validation_fail=[ + ((-1, UUID("0" * 32)), ValueError), + ], +) + +# BlockStateEME +gen_serializable_test( + context=globals(), + cls=BlockStateEME, + fields=[ + ("index", int), + ("value", int), + ], + serialize_deserialize=[ + ((54, 0), b"\x36\x0e\x00"), + ((1, 1), b"\x01\x0e\x01"), + ((2, 127), b"\x02\x0e\x7f"), + ], + validation_fail=[ + ((-1, 0), ValueError), + ], +) + + +# OptBlockStateEME +gen_serializable_test( + context=globals(), + cls=OptBlockStateEME, + fields=[ + ("index", int), + ("value", Union[int, None]), + ], + serialize_deserialize=[ + ((54, None), b"\x36\x0f\x00"), + ((1, 1), b"\x01\x0f\x01"), + ((2, 3), b"\x02\x0f\x03"), # Air is not representable + ], + validation_fail=[ + ((-1, 0), ValueError), + ], +) + +# NBTagEME +gen_serializable_test( + context=globals(), + cls=NBTagEME, + fields=[ + ("index", int), + ("value", NBTag), + ], + serialize_deserialize=[ + ((54, EndNBT()), b"\x36\x10" + EndNBT().serialize()), + ( + (1, CompoundNBT([StringNBT("a", name="b")])), + b"\x01\x10" + CompoundNBT([StringNBT("a", name="b")]).serialize(), + ), + ], + validation_fail=[ + ((-1, EndNBT()), ValueError), + ], +) + +# ParticleEME +gen_serializable_test( + context=globals(), + cls=ParticleEME, + fields=[ + ("index", int), + ("value", ParticleData), + ], + serialize_deserialize=[ + ( + (54, ParticleData(1, 2)), + b"\x36\x11" + ParticleData(1, 2).serialize(), + ), + ], + validation_fail=[ + ((-1, ParticleData(1, 2)), ValueError), + ], +) + +# VillagerDataEME +gen_serializable_test( + context=globals(), + cls=VillagerDataEME, + fields=[ + ("index", int), + ("value", tuple), + ], + serialize_deserialize=[ + ((54, (0, 0, 0)), b"\x36\x12\x00\x00\x00"), + ((1, (1, 2, 3)), b"\x01\x12\x01\x02\x03"), + ], + validation_fail=[ + ((-1, (0, 0, 0)), ValueError), + ], +) + +# OptVarIntEME +gen_serializable_test( + context=globals(), + cls=OptVarIntEME, + fields=[ + ("index", int), + ("value", Union[int, None]), + ], + serialize_deserialize=[ + ((54, None), b"\x36\x13\x00"), + ((1, 0), b"\x01\x13\x01"), + ((2, 127), b"\x02\x13\x80\x01"), + ], + validation_fail=[ + ((-1, 0), ValueError), + ], +) + +# PoseEME +gen_serializable_test( + context=globals(), + cls=PoseEME, + fields=[ + ("index", int), + ("value", Pose), + ], + serialize_deserialize=[ + ((54, Pose.STANDING), b"\x36\x14\x00"), + ((1, Pose.SPIN_ATTACK), b"\x01\x14\x04"), + ((2, Pose.DYING), b"\x02\x14\x07"), + ], + validation_fail=[ + ((-1, Pose.STANDING), ValueError), + ], +) + +# CatVariantEME +gen_serializable_test( # Need to update when registries are implemented + context=globals(), + cls=CatVariantEME, + fields=[ + ("index", int), + ("value", int), + ], + serialize_deserialize=[ + ((54, 0), b"\x36\x15\x00"), + ((1, 1), b"\x01\x15\x01"), + ((2, 127), b"\x02\x15\x7f"), + ], + validation_fail=[ + ((-1, 0), ValueError), + ], +) + +# FrogVariantEME +gen_serializable_test( # Need to update when registries are implemented + context=globals(), + cls=FrogVariantEME, + fields=[ + ("index", int), + ("value", int), + ], + serialize_deserialize=[ + ((54, 0), b"\x36\x16\x00"), + ((1, 1), b"\x01\x16\x01"), + ((2, 127), b"\x02\x16\x7f"), + ], + validation_fail=[ + ((-1, 0), ValueError), + ], +) + +# DragonPhaseEME +gen_serializable_test( + context=globals(), + cls=DragonPhaseEME, + fields=[ + ("index", int), + ("value", DragonPhase), + ], + serialize_deserialize=[ # 0x01 because it is really a varint and not an Enum, I wanted better readability + ((54, DragonPhase.CIRCLING), b"\x36\x01\x00"), + ((1, DragonPhase.STRAFING), b"\x01\x01\x01"), + ((2, DragonPhase.LANDED_BREATH_ATTACK), b"\x02\x01\x05"), + ], + validation_fail=[ + ((-1, DragonPhase.CIRCLING), ValueError), + ], +) + +# OptGlobalPositionEME +gen_serializable_test( + context=globals(), + cls=OptGlobalPositionEME, + fields=[ + ("index", int), + ("value", tuple), # Identifier, Position | None + ], + serialize_deserialize=[ + ((54, None), b"\x36\x17\x00"), + ( + (1, (Identifier("minecraft", "overworld"), Position(4, 5, 6))), + b"\x01\x17\x01" + Identifier("minecraft", "overworld").serialize() + Position(4, 5, 6).serialize(), + ), + ], +) + +# PaintingVariantEME +gen_serializable_test( # Need to update when registries are implemented + context=globals(), + cls=PaintingVariantEME, + fields=[ + ("index", int), + ("value", int), + ], + serialize_deserialize=[ + ((54, 0), b"\x36\x18\x00"), + ((1, 1), b"\x01\x18\x01"), + ((2, 127), b"\x02\x18\x7f"), + ], + validation_fail=[ + ((-1, 0), ValueError), + ], +) + + +# SnifferStateEME +gen_serializable_test( + context=globals(), + cls=SnifferStateEME, + fields=[ + ("index", int), + ("value", SnifferState), + ], + serialize_deserialize=[ + ((54, SnifferState.IDLING), b"\x36\x19\x00"), + ((1, SnifferState.SNIFFING), b"\x01\x19\x03"), + ((2, SnifferState.RISING), b"\x02\x19\x06"), + ], + validation_fail=[ + ((-1, SnifferState.IDLING), ValueError), + ((1, 0xF), ValueError), + ], + deserialization_fail=[ + (b"\x01\x19\x0f", ValueError), + ], +) + +# Vector3EME +gen_serializable_test( + context=globals(), + cls=Vector3EME, + fields=[ + ("index", int), + ("value", Vec3), + ], + serialize_deserialize=[ + ((54, Vec3(0.0, 0.0, 0.0)), b"\x36\x1a" + Vec3(0.0, 0.0, 0.0).serialize()), + ((1, Vec3(1.0, 2.0, 3.0)), b"\x01\x1a" + Vec3(1.0, 2.0, 3.0).serialize()), + ], + validation_fail=[ + ((-1, Vec3(0.0, 0.0, 0.0)), ValueError), + ], +) + +# QuaternionEME +gen_serializable_test( + context=globals(), + cls=QuaternionEME, + fields=[ + ("index", int), + ("value", Quaternion), + ], + serialize_deserialize=[ + ((54, Quaternion(0.0, 0.0, 0.0, 1.0)), b"\x36\x1b" + Quaternion(0.0, 0.0, 0.0, 1.0).serialize()), + ((1, Quaternion(1.0, 2.0, 3.0, 4.0)), b"\x01\x1b" + Quaternion(1.0, 2.0, 3.0, 4.0).serialize()), + ], + validation_fail=[ + ((-1, Quaternion(0.0, 0.0, 0.0, 1.0)), ValueError), + ], +) + +# BoolMasked +gen_serializable_test( + context=globals(), + cls=BoolMasked, + fields=[ + ("bound_entry", ByteEME), + ("mask", int), + ], + validation_fail=[ + ((ByteEME(1, 0), 0b00000011), ValueError), # not a power of 2 + ], +) + + +def test_masked(): + """Test the IntMasked class.""" + container = ByteEME(index=1, value=0) + mask1 = IntMasked(container, mask=0b00000001) + bmask1 = BoolMasked(container, mask=0b00000001) + mask2 = IntMasked(container, mask=0b00000010) + bmask2 = BoolMasked(container, mask=0b00000010) + mask3 = IntMasked(container, mask=0b00000100) + bmask3 = BoolMasked(container, mask=0b00000100) + mask12 = IntMasked(container, mask=0b00000011) + mask13 = IntMasked(container, mask=0b00000101) + + assert mask1.getter() == 0 + assert bmask1.getter() is False + assert mask2.getter() == 0 + assert bmask2.getter() is False + assert mask3.getter() == 0 + assert bmask3.getter() is False + assert mask12.getter() == 0 + assert mask13.getter() == 0 + + mask1.setter(1) + mask2.setter(1) + assert mask1.getter() == 1 + assert bmask1.getter() is True + assert mask2.getter() == 1 + assert bmask2.getter() is True + assert mask3.getter() == 0 + assert bmask3.getter() is False + assert mask12.getter() == 3 + assert mask13.getter() == 1 + + mask1.setter(0) + mask3.setter(1) + assert mask1.getter() == 0 + assert bmask1.getter() is False + assert mask13.getter() == 2 + + mask12.setter(0) + assert mask12.getter() == 0 + assert mask13.getter() == 2 + assert mask1.getter() == 0 + assert bmask1.getter() is False + assert mask2.getter() == 0 + assert bmask2.getter() is False + assert mask3.getter() == 1 + assert bmask3.getter() is True diff --git a/tests/mcproto/types/test_advancement.py b/tests/mcproto/types/test_advancement.py new file mode 100644 index 00000000..f41ec452 --- /dev/null +++ b/tests/mcproto/types/test_advancement.py @@ -0,0 +1,194 @@ +import struct + +from mcproto.types import ( + Advancement, + AdvancementCriterion, + AdvancementDisplay, + AdvancementFrame, + AdvancementProgress, + Identifier, + Slot, + SlotData, + TextComponent, +) +from tests.mcproto.utils.test_serializable import gen_serializable_test + +gen_serializable_test( + context=globals(), + cls=AdvancementDisplay, + fields=[ + ("title", TextComponent), + ("description", TextComponent), + ("icon", Slot), + ("frame", AdvancementFrame), + ("background", "Identifier|None"), + ("show_toast", bool), + ("hidden", bool), + ("x", float), + ("y", float), + ], + serialize_deserialize=[ + ( + ( + TextComponent("The End?"), + TextComponent("Go there"), + Slot(SlotData(2, 1)), + AdvancementFrame.CHALLENGE, + Identifier(namespace="minecraft", path="textures/gui/advancements/backgrounds/end.png"), + True, + False, + 0.5, + 0.5, + ), + bytes( + TextComponent("The End?").serialize() + + TextComponent("Go there").serialize() + + Slot(SlotData(2, 1)).serialize() + + b"\x01" # frame + + b"\x03" # 0b011 + + Identifier(namespace="minecraft", path="textures/gui/advancements/backgrounds/end.png").serialize() + + struct.pack("!ff", 0.5, 0.5) + ), + ), + ( + ( + TextComponent("The End?"), + TextComponent("Go there"), + Slot(SlotData(2, 1)), + AdvancementFrame.TASK, + None, + False, + True, + 0.5, + 0.5, + ), + bytes( + TextComponent("The End?").serialize() + + TextComponent("Go there").serialize() + + Slot(SlotData(2, 1)).serialize() + + b"\x00" # frame + + b"\x04" # 0b100 + + struct.pack("!ff", 0.5, 0.5) + ), + ), + ], +) + + +gen_serializable_test( + context=globals(), + cls=Advancement, + fields=[ + ("parent", "Identifier|None"), + ("display", AdvancementDisplay), + ("requirements", "list[list[str]]"), + ("telemetry", bool), + ], + serialize_deserialize=[ + ( + ( + Identifier("minecraft", "stone"), + AdvancementDisplay( + TextComponent("The End?"), + TextComponent("Go there"), + Slot(SlotData(2, 1)), + AdvancementFrame.GOAL, + Identifier(namespace="minecraft", path="textures/gui/advancements/backgrounds/end.png"), + True, + False, + 0.5, + 0.5, + ), + [["minecraft:stone"]], + True, + ), + bytes( + b"\x01" # Present + + Identifier("minecraft", "stone").serialize() + + b"\x01" # Present + + AdvancementDisplay( + TextComponent("The End?"), + TextComponent("Go there"), + Slot(SlotData(2, 1)), + AdvancementFrame.GOAL, + Identifier(namespace="minecraft", path="textures/gui/advancements/backgrounds/end.png"), + True, + False, + 0.5, + 0.5, + ).serialize() + + b"\x01" # requirements length + + b"\x01" # requirement 1 length + + b"\x0fminecraft:stone" # requirement 1 + + b"\x01" # telemetry + ), + ), + ( + ( + None, + None, + [["minecraft:stone", "minecraft:stone_brick"], ["minecraft:stone"]], + False, + ), + bytes( + b"\x00" # Absent # noqa: ISC003 + + b"\x00" # Absent + + b"\x02" # requirements length + + b"\x02" # requirement 1 length + + b"\x0fminecraft:stone" # requirement 1 + + b"\x15minecraft:stone_brick" # requirement 2 + + b"\x01" # requirement 2 length + + b"\x0fminecraft:stone" # requirement 2 + + b"\x00" # telemetry + ), + ), + ], +) + + +gen_serializable_test( + context=globals(), + cls=AdvancementProgress, + fields=[ + ("criteria", "dict[Identifier, AdvancementCriterion]"), + ], + serialize_deserialize=[ + ( + ( + { + Identifier("minecraft", "stone"): AdvancementCriterion(None), + Identifier("minecraft", "stone_brick"): AdvancementCriterion(1081165320000), + }, + ), + bytes( + b"\x02" # criteria length + + Identifier("minecraft", "stone").serialize() + + AdvancementCriterion(None).serialize() + + b"\x15minecraft:stone_brick" # identifier 2 + + AdvancementCriterion(1081165320000).serialize() + ), + ), + ( + ({},), + b"\x00", # criteria length + ), + ], +) + +gen_serializable_test( + context=globals(), + cls=AdvancementCriterion, + fields=[ + ("date", "int|None"), + ], + serialize_deserialize=[ + ((None,), b"\x00"), # Absent + ((1081165320000,), b"\x01" + struct.pack("!q", 1081165320000)), # Present + ], +) + + +def test_criterion_achieved(): + """Test that the achieved property works correctly.""" + assert AdvancementCriterion(None).achieved is False + assert AdvancementCriterion(1081165320000).achieved is True diff --git a/tests/mcproto/types/test_angle.py b/tests/mcproto/types/test_angle.py new file mode 100644 index 00000000..81de2530 --- /dev/null +++ b/tests/mcproto/types/test_angle.py @@ -0,0 +1,68 @@ +from __future__ import annotations + +import pytest + +from mcproto.types.angle import Angle +from mcproto.types.vec3 import POS_EAST, POS_NORTH, POS_SOUTH, POS_WEST, POS_ZERO, Position +from tests.helpers import gen_serializable_test + +PI = 3.14159265358979323846 +EPSILON = 1e-6 + +gen_serializable_test( + context=globals(), + cls=Angle, + fields=[("angle", int)], + serialize_deserialize=[ + ((0,), b"\x00"), + ((256,), b"\x00"), + ((-1,), b"\xff"), + ((-256,), b"\x00"), + ((2,), b"\x02"), + ((-2,), b"\xfe"), + ], +) + + +@pytest.mark.parametrize( + ("angle", "base", "distance", "expected"), + [ + (Angle(0), POS_ZERO, 1, POS_SOUTH), + (Angle(64), POS_ZERO, 1, POS_WEST), + (Angle(128), POS_ZERO, 1, POS_NORTH), + (Angle(192), POS_ZERO, 1, POS_EAST), + ], +) +def test_in_direction(angle: Angle, base: Position, distance: int, expected: Position): + """Test that the in_direction method moves the base position in the correct direction.""" + assert (angle.in_direction(base, distance) - expected).norm() < EPSILON + + +@pytest.mark.parametrize( + ("base2", "degrees"), + [ + (0, 0), + (64, 90), + (128, 180), + (192, 270), + ], +) +def test_degrees(base2: int, degrees: int): + """Test that the from_degrees and to_degrees methods work correctly.""" + assert Angle.from_degrees(degrees) == Angle(base2) + assert Angle(base2).to_degrees() == degrees + + +@pytest.mark.parametrize( + ("rad", "angle"), + [ + (0, 0), + (PI / 2, 64), + (PI, 128), + (3 * PI / 2, 192), + ], +) +def test_radians(rad: float, angle: int): + """Test that the from_radians and to_radians methods work correctly.""" + assert Angle.from_radians(rad) == Angle(angle) + assert abs(Angle(angle).to_radians() - rad) < EPSILON diff --git a/tests/mcproto/types/test_bitset.py b/tests/mcproto/types/test_bitset.py new file mode 100644 index 00000000..b5af5e35 --- /dev/null +++ b/tests/mcproto/types/test_bitset.py @@ -0,0 +1,232 @@ +import pytest + +from mcproto.buffer import Buffer +from mcproto.types.bitset import Bitset, FixedBitset +from tests.helpers import gen_serializable_test + +gen_serializable_test( + context=globals(), + cls=FixedBitset.of_size(64), + fields=[("data", bytearray)], + serialize_deserialize=[ + ((bytearray(b"\x00\x00\x00\x00\x00\x00\x00\x00"),), b"\x00\x00\x00\x00\x00\x00\x00\x00"), + ((bytearray(b"\xff\xff\xff\xff\xff\xff\xff\xff"),), b"\xff\xff\xff\xff\xff\xff\xff\xff"), + ((bytearray(b"\x55\x55\x55\x55\x55\x55\x55\x55"),), b"\x55\x55\x55\x55\x55\x55\x55\x55"), + ], +) + +gen_serializable_test( + context=globals(), + cls=FixedBitset.of_size(16), + fields=[("data", "list[int]")], + validation_fail=[ + ((bytearray(b"\x00"),), ValueError), + ], +) + +gen_serializable_test( + context=globals(), + cls=Bitset, + fields=[("size", int), ("data", "list[int]")], + serialize_deserialize=[ + ((1, [1]), b"\x01\x00\x00\x00\x00\x00\x00\x00\x01"), + ( + (2, [1, -1]), + b"\x02\x00\x00\x00\x00\x00\x00\x00\x01\xff\xff\xff\xff\xff\xff\xff\xff", + ), + ], + deserialization_fail=[ + (b"\x01", IOError), + ], + validation_fail=[ + ((3, [1]), ValueError), + ], +) + + +def test_fixed_bitset_no_size(): + """Test FixedBitset exceptions with no size.""" + with pytest.raises(ValueError): + FixedBitset.from_int(0) + + with pytest.raises(ValueError): + FixedBitset(bytearray(b"")) + + with pytest.raises(ValueError): + FixedBitset.deserialize(Buffer(b"\x00")) + + +def test_fixed_bitset_indexing(): + """Test indexing and setting values in a FixedBitset.""" + b = FixedBitset.of_size(12).from_int(0) + assert b[0] is False + assert b[12] is False + + b[0] = True + assert b[0] is True + assert b[12] is False + + b[12] = True + assert b[12] is True + assert b[0] is True + + b[0] = False + assert b[0] is False + assert b[12] is True + + +def test_bitset_indexing(): + """Test indexing and setting values in a Bitset.""" + b = Bitset.from_int(0, size=2) + assert b[0] is False + assert b[127] is False + + b[0] = True + assert b[0] is True + + b[127] = True + assert b[127] is True + + b[0] = False + assert b[0] is False + + +def test_fixed_bitset_and(): + """Test bitwise AND operation between FixedBitsets.""" + b1 = FixedBitset.of_size(64).from_int(-1) + b2 = FixedBitset.of_size(64).from_int(0) + + result = b1 & b2 + assert bytes(result) == b"\x00\x00\x00\x00\x00\x00\x00\x00" + + +def test_bitset_and(): + """Test bitwise AND operation between Bitsets.""" + b1 = Bitset(2, [0x0101010101010101, 0x0101010101010100]) + b2 = Bitset(2, [1, 1]) + + result = b1 & b2 + assert result == Bitset(2, [1, 0]) + + +def test_fixed_bitset_or(): + """Test bitwise OR operation between FixedBitsets.""" + b1 = FixedBitset.of_size(8).from_int(-2) + b2 = FixedBitset.of_size(8).from_int(0x01) + + result = b1 | b2 + assert bytes(result) == b"\xff" + + +def test_bitset_or(): + """Test bitwise OR operation between Bitsets.""" + b1 = Bitset(2, [0x0101010101010101, 0x0101010101010100]) + b2 = Bitset(2, [1, 1]) + + result = b1 | b2 + assert bytes(result) == b"\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01" + + +def test_fixed_bitset_xor(): + """Test bitwise XOR operation between FixedBitsets.""" + b1 = FixedBitset.of_size(64)(bytearray(b"\xff\xff\xff\xff\xff\xff\xff\xff")) + b2 = FixedBitset.of_size(64)(bytearray(b"\x00\x00\x00\x00\x00\x00\x00\x00")) + + result = b1 ^ b2 + assert result == FixedBitset.of_size(64).from_int(-1) + + +def test_bitset_xor(): + """Test bitwise XOR operation between Bitsets.""" + b1 = Bitset(2, [0x0101010101010101, 0x0101010101010101]) + b2 = Bitset(2, [0, 0]) + + result = b1 ^ b2 + assert result == Bitset(2, [0x0101010101010101, 0x0101010101010101]) + + +def test_fixed_bitset_invert(): + """Test bitwise inversion operation on FixedBitsets.""" + b = FixedBitset.of_size(64)(bytearray(b"\xff\xff\xff\xff\xff\xff\xff\xff")) + + inverted = ~b + assert inverted == FixedBitset.of_size(64).from_int(0) + + +def test_bitset_invert(): + """Test bitwise inversion operation on Bitsets.""" + b = Bitset(2, [0, 0]) + + inverted = ~b + assert inverted == Bitset(2, [-1, -1]) + + +def test_fixed_bitset_size_undefined(): + """Test that FixedBitset raises ValueError when size is not defined.""" + with pytest.raises(ValueError): + FixedBitset.from_int(0) + + with pytest.raises(ValueError): + FixedBitset(bytearray(b"\x00\x00\x00\x00")) + + with pytest.raises(ValueError): + FixedBitset.deserialize(Buffer(b"\x00")) + + +def test_bitset_len(): + """Test that FixedBitset has the correct length.""" + b = FixedBitset.of_size(64).from_int(0) + assert len(b) == 64 + + b = FixedBitset.of_size(8).from_int(0) + assert len(b) == 8 + + b = Bitset(2, [0, 0]) + assert len(b) == 128 + + +def test_fixed_bitset_operations_length_mismatch(): + """Test that FixedBitset operations raise ValueError when lengths don't match.""" + b1 = FixedBitset.of_size(64).from_int(0) + b2 = FixedBitset.of_size(8).from_int(0) + b3 = "not a bitset" + + with pytest.raises(ValueError): + b1 & b2 # type: ignore + + with pytest.raises(ValueError): + b1 | b2 # type: ignore + + with pytest.raises(ValueError): + b1 ^ b2 # type: ignore + + assert b1 != b3 + + +def test_bitset_operations_length_mismatch(): + """Test that Bitset operations raise ValueError when lengths don't match.""" + b1 = Bitset(2, [0, 0]) + b2 = Bitset.from_int(1) + b3 = "not a bitset" + + with pytest.raises(ValueError): + b1 & b2 # type: ignore + + with pytest.raises(ValueError): + b1 | b2 # type: ignore + + with pytest.raises(ValueError): + b1 ^ b2 # type: ignore + + assert b1 != b3 + + +def test_fixed_bitset_cache(): + """Test that FixedBitset.of_size caches the result.""" + b1 = FixedBitset.of_size(64) + for i in range(1, 64): + b = FixedBitset.of_size(i) + assert b is not b1 + b2 = FixedBitset.of_size(64) + + assert b1 is b2 diff --git a/tests/mcproto/types/test_block_entity.py b/tests/mcproto/types/test_block_entity.py new file mode 100644 index 00000000..a5e41cbc --- /dev/null +++ b/tests/mcproto/types/test_block_entity.py @@ -0,0 +1,25 @@ +from mcproto.types import BlockEntity, CompoundNBT, Position +from mcproto.types.nbt import ByteNBT +from tests.helpers import gen_serializable_test + +gen_serializable_test( + context=globals(), + cls=BlockEntity, + fields=[ + ("position", Position), + ("block_type", int), + ("nbt", CompoundNBT), + ], + serialize_deserialize=[ + ( + (Position(2, 65, 8), 1, CompoundNBT([ByteNBT(1, "test")])), + b"\x28\x00\x41\x01" + CompoundNBT([ByteNBT(1, "test")]).serialize(with_type=False), + ), + ], + validation_fail=[ + ((Position(0, 0, 16), 1, CompoundNBT([ByteNBT(1, "test")])), ValueError), + ((Position(16, 0, 0), 1, CompoundNBT([ByteNBT(1, "test")])), ValueError), + ((Position(-1, 0, 0), 1, CompoundNBT([ByteNBT(1, "test")])), ValueError), + ((Position(0, 0, -1), 1, CompoundNBT([ByteNBT(1, "test")])), ValueError), + ], +) diff --git a/tests/mcproto/types/test_chat.py b/tests/mcproto/types/test_chat.py index 54f16583..a0376f97 100644 --- a/tests/mcproto/types/test_chat.py +++ b/tests/mcproto/types/test_chat.py @@ -2,7 +2,8 @@ import pytest -from mcproto.types.chat import ChatMessage, RawChatMessage, RawChatMessageDict +from mcproto.types.chat import JSONTextComponent, RawTextComponent, RawTextComponentDict, TextComponent +from mcproto.types.nbt import ByteNBT, CompoundNBT, ListNBT, StringNBT from tests.helpers import gen_serializable_test @@ -23,9 +24,9 @@ ), ], ) -def test_as_dict(raw: RawChatMessage, expected_dict: RawChatMessageDict): - """Test converting raw ChatMessage input into dict produces expected dict.""" - chat = ChatMessage(raw) +def test_as_dict(raw: RawTextComponent, expected_dict: RawTextComponentDict): + """Test converting raw TextComponent input into dict produces expected dict.""" + chat = JSONTextComponent(raw) assert chat.as_dict() == expected_dict @@ -44,15 +45,15 @@ def test_as_dict(raw: RawChatMessage, expected_dict: RawChatMessageDict): ), ], ) -def test_equality(raw1: RawChatMessage, raw2: RawChatMessage, expected_result: bool): - """Test comparing ChatMessage instances produces expected equality result.""" - assert (ChatMessage(raw1) == ChatMessage(raw2)) is expected_result +def test_equality(raw1: RawTextComponent, raw2: RawTextComponent, expected_result: bool): + """Test comparing TextComponent instances produces expected equality result.""" + assert (JSONTextComponent(raw1) == JSONTextComponent(raw2)) is expected_result gen_serializable_test( context=globals(), - cls=ChatMessage, - fields=[("raw", RawChatMessage)], + cls=JSONTextComponent, + fields=[("raw", RawTextComponent)], serialize_deserialize=[ ( ("A Minecraft Server",), @@ -76,3 +77,48 @@ def test_equality(raw1: RawChatMessage, raw2: RawChatMessage, expected_result: b (([[]],), TypeError), ], ) + +gen_serializable_test( + context=globals(), + cls=TextComponent, + fields=[("raw", RawTextComponent)], + serialize_deserialize=[ + (({"text": "abc"},), bytes(CompoundNBT([StringNBT("abc", name="text")]).serialize())), + ( + ([{"text": "abc"}, {"text": "def"}],), + bytes( + CompoundNBT( + [ + StringNBT("abc", name="text"), + ListNBT([CompoundNBT([StringNBT("def", name="text")])], name="extra"), + ] + ).serialize() + ), + ), + (("A Minecraft Server",), bytes(CompoundNBT([StringNBT("A Minecraft Server", name="text")]).serialize())), + ( + ([{"text": "abc", "extra": [{"text": "def"}]}, {"text": "ghi"}],), + bytes( + CompoundNBT( + [ + StringNBT("abc", name="text"), + ListNBT( + [ + CompoundNBT([StringNBT("def", name="text")]), + CompoundNBT([StringNBT("ghi", name="text")]), + ], + name="extra", + ), + ] + ).serialize() + ), + ), + ], + deserialization_fail=[ + # Type shitfuckery + (bytes(CompoundNBT([CompoundNBT([ByteNBT(0, "Something")], "text")]).serialize()), TypeError), + (bytes(CompoundNBT([ByteNBT(0, "unknownkey")]).serialize()), KeyError), + (bytes(CompoundNBT([ListNBT([StringNBT("Expected str")], "text")]).serialize()), TypeError), + (bytes(CompoundNBT([StringNBT("Wrong type", "extra")]).serialize()), TypeError), + ], +) diff --git a/tests/mcproto/types/test_identifier.py b/tests/mcproto/types/test_identifier.py new file mode 100644 index 00000000..54ac9243 --- /dev/null +++ b/tests/mcproto/types/test_identifier.py @@ -0,0 +1,54 @@ +from mcproto.types.identifier import Identifier +from mcproto.types.nbt import StringNBT +from tests.helpers import gen_serializable_test + +gen_serializable_test( + context=globals(), + cls=Identifier, + fields=[("namespace", str), ("path", str)], + serialize_deserialize=[ + (("minecraft", "stone"), b"\x0fminecraft:stone"), + (("minecraft", "stone_brick"), b"\x15minecraft:stone_brick"), + (("minecraft:stone_brick_slab", None), b"\x1aminecraft:stone_brick_slab"), + (("stone", None), b"\x0fminecraft:stone"), + ( + ("minecraft.beta", "textures/gui/advancements/backgrounds/end.png"), + b"\x3cminecraft.beta:textures/gui/advancements/backgrounds/end.png", + ), + ], + validation_fail=[ + (("minecr*ft", "stone_brick_slab_top"), ValueError), # Invalid namespace + (("minecraft", "stone_brick_slab_t@p"), ValueError), # Invalid path + (("", "something"), ValueError), # Empty namespace + (("minecraft", ""), ValueError), # Empty path + (("minecraft", "a" * 32767), ValueError), # Too long + ], +) + + +def test__identifier_convert_from_tag(): + """Assert that any # in the namespace is removed.""" + assert Identifier("#minecraft:stone").namespace == "minecraft" + assert Identifier("#minecraft:stone").path == "stone" + assert Identifier("#minecraft:stone").serialize() == b"\x0fminecraft:stone" + + +def test_identifier_hash(): + """Test that the hash function works correctly.""" + assert hash(Identifier("minecraft", "stone")) == hash(Identifier("#stone")) + + +def test_identifier_str(): + """Test that the string conversion works correctly.""" + assert str(Identifier("minecraft", "stone")) == "minecraft:stone" + assert str(Identifier("minecraft", "stone_brick")) == "minecraft:stone_brick" + assert str(Identifier("minecraft:stone_brick_slab", None)) == "minecraft:stone_brick_slab" + assert str(Identifier("stone")) == "minecraft:stone" + + +def test_identifier_to_nbt(): + """Test that the identifier can be converted to an NBT tag.""" + assert Identifier("minecraft", "stone").to_nbt() == StringNBT("minecraft:stone") + assert Identifier("minecraft", "stone_brick").to_nbt("block_held") == StringNBT( + "minecraft:stone_brick", name="block_held" + ) diff --git a/tests/mcproto/types/test_map_icon.py b/tests/mcproto/types/test_map_icon.py new file mode 100644 index 00000000..bb0624e9 --- /dev/null +++ b/tests/mcproto/types/test_map_icon.py @@ -0,0 +1,26 @@ +from mcproto.types import IconType, MapIcon, TextComponent +from tests.helpers import ExcTest, gen_serializable_test + +gen_serializable_test( + context=globals(), + cls=MapIcon, + fields=[ + ("icon_type", IconType), + ("x", int), + ("z", int), + ("direction", int), + ("display_name", TextComponent), + ], + serialize_deserialize=[ + ( + (IconType.PLAYER, 0, 0, 0, TextComponent("test")), + b"\x00\x00\x00\x00\x01" + TextComponent("test").serialize(), + ), + ((IconType.WHITE_BANNER, 127, -128, 15, None), b"\x0a\x7f\x80\x0f\x00"), + ], + validation_fail=[ + ((IconType.PLAYER, 128, 0, 0, None), ExcTest(ValueError, "<= 127")), + ((IconType.PLAYER, 0, -129, 0, None), ExcTest(ValueError, ">= -128")), + ((IconType.PLAYER, 0, 0, 16, None), ExcTest(ValueError, "<= 15")), + ], +) diff --git a/tests/mcproto/types/test_modifier.py b/tests/mcproto/types/test_modifier.py new file mode 100644 index 00000000..79eb6ae9 --- /dev/null +++ b/tests/mcproto/types/test_modifier.py @@ -0,0 +1,24 @@ +import struct + +from mcproto.types import ModifierData, ModifierOperation, UUID +from tests.helpers import gen_serializable_test + +gen_serializable_test( + context=globals(), + cls=ModifierData, + fields=[ + ("uuid", UUID), + ("amount", float), + ("operation", ModifierOperation), + ], + serialize_deserialize=[ + ( + (UUID("f70b4a42c9a04ffb92a31390c128a1b2"), 1.5, ModifierOperation.ADD), + bytes(UUID("f70b4a42c9a04ffb92a31390c128a1b2").serialize() + struct.pack("!d", 1.5) + b"\x00"), + ), + ( + (UUID("f70b4a42c9a04ffb92a31390c128a1b2"), 0.5, ModifierOperation.MULTIPLY_TOTAL), + bytes(UUID("f70b4a42c9a04ffb92a31390c128a1b2").serialize() + struct.pack("!d", 0.5) + b"\x02"), + ), + ], +) diff --git a/tests/mcproto/types/test_nbt.py b/tests/mcproto/types/test_nbt.py index 10bacbb1..fd0c73c4 100644 --- a/tests/mcproto/types/test_nbt.py +++ b/tests/mcproto/types/test_nbt.py @@ -178,10 +178,6 @@ (b"\x05\x00", IOError), (b"\x05", IOError), ], - validation_fail=[ - # Wrong type - (("1.5", "a"), TypeError), - ], ) gen_serializable_test( @@ -230,10 +226,6 @@ # Negative length (b"\x07\x00\x01a\xff\xff\xff\xff", ValueError), ], - validation_fail=[ - # Wrong type - ((1, "a"), TypeError), - ], ) gen_serializable_test( @@ -452,7 +444,7 @@ def test_intarray_negative_length(): def test_nbt_helloworld(): """Test serialization/deserialization of a simple NBT tag. - Source data: https://wiki.vg/NBT#Example. + Source data: . """ data = bytearray.fromhex("0a000b68656c6c6f20776f726c640800046e616d65000942616e616e72616d6100") buffer = Buffer(data) @@ -471,7 +463,7 @@ def test_nbt_bigfile(): """Test serialization/deserialization of a big NBT tag. Slighly modified from the source data to also include a IntArrayNBT and a LongArrayNBT. - Source data: https://wiki.vg/NBT#Example. + Source data: . """ data = "0a00054c6576656c0400086c6f6e67546573747fffffffffffffff02000973686f7274546573747fff08000a737472696e6754657374002948454c4c4f20574f524c4420544849532049532041205445535420535452494e4720c385c384c39621050009666c6f6174546573743eff1832030007696e74546573747fffffff0a00146e657374656420636f6d706f756e6420746573740a000368616d0800046e616d65000648616d70757305000576616c75653f400000000a00036567670800046e616d6500074567676265727405000576616c75653f00000000000c000f6c6973745465737420286c6f6e672900000005000000000000000b000000000000000c000000000000000d000000000000000e7fffffffffffffff0b000e6c697374546573742028696e7429000000047fffffff7ffffffe7ffffffd7ffffffc0900136c697374546573742028636f6d706f756e64290a000000020800046e616d65000f436f6d706f756e642074616720233004000a637265617465642d6f6e000001265237d58d000800046e616d65000f436f6d706f756e642074616720233104000a637265617465642d6f6e000001265237d58d0001000862797465546573747f07006562797465417272617954657374202874686520666972737420313030302076616c756573206f6620286e2a6e2a3235352b6e2a3729253130302c207374617274696e672077697468206e3d302028302c2036322c2033342c2031362c20382c202e2e2e2929000003e8003e2210080a162c4c12462004564e505c0e2e5828024a3830323e54103a0a482c1a12142036561c502a0e60585a02183862320c54423a3c485e1a44145236241c1e2a4060265a34180662000c2242083c165e4c44465204244e1e5c402e2628344a0630003e2210080a162c4c12462004564e505c0e2e5828024a3830323e54103a0a482c1a12142036561c502a0e60585a02183862320c54423a3c485e1a44145236241c1e2a4060265a34180662000c2242083c165e4c44465204244e1e5c402e2628344a0630003e2210080a162c4c12462004564e505c0e2e5828024a3830323e54103a0a482c1a12142036561c502a0e60585a02183862320c54423a3c485e1a44145236241c1e2a4060265a34180662000c2242083c165e4c44465204244e1e5c402e2628344a0630003e2210080a162c4c12462004564e505c0e2e5828024a3830323e54103a0a482c1a12142036561c502a0e60585a02183862320c54423a3c485e1a44145236241c1e2a4060265a34180662000c2242083c165e4c44465204244e1e5c402e2628344a0630003e2210080a162c4c12462004564e505c0e2e5828024a3830323e54103a0a482c1a12142036561c502a0e60585a02183862320c54423a3c485e1a44145236241c1e2a4060265a34180662000c2242083c165e4c44465204244e1e5c402e2628344a0630003e2210080a162c4c12462004564e505c0e2e5828024a3830323e54103a0a482c1a12142036561c502a0e60585a02183862320c54423a3c485e1a44145236241c1e2a4060265a34180662000c2242083c165e4c44465204244e1e5c402e2628344a0630003e2210080a162c4c12462004564e505c0e2e5828024a3830323e54103a0a482c1a12142036561c502a0e60585a02183862320c54423a3c485e1a44145236241c1e2a4060265a34180662000c2242083c165e4c44465204244e1e5c402e2628344a0630003e2210080a162c4c12462004564e505c0e2e5828024a3830323e54103a0a482c1a12142036561c502a0e60585a02183862320c54423a3c485e1a44145236241c1e2a4060265a34180662000c2242083c165e4c44465204244e1e5c402e2628344a0630003e2210080a162c4c12462004564e505c0e2e5828024a3830323e54103a0a482c1a12142036561c502a0e60585a02183862320c54423a3c485e1a44145236241c1e2a4060265a34180662000c2242083c165e4c44465204244e1e5c402e2628344a0630003e2210080a162c4c12462004564e505c0e2e5828024a3830323e54103a0a482c1a12142036561c502a0e60585a02183862320c54423a3c485e1a44145236241c1e2a4060265a34180662000c2242083c165e4c44465204244e1e5c402e2628344a063005000a646f75626c65546573743efc000000" # noqa: E501 data = bytes.fromhex(data) @@ -839,3 +831,60 @@ def test_wrong_type(buffer_content: str, tag_type: type[NBTag]): buffer = Buffer(bytearray.fromhex(buffer_content)) with pytest.raises(TypeError): tag_type.read_from(buffer, with_name=False) + + +def test_nbt_sets(): + """Test that NBTags behave correctly in dict and sets to be used as keys.""" + tag1 = ByteNBT(0, "tag") + tag2 = ByteNBT(1, "tag2") + tag3 = ByteNBT(0, "tag") + tag4 = ByteNBT(1, "tag") + + byte_set: set[NBTag] = {tag1, tag2} + assert tag1 in byte_set + assert tag2 in byte_set + + byte_set.add(tag3) + assert tag3 in byte_set + assert len(byte_set) == 2 + + byte_set.add(tag4) + assert tag4 in byte_set + assert len(byte_set) == 3 + + byte_dict: dict[NBTag, int] = {tag1: 0, tag2: 1} + assert tag1 in byte_dict + assert tag2 in byte_dict + + byte_dict[tag3] = 2 + assert tag3 in byte_dict + assert len(byte_dict) == 2 + assert byte_dict[tag1] == 2 + assert byte_dict[tag3] == 2 + + +def test_nbt_compound_set(): + """Test that CompoundNBT behave correctly in dict and sets to be used as keys.""" + tag1 = ByteNBT(0, "tag") + tag2 = ByteNBT(1, "tag2") + tag3 = ByteNBT(0, "tag") + tag4 = ByteNBT(1, "tag4") + + compound1 = CompoundNBT([tag1, tag2], "compound") + compound2 = CompoundNBT([tag3, tag4], "compound2") + compound3 = CompoundNBT([tag3, tag2], "compound") + + compound_set: set[NBTag] = {compound1, compound2} + assert compound1 in compound_set + assert compound2 in compound_set + assert len(compound_set) == 2 + + assert compound3 in compound_set + assert len(compound_set) == 2 + + compound_set.add(compound3) # Should hash to the same value as compound1 + assert len(compound_set) == 2 + + compound4 = CompoundNBT([tag2, tag1], "compound") + assert compound4 in compound_set + assert len(compound_set) == 2 diff --git a/tests/mcproto/types/test_particle_data.py b/tests/mcproto/types/test_particle_data.py new file mode 100644 index 00000000..948274a6 --- /dev/null +++ b/tests/mcproto/types/test_particle_data.py @@ -0,0 +1,190 @@ +import struct + +from mcproto.buffer import Buffer +from mcproto.types import ParticleData, Position, Slot, SlotData +from tests.mcproto.utils.test_serializable import gen_serializable_test + +# WITH_BLOCK_STATE +gen_serializable_test( + context=globals(), + cls=ParticleData, + fields=[ + ("particle_id", int), + ("block_state", int), + ], + serialize_deserialize=[ + ((1, 2), b"\x01\x02"), # minecraft:block + ((2, 3), b"\x02\x03"), # minecraft:block_marker + ((28, 4), b"\x1c\x04"), # minecraft:falling_dust + ((105, 5), b"\x69\x05"), # minecraft:dust_pillar + ], + validation_fail=[ + ((1, None), ValueError), # Missing block state + ], + test_suffix="BlockState", +) + +# WITH_RGB_SCALE +gen_serializable_test( + context=globals(), + cls=ParticleData, + fields=[ + ("particle_id", int), + ("red", float), + ("green", float), + ("blue", float), + ], + serialize_deserialize=[ + ((13, 0.5, 0.5, 0.625), b"\x0d" + struct.pack("!fff", 0.5, 0.5, 0.625)), # minecraft:dust + ], + validation_fail=[ + ((13, None, 0.5, 0.75), ValueError), # Missing red + ((13, 1.0, None, 0.75), ValueError), # Missing green + ((13, 1.0, 0.5, None), ValueError), # Missing blue + ], + test_suffix="RGBScale", +) + +# WITH_RGB_TRANSITION +gen_serializable_test( + context=globals(), + cls=ParticleData, + fields=[ + ("particle_id", int), + ("from_red", float), + ("from_green", float), + ("from_blue", float), + ("scale", float), + ("to_red", float), + ("to_green", float), + ("to_blue", float), + ], + serialize_deserialize=[ + ( + (14, 1.0, 0.5, 0.75, 2.0, 0.5, 0.0, 0.625), + b"\x0e" + struct.pack("!fffffff", 1.0, 0.5, 0.75, 2.0, 0.5, 0.0, 0.625), + ), # minecraft:dust_color_transition + ], + validation_fail=[ + ((14, None, 0.5, 0.75, 2.0, 0.5, 0.0, 0.625), ValueError), # Missing from_red + ((14, 1.0, None, 0.75, 2.0, 0.5, 0.0, 0.625), ValueError), # Missing from_green + ((14, 1.0, 0.5, None, 2.0, 0.5, 0.0, 0.625), ValueError), # Missing from_blue + ((14, 1.0, 0.5, 0.75, None, 0.5, 0.0, 0.625), ValueError), # Missing scale + ((14, 1.0, 0.5, 0.75, 2.0, None, 0.0, 0.625), ValueError), # Missing to_red + ((14, 1.0, 0.5, 0.75, 2.0, 0.5, None, 0.625), ValueError), # Missing to_green + ((14, 1.0, 0.5, 0.75, 2.0, 0.5, 0.0, None), ValueError), # Missing to_blue + ], + test_suffix="RGBTransition", +) + +# WITH_ROLL +gen_serializable_test( + context=globals(), + cls=ParticleData, + fields=[ + ("particle_id", int), + ("roll", float), + ], + serialize_deserialize=[ + ((35, 1.0), b"\x23" + struct.pack("!f", 1.0)), # minecraft:sculk_charge + ], + validation_fail=[ + ((35, None), ValueError), # Missing roll + ], + test_suffix="Roll", +) + +# WITH_ITEM +gen_serializable_test( + context=globals(), + cls=ParticleData, + fields=[ + ("particle_id", int), + ("item", Slot), + ], + serialize_deserialize=[ + ( + (44, Slot(SlotData(23, 13))), + b"\x2c" + Slot(SlotData(23, 13)).serialize(), + ), + ], + validation_fail=[ + ((44, None), ValueError), # Missing item + ], + test_suffix="Item", +) + +# WITH_VIBRATION +gen_serializable_test( + context=globals(), + cls=ParticleData, + fields=[ + ("particle_id", int), + ("source_type", int), + ("block_position", Position), + ("entity_id", int), + ("entity_eye_height", float), + ("tick", int), + ], + serialize_deserialize=[ + ( + (45, 0, Position(0, 0, 0), None, None, 10), + b"\x2d\x00" + Position(0, 0, 0).serialize() + b"\x0a", + ), # minecraft:vibration with block_position + ( + (45, 1, None, 3, 1.0625, 10), + b"\x2d\x01\x03" + struct.pack("!f", 1.0625) + b"\x0a", + ), # minecraft:vibration with entity_id and entity_eye_height + ], + validation_fail=[ + ((45, None, Position(0, 0, 0), None, None, 1), ValueError), # Missing source_type + ((45, 0, None, None, None, 1), ValueError), # Missing block_position + ((45, 1, None, None, None, 1), ValueError), # Missing entity_id + ((45, 1, None, 1, None, 1), ValueError), # Missing entity_eye_height + ((45, 1, None, 1, 1.8, None), ValueError), # Missing tick + ], + test_suffix="Vibration", +) + +# WITH_DELAY +gen_serializable_test( + context=globals(), + cls=ParticleData, + fields=[ + ("particle_id", int), + ("delay", int), + ], + serialize_deserialize=[ + ((99, 1), b"\x63\x01"), # minecraft:shriek + ], + validation_fail=[ + ((99, None), ValueError), # Missing delay + ], + test_suffix="Delay", +) + +# WITH_COLOR +gen_serializable_test( + context=globals(), + cls=ParticleData, + fields=[ + ("particle_id", int), + ("color", int), + ], + serialize_deserialize=[ + ((20, 0xCC00FF66), b"\x14\xcc\x00\xff\x66"), # minecraft:entity_effect + ], + validation_fail=[ + ((20, None), ValueError), # Missing color + ], + test_suffix="Color", +) + + +def test_particle_data_without_id(): + """Test ParticleData without particle_id during serialization.""" + particle_data = ParticleData(particle_id=4) + assert particle_data.particle_id == 4 + buf = Buffer() + particle_data.serialize_to(buf, with_id=False) + assert bytes(buf) == b"" diff --git a/tests/mcproto/types/test_quaternion.py b/tests/mcproto/types/test_quaternion.py new file mode 100644 index 00000000..37943f71 --- /dev/null +++ b/tests/mcproto/types/test_quaternion.py @@ -0,0 +1,126 @@ +from __future__ import annotations + +import math +import struct +from typing import cast + +import pytest + +from mcproto.types.quaternion import Quaternion +from tests.helpers import gen_serializable_test + +gen_serializable_test( + context=globals(), + cls=Quaternion, + fields=[("x", float), ("y", float), ("z", float), ("w", float)], + serialize_deserialize=[ + ((0.0, 0.0, 0.0, 0.0), struct.pack(">ffff", 0.0, 0.0, 0.0, 0.0)), + ((-1.0, -1.0, -1.0, -1.0), struct.pack(">ffff", -1.0, -1.0, -1.0, -1.0)), + ((1.0, 2.0, 3.0, 4.0), struct.pack(">ffff", 1.0, 2.0, 3.0, 4.0)), + ((1.5, 2.5, 3.5, 4.5), struct.pack(">ffff", 1.5, 2.5, 3.5, 4.5)), + ], + validation_fail=[ + # Invalid values + ((1.0, 2.0, "3.0", 4.0), TypeError), + ((float("nan"), 2.0, 3.0, 4.0), ValueError), + ((1.0, float("inf"), 3.0, 4.0), ValueError), + ((1.0, 2.0, -float("inf"), 4.0), ValueError), + ], +) + + +def test_quaternion_addition(): + """Test that two Quaternion objects can be added together (resulting in a new Quaternion object).""" + v1 = Quaternion(x=1.0, y=2.0, z=3.0, w=4.0) + v2 = Quaternion(x=4.5, y=5.25, z=6.125, w=7.0625) + v3 = v1 + v2 + assert type(v3) == Quaternion + assert v3.x == 5.5 + assert v3.y == 7.25 + assert v3.z == 9.125 + assert v3.w == 11.0625 + + +def test_quaternion_subtraction(): + """Test that two Quaternion objects can be subtracted (resulting in a new Quaternion object).""" + v1 = Quaternion(x=1.0, y=2.0, z=3.0, w=4.0) + v2 = Quaternion(x=4.5, y=5.25, z=6.125, w=7.0625) + v3 = v2 - v1 + assert type(v3) == Quaternion + assert v3.x == 3.5 + assert v3.y == 3.25 + assert v3.z == 3.125 + assert v3.w == 3.0625 + + +def test_quaternion_negative(): + """Test that a Quaternion object can be negated.""" + v1 = Quaternion(x=1.0, y=2.5, z=3.0, w=4.5) + v2 = -v1 + assert type(v2) == Quaternion + assert v2.x == -1.0 + assert v2.y == -2.5 + assert v2.z == -3.0 + assert v2.w == -4.5 + + +def test_quaternion_multiplication_int(): + """Test that a Quaternion object can be multiplied by an integer.""" + v1 = Quaternion(x=1.0, y=2.25, z=3.0, w=4.5) + v2 = v1 * 2 + assert v2.x == 2.0 + assert v2.y == 4.5 + assert v2.z == 6.0 + assert v2.w == 9.0 + + +def test_quaternion_multiplication_float(): + """Test that a Quaternion object can be multiplied by a float.""" + v1 = Quaternion(x=2.0, y=4.5, z=6.0, w=9.0) + v2 = v1 * 1.5 + assert type(v2) == Quaternion + assert v2.x == 3.0 + assert v2.y == 6.75 + assert v2.z == 9.0 + assert v2.w == 13.5 + + +def test_quaternion_norm_squared(): + """Test that the squared norm of a Quaternion object can be calculated.""" + v = Quaternion(x=3.0, y=4.0, z=5.0, w=6.0) + assert v.norm_squared() == 86.0 + + +def test_quaternion_norm(): + """Test that the norm of a Quaternion object can be calculated.""" + v = Quaternion(x=3.0, y=4.0, z=5.0, w=6.0) + assert (v.norm() - 86.0**0.5) < 1e-6 + + +@pytest.mark.parametrize( + ("x", "y", "z", "w", "expected"), + [ + (0, 0, 0, 0, ZeroDivisionError), + (1, 0, 0, 0, Quaternion(x=1, y=0, z=0, w=0)), + (0, 1, 0, 0, Quaternion(x=0, y=1, z=0, w=0)), + (0, 0, 1, 0, Quaternion(x=0, y=0, z=1, w=0)), + (0, 0, 0, 1, Quaternion(x=0, y=0, z=0, w=1)), + (1, 1, 1, 1, Quaternion(x=1, y=1, z=1, w=1) / math.sqrt(4)), + (-1, -1, -1, -1, Quaternion(x=-1, y=-1, z=-1, w=-1) / math.sqrt(4)), + ], +) +def test_quaternion_normalize(x: float, y: float, z: float, w: float, expected: Quaternion | type): + """Test that a Quaternion object can be normalized.""" + v = Quaternion(x=x, y=y, z=z, w=w) + if isinstance(expected, type): + expected = cast("type[Exception]", expected) + with pytest.raises(expected): + v.normalize() + else: + assert (v.normalize() - expected).norm() < 1e-6 + + +def test_quaternion_tuple(): + """Test that a Quaternion object can be converted to a tuple.""" + v = Quaternion(x=1.0, y=2.0, z=3.0, w=4.0) + assert v.to_tuple() == (1.0, 2.0, 3.0, 4.0) diff --git a/tests/mcproto/types/test_recipe.py b/tests/mcproto/types/test_recipe.py new file mode 100644 index 00000000..9bf36419 --- /dev/null +++ b/tests/mcproto/types/test_recipe.py @@ -0,0 +1,241 @@ +import struct + +from mcproto.types import ( + ArmorDyeRecipe, + Identifier, + Ingredient, + ShapedRecipe, + ShapelessRecipe, + Slot, + SlotData, + SmeltingRecipe, + SmithingTransformRecipe, + SmithingTrimRecipe, + StoneCuttingRecipe, +) +from tests.helpers import gen_serializable_test + +gen_serializable_test( + context=globals(), + cls=Ingredient, + fields=[("count", "int"), ("items", "set[Slot]")], + serialize_deserialize=[ + ((1, {Slot(SlotData(1, 1))}), b"\x01\x01" + Slot(SlotData(1, 1)).serialize()), + ], + validation_fail=[((1, {Slot(SlotData(1, 2))}), ValueError)], +) + + +def test_ingredient_set(): + """Test that the set of items gets serialized correctly.""" + ing = Ingredient(1, {Slot(SlotData(1, 1)), Slot(SlotData(2, 1))}) + + opt1 = b"\x01\x02" + Slot(SlotData(1, 1)).serialize() + Slot(SlotData(2, 1)).serialize() + opt2 = b"\x01\x02" + Slot(SlotData(2, 1)).serialize() + Slot(SlotData(1, 1)).serialize() + + assert ing.serialize() == opt1 or ing.serialize() == opt2 # Set order is not guaranteed + + +gen_serializable_test( + context=globals(), + cls=ShapedRecipe, + fields=[ + ("recipe_id", Identifier), + ("group", str), + ("category", int), + ("width", int), + ("height", int), + ("ingredients", "list[Ingredient]"), + ("result", Slot), + ("show_toast", bool), + ], + serialize_deserialize=[ + ( + ( + Identifier("minecraft", "test"), + "test_group", + 1, + 2, + 2, + [Ingredient(1, {Slot(SlotData(1, 1))})], + Slot(SlotData(1, 1)), + True, + ), + bytes( + Identifier("minecraft", "test").serialize() + + b"\x00" # id + + b"\x0atest_group\x01\x02\x02\x01" + + Ingredient(1, {Slot(SlotData(1, 1))}).serialize() + + Slot(SlotData(1, 1)).serialize() + + b"\x01" + ), + ), + ], +) + +gen_serializable_test( + context=globals(), + cls=ShapelessRecipe, + fields=[ + ("recipe_id", Identifier), + ("group", str), + ("category", int), + ("ingredients", "list[Ingredient]"), + ("result", Slot), + ], + serialize_deserialize=[ + ( + ( + Identifier("minecraft", "test"), + "test_group", + 6, + [Ingredient(3, {Slot(SlotData(2, 1))})], + Slot(SlotData(4, 5)), + ), + bytes( + Identifier("minecraft", "test").serialize() + + b"\x01" # id + + b"\x0atest_group" + + b"\x06\x01" # category + count + + Ingredient(3, {Slot(SlotData(2, 1))}).serialize() + + Slot(SlotData(4, 5)).serialize() + ), + ), + ], +) + +gen_serializable_test( + context=globals(), + cls=ArmorDyeRecipe, + fields=[ + ("recipe_id", Identifier), + ("category", int), + ], + serialize_deserialize=[((Identifier("test"), 1), bytes(Identifier("test").serialize() + b"\x02\01"))], +) + + +gen_serializable_test( + context=globals(), + cls=SmeltingRecipe, + fields=[ + ("recipe_id", Identifier), + ("group", str), + ("category", int), + ("ingredient", Ingredient), + ("result", Slot), + ("experience", float), + ("cooking_time", int), + ], + serialize_deserialize=[ + ( + ( + Identifier("test"), + "group", + 2, + Ingredient(3, {Slot(SlotData(4, 1))}), + Slot(SlotData(5, 6)), + 7.0, + 8, + ), + bytes( + Identifier("test").serialize() + + b"\x0f" # id + + b"\x05group\x02" + + Ingredient(3, {Slot(SlotData(4, 1))}).serialize() + + Slot(SlotData(5, 6)).serialize() + + struct.pack("!f", 7.0) + + b"\x08" + ), + ), + ], +) + +gen_serializable_test( + context=globals(), + cls=StoneCuttingRecipe, + fields=[ + ("recipe_id", Identifier), + ("group", str), + ("ingredient", Ingredient), + ("result", Slot), + ], + serialize_deserialize=[ + ( + ( + Identifier("test"), + "group", + Ingredient(3, {Slot(SlotData(4, 1))}), + Slot(SlotData(5, 6)), + ), + bytes( + Identifier("test").serialize() + + b"\x13" # id + + b"\x05group" + + Ingredient(3, {Slot(SlotData(4, 1))}).serialize() + + Slot(SlotData(5, 6)).serialize() + ), + ), + ], +) + + +gen_serializable_test( + context=globals(), + cls=SmithingTrimRecipe, + fields=[ + ("recipe_id", Identifier), + ("template", Ingredient), + ("base", Ingredient), + ("addition", Ingredient), + ], + serialize_deserialize=[ + ( + ( + Identifier("test"), + Ingredient(3, {Slot(SlotData(4, 1))}), + Ingredient(5, {Slot(SlotData(6, 1))}), + Ingredient(7, {Slot(SlotData(8, 1))}), + ), + bytes( + Identifier("test").serialize() + + b"\x15" # id + + Ingredient(3, {Slot(SlotData(4, 1))}).serialize() + + Ingredient(5, {Slot(SlotData(6, 1))}).serialize() + + Ingredient(7, {Slot(SlotData(8, 1))}).serialize() + ), + ), + ], +) + + +gen_serializable_test( + context=globals(), + cls=SmithingTransformRecipe, + fields=[ + ("recipe_id", Identifier), + ("template", Ingredient), + ("base", Ingredient), + ("addition", Ingredient), + ("result", Slot), + ], + serialize_deserialize=[ + ( + ( + Identifier("test"), + Ingredient(3, {Slot(SlotData(4, 1))}), + Ingredient(5, {Slot(SlotData(6, 1))}), + Ingredient(7, {Slot(SlotData(8, 1))}), + Slot(SlotData(9, 10)), + ), + bytes( + Identifier("test").serialize() + + b"\x14" # id + + Ingredient(3, {Slot(SlotData(4, 1))}).serialize() + + Ingredient(5, {Slot(SlotData(6, 1))}).serialize() + + Ingredient(7, {Slot(SlotData(8, 1))}).serialize() + + Slot(SlotData(9, 10)).serialize() + ), + ), + ], +) diff --git a/tests/mcproto/types/test_registry_tag.py b/tests/mcproto/types/test_registry_tag.py new file mode 100644 index 00000000..e8205b75 --- /dev/null +++ b/tests/mcproto/types/test_registry_tag.py @@ -0,0 +1,20 @@ +from mcproto.types import Identifier, RegistryTag +from tests.helpers import gen_serializable_test + +gen_serializable_test( + context=globals(), + cls=RegistryTag, + fields=[ + ("name", Identifier), + ("values", "list[int]"), + ], + serialize_deserialize=[ + ((Identifier("wool"), [1, 2, 3]), bytes(Identifier("wool").serialize() + b"\x03\x01\x02\x03")), + ((Identifier("block"), [1, 2, 3, 4]), bytes(Identifier("block").serialize() + b"\x04\x01\x02\x03\x04")), + ], +) + + +def test_registry_tag_str(): + """Test that registry tags can be printed as strings correctly.""" + assert str(RegistryTag(Identifier("stone"), [1, 2, 3])) == "#minecraft:stone" diff --git a/tests/mcproto/types/test_slot.py b/tests/mcproto/types/test_slot.py new file mode 100644 index 00000000..b65d4873 --- /dev/null +++ b/tests/mcproto/types/test_slot.py @@ -0,0 +1,34 @@ +from __future__ import annotations + +from mcproto.types.nbt import ByteNBT, CompoundNBT, IntNBT +from mcproto.types.slot import Slot, SlotData +from tests.helpers import gen_serializable_test + +gen_serializable_test( + context=globals(), + cls=Slot, + fields=[("data", "SlotData|None")], + serialize_deserialize=[ + ((None,), b"\x00"), + ((SlotData(1, 1, None),), b"\x01\x01\x01\x00"), # EndNBT() is automatically added + ( + (SlotData(2, 3, CompoundNBT([IntNBT(4, "int_nbt"), ByteNBT(5, "byte_nbt")])),), + b"\x01\x02\x03" + CompoundNBT([IntNBT(4, "int_nbt"), ByteNBT(5, "byte_nbt")]).serialize(), + ), + ], +) + + +def test_slot_hash(): + """Test that the slot hash is consistent.""" + s1 = Slot(SlotData(1, 1, None)) + s2 = Slot(SlotData(1, 1, None)) + + assert hash(s1) == hash(s2) + assert s1 == s2 + + s1 = Slot(SlotData(1, 1, CompoundNBT([ByteNBT(1, "byte_nbt")]))) + s2 = Slot(SlotData(1, 1, CompoundNBT([ByteNBT(1, "byte_nbt")]))) + + assert hash(s1) == hash(s2) + assert s1 == s2 diff --git a/tests/mcproto/types/test_trade.py b/tests/mcproto/types/test_trade.py new file mode 100644 index 00000000..d7db8d06 --- /dev/null +++ b/tests/mcproto/types/test_trade.py @@ -0,0 +1,43 @@ +import struct + +from mcproto.types import Slot, SlotData, Trade +from tests.helpers import gen_serializable_test + +gen_serializable_test( + context=globals(), + cls=Trade, + fields=[ + ("input_item", Slot), + ("input_item2", Slot), + ("output_item", Slot), + ("trade_disabled", bool), + ("trade_uses", int), + ("max_trade_uses", int), + ("experience", int), + ("special_price", int), + ("price_multiplier", float), + ("demand", int), + ], + serialize_deserialize=[ + ( + ( + Slot(SlotData(6, 64)), + Slot(None), + Slot(SlotData(1, 1)), + False, + 1, + 12, + 16, + 2, + 1.5, + 3, + ), + bytes(Slot(SlotData(6, 64)).serialize()) + + bytes(Slot(None).serialize()) + + bytes(Slot(SlotData(1, 1)).serialize()) + + b"\x00\x01\x0c\x10\x02" + + struct.pack("!f", 1.5) + + b"\x03", + ) + ], +) diff --git a/tests/mcproto/types/test_vec3.py b/tests/mcproto/types/test_vec3.py new file mode 100644 index 00000000..7e17045e --- /dev/null +++ b/tests/mcproto/types/test_vec3.py @@ -0,0 +1,240 @@ +from __future__ import annotations + +import math +import struct +from typing import cast + +import pytest + +from mcproto.buffer import Buffer +from mcproto.types.vec3 import Position, Vec3 +from tests.helpers import gen_serializable_test + +gen_serializable_test( + context=globals(), + cls=Position, + fields=[("x", int), ("y", int), ("z", int)], + serialize_deserialize=[ + ((0, 0, 0), b"\x00\x00\x00\x00\x00\x00\x00\x00"), + ((-1, -1, -1), b"\xff\xff\xff\xff\xff\xff\xff\xff"), + # from https://wiki.vg/Protocol#Position + ( + (18357644, 831, -20882616), + bytes([0b01000110, 0b00000111, 0b01100011, 0b00101100, 0b00010101, 0b10110100, 0b10000011, 0b00111111]), + ), + ], + validation_fail=[ + # X out of bounds + ((1 << 25, 0, 0), ValueError), + ((-(1 << 25) - 1, 0, 0), ValueError), + # Y out of bounds + ((0, 1 << 11, 0), ValueError), + ((0, -(1 << 11) - 1, 0), ValueError), + # Z out of bounds + ((0, 0, 1 << 25), ValueError), + ((0, 0, -(1 << 25) - 1), ValueError), + ], +) + +gen_serializable_test( + context=globals(), + cls=Vec3, + fields=[("x", float), ("y", float), ("z", float)], + serialize_deserialize=[ + ((0.0, 0.0, 0.0), struct.pack(">fff", 0.0, 0.0, 0.0)), + ((-1.0, -1.0, -1.0), struct.pack(">fff", -1.0, -1.0, -1.0)), + ((1.0, 2.0, 3.0), struct.pack(">fff", 1.0, 2.0, 3.0)), + ((1.5, 2.5, 3.5), struct.pack(">fff", 1.5, 2.5, 3.5)), + ], + validation_fail=[ + # Invalid values + ((1.0, 2.0, "3.0"), TypeError), + ((float("nan"), 2.0, 3.0), ValueError), + ((1.0, float("inf"), 3.0), ValueError), + ((1.0, 2.0, -float("inf")), ValueError), + ], +) + + +def test_position_addition(): + """Test that two Position objects can be added together (resuling in a new Position object).""" + p1 = Position(x=1, y=2, z=3) + p2 = Position(x=4, y=5, z=6) + p3 = p1 + p2 + assert type(p3) == Position + assert p3.x == 5 + assert p3.y == 7 + assert p3.z == 9 + + +def test_position_subtraction(): + """Test that two Position objects can be subtracted (resuling in a new Position object).""" + p1 = Position(x=1, y=2, z=3) + p2 = Position(x=2, y=4, z=6) + p3 = p2 - p1 + assert type(p3) == Position + assert p3.x == 1 + assert p3.y == 2 + assert p3.z == 3 + + +def test_position_negative(): + """Test that a Position object can be negated.""" + p1 = Position(x=1, y=2, z=3) + p2 = -p1 + assert type(p2) == Position + assert p2.x == -1 + assert p2.y == -2 + assert p2.z == -3 + + +def test_position_multiplication_int(): + """Test that a Position object can be multiplied by an integer.""" + p1 = Position(x=1, y=2, z=3) + p2 = p1 * 2 + assert p2.x == 2 + assert p2.y == 4 + assert p2.z == 6 + + +def test_position_multiplication_float(): + """Test that a Position object can be multiplied by a float.""" + p1 = Position(x=2, y=4, z=6) + p2 = p1 * 1.5 + assert type(p2) == Position + assert p2.x == 3 + assert p2.y == 6 + assert p2.z == 9 + + +def test_vec3_to_position(): + """Test that a Vec3 object can be converted to a Position object.""" + v = Vec3(x=1.5, y=2.5, z=3.5) + p = v.to_position() + assert type(p) == Position + assert p.x == 1 + assert p.y == 2 + assert p.z == 3 + + +def test_position_to_vec3(): + """Test that a Position object can be converted to a Vec3 object.""" + p = Position(x=1, y=2, z=3) + v = p.to_vec3() + assert type(v) == Vec3 + assert v.x == 1.0 + assert v.y == 2.0 + assert v.z == 3.0 + + +def test_position_to_tuple(): + """Test that a Position object can be converted to a tuple.""" + p = Position(x=1, y=2, z=3) + t = p.to_tuple() + assert type(t) is tuple + assert t == (1, 2, 3) + + +def test_vec3_addition(): + """Test that two Vec3 objects can be added together (resuling in a new Vec3 object).""" + v1 = Vec3(x=1.0, y=2.0, z=3.0) + v2 = Vec3(x=4.5, y=5.25, z=6.125) + v3 = v1 + v2 + assert type(v3) == Vec3 + assert v3.x == 5.5 + assert v3.y == 7.25 + assert v3.z == 9.125 + + +def test_vec3_subtraction(): + """Test that two Vec3 objects can be subtracted (resuling in a new Vec3 object).""" + v1 = Vec3(x=1.0, y=2.0, z=3.0) + v2 = Vec3(x=4.5, y=5.25, z=6.125) + v3 = v2 - v1 + assert type(v3) == Vec3 + assert v3.x == 3.5 + assert v3.y == 3.25 + assert v3.z == 3.125 + + +def test_vec3_negative(): + """Test that a Vec3 object can be negated.""" + v1 = Vec3(x=1.0, y=2.5, z=3.0) + v2 = -v1 + assert type(v2) == Vec3 + assert v2.x == -1.0 + assert v2.y == -2.5 + assert v2.z == -3.0 + + +def test_vec3_multiplication_int(): + """Test that a Vec3 object can be multiplied by an integer.""" + v1 = Vec3(x=1.0, y=2.25, z=3.0) + v2 = v1 * 2 + assert v2.x == 2.0 + assert v2.y == 4.5 + assert v2.z == 6.0 + + +def test_vec3_multiplication_float(): + """Test that a Vec3 object can be multiplied by a float.""" + v1 = Vec3(x=2.0, y=4.5, z=6.0) + v2 = v1 * 1.5 + assert type(v2) == Vec3 + assert v2.x == 3.0 + assert v2.y == 6.75 + assert v2.z == 9.0 + + +def test_vec3_norm_squared(): + """Test that the squared norm of a Vec3 object can be calculated.""" + v = Vec3(x=3.0, y=4.0, z=5.0) + assert v.norm_squared() == 50.0 + + +def test_vec3_norm(): + """Test that the norm of a Vec3 object can be calculated.""" + v = Vec3(x=3.0, y=4.0, z=5.0) + assert (v.norm() - 50.0**0.5) < 1e-6 + + +@pytest.mark.parametrize( + ("x", "y", "z", "expected"), + [ + (0, 0, 0, ZeroDivisionError), + (1, 0, 0, Vec3(x=1, y=0, z=0)), + (0, 1, 0, Vec3(x=0, y=1, z=0)), + (0, 0, 1, Vec3(x=0, y=0, z=1)), + (1, 1, 1, Vec3(x=1, y=1, z=1) / math.sqrt(3)), + (-1, -1, -1, Vec3(x=-1, y=-1, z=-1) / math.sqrt(3)), + ], +) +def test_vec3_normalize(x: float, y: float, z: float, expected: Vec3 | type): + """Test that a Vec3 object can be normalized.""" + v = Vec3(x=x, y=y, z=z) + if isinstance(expected, type): + expected = cast("type[Exception]", expected) + with pytest.raises(expected): + v.normalize() + else: + assert (v.normalize() - expected).norm() < 1e-6 + + +def test_vec3_serialize_to_double(): + """Test that a Vec3 object can be serialized to a double.""" + v = Vec3(x=1.0, y=2.0, z=3.0) + buf = Buffer() + v.serialize_to_double(buf) + + assert bytes(buf) == struct.pack(">ddd", 1.0, 2.0, 3.0) + + +def test_vec3_deserialize_from_double(): + """Test that a Vec3 object can be deserialized from a double.""" + buf = Buffer(struct.pack(">ddd", 1.0, 2.0, 3.0)) + v = Vec3.deserialize_double(buf) + + assert type(v) == Vec3 + assert v.x == 1.0 + assert v.y == 2.0 + assert v.z == 3.0 diff --git a/tests/mcproto/utils/test_serializable.py b/tests/mcproto/utils/test_serializable.py index b02248a6..70e31e0f 100644 --- a/tests/mcproto/utils/test_serializable.py +++ b/tests/mcproto/utils/test_serializable.py @@ -1,13 +1,14 @@ from __future__ import annotations -from typing import Any, cast, final +from typing import Any, final -from attrs import define +from attrs import define, field +from attrs.validators import and_, ge, le, max_len, not_ from typing_extensions import override from mcproto.buffer import Buffer from mcproto.utils.abc import Serializable -from tests.helpers import TestExc, gen_serializable_test +from tests.helpers import ExcTest, gen_serializable_test class CustomError(Exception): @@ -26,20 +27,12 @@ def __init__(self, message: str, additional_data: Any): class ToyClass(Serializable): """Toy class for testing demonstrating the use of gen_serializable_test on `Serializable`.""" - a: int - b: str | int - - @override - def __attrs_post_init__(self) -> None: - if isinstance(self.b, int): - self.b = str(self.b) - - return super().__attrs_post_init__() + a: int = field(validator=not_(and_(ge(0), le(0)))) + b: str = field(converter=str, validator=max_len(10)) @override def serialize_to(self, buf: Buffer): """Write the object to a buffer.""" - self.b = cast(str, self.b) # Handled by the __attrs_post_init__ method buf.write_varint(self.a) buf.write_utf(self.b) @@ -53,15 +46,6 @@ def deserialize(cls, buf: Buffer) -> ToyClass: b = buf.read_utf() return cls(a, b) - @override - def validate(self) -> None: - """Validate the object's attributes.""" - if self.a == 0: - raise ZeroDivisionError("a must be non-zero") - self.b = cast(str, self.b) # Handled by the __attrs_post_init__ method - if len(self.b) > 10: - raise ValueError("b must be less than 10 characters") - # endregion ToyClass @@ -76,14 +60,14 @@ def validate(self) -> None: ((3, 1234567890), b"\x03\x0a1234567890"), ], validation_fail=[ - ((0, "hello"), TestExc(ZeroDivisionError, "a must be non-zero")), # Message specified + ((0, "hello"), ValueError), ((1, "hello world"), ValueError), # No message specified - ((1, 12345678900), TestExc(ValueError, "b must be less than .*")), # Message regex + ((1, 12345678900), ValueError), ], deserialization_fail=[ (b"\x00", CustomError), # No message specified - (b"\x00\x05hello", TestExc(CustomError, "a must be non-zero", {"additional_data": 0})), # Check fields - (b"\x01", TestExc(IOError)), # No message specified + (b"\x00\x05hello", ExcTest(CustomError, "a must be non-zero", {"additional_data": 0})), # Check fields + (b"\x01", ExcTest(IOError)), # No message specified ], ) # endregion Test ToyClass