pyCraft/minecraft/networking/types/enum.py

125 lines
3.4 KiB
Python

"""Types for enumerations of values occurring in packets, including operations
for working with these values.
The values in an enum are given as class attributes with UPPERCASE names.
These classes are usually not supposed to be instantiated, but sometimes an
instantiatable class may subclass Enum to provide class enum attributes in
addition to other functionality.
"""
from .utility import Vector
__all__ = (
'Enum', 'BitFieldEnum', 'AbsoluteHand', 'RelativeHand', 'BlockFace',
'Difficulty', 'Dimension', 'GameMode', 'OriginPoint'
)
class Enum(object):
# Return a human-readable string representation of an enum value.
@classmethod
def name_from_value(cls, value):
for name, name_value in cls.__dict__.items():
if name.isupper() and name_value == value:
return name
class BitFieldEnum(Enum):
@classmethod
def name_from_value(cls, value):
if not isinstance(value, int):
return
ret_names = []
ret_value = 0
for cls_name, cls_value in sorted(
[(n, v) for (n, v) in cls.__dict__.items()
if isinstance(v, int) and n.isupper() and v | value == value],
reverse=True, key=lambda p: p[1]
):
if ret_value | cls_value != ret_value or cls_value == value:
ret_names.append(cls_name)
ret_value |= cls_value
if ret_value == value:
return '|'.join(reversed(ret_names)) if ret_names else '0'
# Designation of one of a player's hands, in absolute terms.
class AbsoluteHand(Enum):
LEFT = 0
RIGHT = 1
# Designation of one a player's hands, relative to a choice of main/off hand.
class RelativeHand(Enum):
MAIN = 0
OFF = 1
# Designation of one of a block's 6 faces.
class BlockFace(Enum):
BOTTOM = 0 # -Y
TOP = 1 # +Y
NORTH = 2 # -Z
SOUTH = 3 # +Z
WEST = 4 # -X
EAST = 5 # +X
# A dict mapping Vector tuples to the corresponding BlockFace values.
# When accessing this dict, plain tuples also match. For example:
# >>> BlockFace.from_vector[0, 0, -1] == BlockFace.NORTH
# True
from_vector = {
Vector(0, -1, 0): BOTTOM,
Vector(0, +1, 0): TOP,
Vector(0, 0, -1): NORTH,
Vector(0, 0, +1): SOUTH,
Vector(-1, 0, 0): WEST,
Vector(+1, 0, 0): EAST,
}
# A dict mapping BlockFace values to unit Position tuples.
# This is the inverse mapping of face_by_position. For example:
# >>> BlockFace.to_vector[BlockFace.NORTH]
# Position(x=0, y=0, z=-1)
to_vector = {fce: pos for (pos, fce) in from_vector.items()}
# Designation of a world's difficulty.
class Difficulty(Enum):
PEACEFUL = 0
EASY = 1
NORMAL = 2
HARD = 3
# Designation of a world's dimension.
class Dimension(Enum):
NETHER = -1
OVERWORLD = 0
END = 1
from_identifier_dict = {
'minecraft:the_nether': NETHER,
'minecraft:overworld': OVERWORLD,
'minecraft:the_end': END,
}
to_identifier_dict = {e: i for (i, e) in from_identifier_dict.items()}
# Designation of a player's gamemode.
class GameMode(BitFieldEnum):
SURVIVAL = 0
CREATIVE = 1
ADVENTURE = 2
SPECTATOR = 3
HARDCORE = 8 # Only used prior to protocol 738.
# Currently designates an entity's feet or eyes.
# Used in the Face Player Packet
class OriginPoint(Enum):
FEET = 0
EYES = 1