class predictionRequest:

    template_prediction = Dict(
        schema={
            'order_id': Int(coerce=True),
            'store_id': Int(coerce=True),
            'to_user_distance': Float(),
            'to_user_elevation': Float(),
            'total_earning': Int(coerce=True),
            'created_at': Str()
        })

    @classmethod
    def validate_request(cls, request: dict):
        return cls.template_prediction(request)
示例#2
0
class BKAnimation(Animation):
    __slots__ = (
        "null",
        "chain_hit",
        "chain_no_hit",
        "repeat",
        "probability",
        "hazard_damage",
        "footer_string",
    )

    schema = Dict(
        {
            **Animation.schema.schema,
            **{
                "null": UInt8,
                "chain_hit": UInt8,
                "chain_no_hit": UInt8,
                "repeat": UInt8,
                "probability": UInt16,
                "hazard_damage": UInt8,
                "footer_string": Str(),
            },
        }
    )

    def __init__(self):
        super(BKAnimation, self).__init__()
        self.null: int = 0
        self.chain_hit: int = 0
        self.chain_no_hit: int = 0
        self.repeat: int = 0
        self.probability: int = 0
        self.hazard_damage: int = 0
        self.footer_string: str = ""

    @staticmethod
    def get_name(index: int):
        if index in BK_ANIMATION_NAMES:
            return BK_ANIMATION_NAMES[index]
        return None

    def read(self, parser):
        self.null = parser.get_uint8()
        self.chain_hit = parser.get_uint8()
        self.chain_no_hit = parser.get_uint8()
        self.repeat = parser.get_uint8()
        self.probability = parser.get_uint16()
        self.hazard_damage = parser.get_uint8()
        self.footer_string = parser.get_var_str(size_includes_zero=True)
        super(BKAnimation, self).read(parser)
        return self

    def write(self, parser):
        parser.put_uint8(self.null)
        parser.put_uint8(self.chain_hit)
        parser.put_uint8(self.chain_no_hit)
        parser.put_uint8(self.repeat)
        parser.put_uint16(self.probability)
        parser.put_uint8(self.hazard_damage)
        parser.put_var_str(self.footer_string, size_includes_zero=True)
        super(BKAnimation, self).write(parser)

    def serialize(self):
        return {
            **super(BKAnimation, self).serialize(),
            **{
                "null": self.null,
                "chain_hit": self.chain_hit,
                "chain_no_hit": self.chain_no_hit,
                "repeat": self.repeat,
                "probability": self.probability,
                "hazard_damage": self.hazard_damage,
                "footer_string": self.footer_string,
            },
        }

    def unserialize(self, data):
        super(BKAnimation, self).unserialize(data)
        self.null = data["null"]
        self.chain_hit = data["chain_hit"]
        self.chain_no_hit = data["chain_no_hit"]
        self.repeat = data["repeat"]
        self.probability = data["probability"]
        self.hazard_damage = data["hazard_damage"]
        self.footer_string = data["footer_string"]
        return self
示例#3
0
from validx import Dict, List, Str, Datetime, Bool
from django.utils.dateparse import parse_datetime
from datetime import timezone

new_msg_validator = Dict(
    {
        "sender": Str(minlen=1, maxlen=64),
        "text": Str(minlen=1, maxlen=2048),
        "type": Str(minlen=1, maxlen=32),
        "time": Datetime(nullable=True, parser=parse_datetime,
                         tz=timezone.utc),
        "tts": Bool(),
        "data": Str(minlen=0, maxlen=5120),
        "speech_override": Str(nullable=True, minlen=1, maxlen=2048),
        "seen": Bool(),
    },
    defaults={
        "type": "default",
        "time": None,
        "tts": True,
        "seen": False,
        "data": "",
        "speech_override": None,
    },
)

seen_messages_validator = List(Str(minlen=1, maxlen=32))
示例#4
0
class Animation(DataObject):
    __slots__ = (
        "start_x",
        "start_y",
        "base_string",
        "hit_coords",
        "extra_strings",
        "sprites",
    )

    schema = Dict({
        "start_x":
        Int16,
        "start_y":
        Int16,
        "base_string":
        Str(),
        "hit_coords":
        List(
            Dict({
                "x": Int(min=-511, max=511),
                "null": Int(min=0, max=0),
                "y": Int(min=-511, max=511),
                "frame_id": Int(min=0, max=63),
            })),
        "extra_strings":
        List(Str()),
        "sprites":
        List(Sprite.schema),
    })

    def __init__(self):
        self.start_x: int = 0
        self.start_y: int = 0
        self.hit_coords: typing.List[HitCoordinate] = []
        self.sprites: typing.List[Sprite] = []
        self.base_string: str = ""
        self.extra_strings: typing.List[str] = []

    def read(self, parser):
        self.start_x = parser.get_int16()
        self.start_y = parser.get_int16()
        assert parser.get_uint32() == 0
        coord_count = parser.get_uint16()
        sprite_count = parser.get_uint8()

        self.hit_coords = []
        for m in range(0, coord_count):
            a = parser.get_uint16()
            b = parser.get_uint16()
            x = 0x3FF & a
            y = 0x3FF & b
            self.hit_coords.append({
                "x": x if x < 512 else x - 1024,
                "null": (a >> 10),
                "y": y if y < 512 else y - 1024,
                "frame_id": (b >> 10),
            })

        self.base_string = parser.get_var_str()
        extra_str_count = parser.get_uint8()

        self.extra_strings = [
            parser.get_var_str() for _ in range(extra_str_count)
        ]
        self.sprites = [Sprite().read(parser) for _ in range(sprite_count)]

        return self

    def write(self, parser):
        parser.put_int16(self.start_x)
        parser.put_int16(self.start_y)
        parser.put_uint32(0)
        parser.put_uint16(len(self.hit_coords))
        parser.put_uint8(len(self.sprites))

        for coord in self.hit_coords:
            frame_id = coord["frame_id"]
            null = coord["null"]
            x = coord["x"]
            y = coord["y"]
            tmp = frame_id & 0x3F
            tmp <<= 10
            tmp |= y & 0x3FF
            tmp <<= 6
            tmp |= null & 0x3F
            tmp <<= 10
            tmp |= x & 0x3FF
            parser.put_uint32(tmp)

        parser.put_var_str(self.base_string)

        parser.put_uint8(len(self.extra_strings))
        for extra_string in self.extra_strings:
            parser.put_var_str(extra_string)

        for sprite in self.sprites:
            sprite.write(parser)

    def serialize(self):
        return {
            "start_x": self.start_x,
            "start_y": self.start_y,
            "hit_coords": self.hit_coords,
            "sprites": [sprite.serialize() for sprite in self.sprites],
            "base_string": self.base_string,
            "extra_strings": self.extra_strings,
        }

    def unserialize(self, data):
        self.start_x = data["start_x"]
        self.start_y = data["start_y"]
        self.hit_coords = data["hit_coords"]
        self.sprites = [
            Sprite().unserialize(sprite) for sprite in data["sprites"]
        ]
        self.base_string = data["base_string"]
        self.extra_strings = data["extra_strings"]
        return self
示例#5
0
文件: schema.py 项目: spack971/becmd
#: Set of reserved configuration keys.
CONFIG_RESERVED_KEYS = {'becmd', 'hosts', 'logging', 'refresh'}

#: List of logging levels.
LOGGING_LEVELS = {'CRITICAL', 'ERROR', 'WARNING', 'INFO', 'DEBUG', 'NOTSET'}
#: Logging format styles.
LOGGING_STYLES = {'%', '{', '$'}

#: Regular expression excluding all reserved configuration keys.
RESERVED_KEYS_PATTERN = r'^(?:(?!{}).+)$'.format(
    r'|'.join(CONFIG_RESERVED_KEYS))

#: Validation schema for a host configuration.
Host = Dict(
    {
        'api_key': Str(nullable=False),
        'host': Str(pattern=r'^[0-9A-Za-z\._-]+$', nullable=False),
        'insecure_tls': Bool(),
        'timeout': Float(),
        'use_cache': Bool(),
        'use_https': Bool(),
    },
    dispose=[
        'default',
    ],
)

#: Host configuration keys.
HOST_CONFIG_KEYS = set(Host.schema)

#: Host validator where the command line arguments are optional.
示例#6
0
#!/bin/python
# validation!!
# https://validx.readthedocs.io/en/latest/usage.html?highlight=install

from validx import Dict, List, Str, Int

search_params = Dict(
    {
        "query": Str(minlen=3, maxlen=500),    # Search query
        "tags": List(Str(pattern=r"^[\w]+$")), # Optional list of tags
        "limit": Int(min=0, max=100),          # Pagination parameters
        "offset": Int(min=0),
    },
    defaults={
        "limit": 100,
        "offset": 0,
    },
    optional=["tags"],
)

# testing
assert search_params({"query": u"Craft Beer"}) == {
    "query": "Craft Beer",
    "limit": 100,
    "offset": 0,
}

assert search_params({"query": u"Craft Beer", "offset": 100}) == {
    "query": u"Craft Beer",
    "limit": 100,
    "offset": 100,
示例#7
0
class AFMove(Animation):
    __slots__ = (
        "ai_opts",
        "pos_constraint",
        "unknown_4",
        "unknown_5",
        "unknown_6",
        "unknown_7",
        "unknown_8",
        "unknown_9",
        "unknown_10",
        "unknown_11",
        "next_animation_id",
        "category",
        "unknown_14",
        "scrap_amount",
        "successor_id",
        "damage_amount",
        "collision_opts",
        "extra_string_selector",
        "points",
        "move_string",
        "enemy_string",
    )

    schema = Dict({
        **Animation.schema.schema,
        **{
            "ai_opts": UInt16,
            "pos_constraint": UInt16,
            "unknown_4": UInt8,
            "unknown_5": UInt8,
            "unknown_6": UInt8,
            "unknown_7": UInt8,
            "unknown_8": UInt8,
            "unknown_9": UInt8,
            "unknown_10": UInt8,
            "unknown_11": UInt8,
            "next_animation_id": UInt8,
            "category": UInt8,
            "unknown_14": UInt8,
            "scrap_amount": UInt8,
            "successor_id": UInt8,
            "damage_amount": UInt8,
            "collision_opts": UInt8,
            "extra_string_selector": UInt8,
            "points": UInt8,
            "move_string": Str(maxlen=21),
            "enemy_string": Str(),
        },
    })

    def __init__(self):
        super(AFMove, self).__init__()
        self.ai_opts: AIOptions = AIOptions.NONE
        self.pos_constraint: PositionConstraint = PositionConstraint.NONE
        self.unknown_4: int = 0
        self.unknown_5: int = 0
        self.unknown_6: int = 0
        self.unknown_7: int = 0
        self.unknown_8: int = 0
        self.unknown_9: int = 0
        self.unknown_10: int = 0
        self.unknown_11: int = 0
        self.next_animation_id: int = 0
        self.category: MoveCategory = MoveCategory.MISCELLANEOUS
        self.unknown_14: int = 0
        self.scrap_amount: int = 0
        self.successor_id: int = 0
        self.damage_amount: int = 0
        self.collision_opts: CollisionOpts = CollisionOpts.NONE
        self.extra_string_selector: int = 0
        self.points: int = 0
        self.move_string: str = ""
        self.enemy_string: str = ""

    @staticmethod
    def get_name(index: int):
        if index in AF_ANIMATION_NAMES:
            return AF_ANIMATION_NAMES[index]
        return None

    def read(self, parser):
        super(AFMove, self).read(parser)
        self.ai_opts = AIOptions(parser.get_uint16())
        self.pos_constraint = PositionConstraint(parser.get_uint16())
        self.unknown_4 = parser.get_uint8()
        self.unknown_5 = parser.get_uint8()
        self.unknown_6 = parser.get_uint8()
        self.unknown_7 = parser.get_uint8()
        self.unknown_8 = parser.get_uint8()
        self.unknown_9 = parser.get_uint8()
        self.unknown_10 = parser.get_uint8()
        self.unknown_11 = parser.get_uint8()
        self.next_animation_id = parser.get_uint8()
        self.category = MoveCategory(parser.get_uint8())
        self.unknown_14 = parser.get_uint8()
        self.scrap_amount = parser.get_uint8()
        self.successor_id = parser.get_uint8()
        self.damage_amount = parser.get_uint8()
        self.collision_opts = CollisionOpts(parser.get_uint8())
        self.extra_string_selector = parser.get_uint8()
        self.points = parser.get_uint8()
        self.move_string = parser.get_null_padded_str(21)
        self.enemy_string = parser.get_var_str(size_includes_zero=True)
        return self

    def write(self, parser):
        super(AFMove, self).write(parser)
        parser.put_uint16(self.ai_opts.value)
        parser.put_uint16(self.pos_constraint.value)
        parser.put_uint8(self.unknown_4)
        parser.put_uint8(self.unknown_5)
        parser.put_uint8(self.unknown_6)
        parser.put_uint8(self.unknown_7)
        parser.put_uint8(self.unknown_8)
        parser.put_uint8(self.unknown_9)
        parser.put_uint8(self.unknown_10)
        parser.put_uint8(self.unknown_11)
        parser.put_uint8(self.next_animation_id)
        parser.put_uint8(self.category.value)
        parser.put_uint8(self.unknown_14)
        parser.put_uint8(self.scrap_amount)
        parser.put_uint8(self.successor_id)
        parser.put_uint8(self.damage_amount)
        parser.put_uint8(self.collision_opts.value)
        parser.put_uint8(self.extra_string_selector)
        parser.put_uint8(self.points)
        parser.put_null_padded_str(self.move_string, 21)
        parser.put_var_str(self.enemy_string, size_includes_zero=True)

    def serialize(self):
        return {
            **super(AFMove, self).serialize(),
            **{
                "ai_opts": self.ai_opts.value,
                "pos_constraint": self.pos_constraint.value,
                "unknown_4": self.unknown_4,
                "unknown_5": self.unknown_5,
                "unknown_6": self.unknown_6,
                "unknown_7": self.unknown_7,
                "unknown_8": self.unknown_8,
                "unknown_9": self.unknown_9,
                "unknown_10": self.unknown_10,
                "unknown_11": self.unknown_11,
                "next_animation_id": self.next_animation_id,
                "category": self.category.value,
                "unknown_14": self.unknown_14,
                "scrap_amount": self.scrap_amount,
                "successor_id": self.successor_id,
                "damage_amount": self.damage_amount,
                "collision_opts": self.collision_opts.value,
                "extra_string_selector": self.extra_string_selector,
                "points": self.points,
                "move_string": self.move_string,
                "enemy_string": self.enemy_string,
            },
        }

    def unserialize(self, data: dict):
        super(AFMove, self).unserialize(data)
        self.ai_opts = AIOptions(data["ai_opts"])
        self.pos_constraint = PositionConstraint(data["pos_constraint"])
        self.unknown_4 = data["unknown_4"]
        self.unknown_5 = data["unknown_5"]
        self.unknown_6 = data["unknown_6"]
        self.unknown_7 = data["unknown_7"]
        self.unknown_8 = data["unknown_8"]
        self.unknown_9 = data["unknown_9"]
        self.unknown_10 = data["unknown_10"]
        self.unknown_11 = data["unknown_11"]
        self.next_animation_id = data["next_animation_id"]
        self.category = MoveCategory(data["category"])
        self.unknown_14 = data["unknown_14"]
        self.scrap_amount = data["scrap_amount"]
        self.successor_id = data["successor_id"]
        self.damage_amount = data["damage_amount"]
        self.collision_opts = CollisionOpts(data["collision_opts"])
        self.extra_string_selector = data["extra_string_selector"]
        self.points = data["points"]
        self.move_string = data["move_string"]
        self.enemy_string = data["enemy_string"]
        return self
示例#8
0
class BKFile(Entrypoint):
    ANIMATION_MAX_NUMBER = 50

    __slots__ = (
        "file_id",
        "unknown_a",
        "background_width",
        "background_height",
        "background_image",
        "animations",
        "sound_table",
        "palettes",
    )

    schema = Dict(
        {
            "file_id": UInt32,
            "unknown_a": UInt8,
            "background_width": UInt16,
            "background_height": UInt16,
            "background_image": List(UInt8),
            "animations": Dict(extra=(Str(pattern=r"^[0-9]+$"), BKAnimation.schema)),
            "sound_table": List(UInt8, maxlen=30, minlen=30),
            "palettes": List(PaletteMapping.schema),
        }
    )

    def __init__(self):
        self.file_id = 0
        self.unknown_a = 0
        self.background_width = 0
        self.background_height = 0
        self.animations: typing.Dict[int, BKAnimation] = {}
        self.palettes: typing.List[PaletteMapping] = []
        self.sound_table: typing.List[int] = []
        self.background_image: EncodedImage = []

    def serialize(self):
        return {
            "file_id": self.file_id,
            "unknown_a": self.unknown_a,
            "background_width": self.background_width,
            "background_height": self.background_height,
            "background_image": self.background_image,
            "animations": {k: v.serialize() for k, v in self.animations.items()},
            "palettes": [palette.serialize() for palette in self.palettes],
            "sound_table": self.sound_table,
        }

    def unserialize(self, data):
        self.file_id = data["file_id"]
        self.unknown_a = data["unknown_a"]
        self.background_width = data["background_width"]
        self.background_height = data["background_height"]
        self.background_image = data["background_image"]
        self.sound_table = data["sound_table"]
        self.palettes = [PaletteMapping().unserialize(v) for v in data["palettes"]]
        self.animations = {
            int(k): BKAnimation().unserialize(v) for k, v in data["animations"].items()
        }
        return self

    def read(self, parser):
        self.file_id = parser.get_uint32()
        self.unknown_a = parser.get_uint8()
        self.background_width = parser.get_uint16()
        self.background_height = parser.get_uint16()

        # Read all animations (up to max ANIMATION_MAX_NUMBER)
        while True:
            parser.get_uint32()  # Skip
            anim_no = parser.get_uint8()
            if anim_no >= self.ANIMATION_MAX_NUMBER:
                break
            self.animations[anim_no] = BKAnimation().read(parser)

        # Read the raw Background image (VGA palette format)
        background_size = self.background_height * self.background_width
        self.background_image = [parser.get_uint8() for _ in range(background_size)]

        # Read up all available color palettes
        palette_count = parser.get_uint8()
        self.palettes = [PaletteMapping().read(parser) for _ in range(palette_count)]

        # Get sound mappings
        self.sound_table = [parser.get_uint8() for _ in range(30)]

        return self

    def write(self, parser):
        parser.put_uint32(self.file_id)
        parser.put_uint8(self.unknown_a)
        parser.put_uint16(self.background_width)
        parser.put_uint16(self.background_height)

        for key, ani in self.animations.items():
            # Write animation to binary buffer so that
            # we can tell its length
            buf = io.BytesIO()
            ani.write(BinaryParser(buf))
            ani_data = buf.getvalue()

            # Write offset of next animation, then ID,
            # then the animation blob. Add +5 to offset to account
            # for the next offset and ID.
            offset = parser.get_pos() + len(ani_data) + 5
            parser.put_uint32(offset)
            parser.put_uint8(key)
            parser.put_bytes(ani_data)

            buf.close()

        # Write ending of the animations block
        parser.put_uint32(parser.get_pos())
        parser.put_uint8(self.ANIMATION_MAX_NUMBER + 1)

        for pixel in self.background_image:
            parser.put_uint8(pixel)

        parser.put_uint8(len(self.palettes))
        for pal in self.palettes:
            pal.write(parser)

        for sound in self.sound_table:
            parser.put_uint8(sound)

    def save_background(self, filename: str):
        save_png(
            generate_png(
                self.background_image,
                self.background_width,
                self.background_height,
                self.palettes[0].colors,
            ),
            filename,
        )
示例#9
0
文件: af.py 项目: pikatech/pyomftools
class AFFile(Entrypoint):
    MOVE_MAX_NUMBER = 70

    __slots__ = (
        "file_id",
        "exec_window",
        "endurance",
        "unknown_b",
        "health",
        "forward_speed",
        "reverse_speed",
        "jump_speed",
        "fall_speed",
        "unknown_c",
        "unknown_d",
        "sound_table",
        "moves",
    )

    schema = Dict(
        {
            "file_id": UInt16,
            "exec_window": UInt16,
            "endurance": UInt32,
            "unknown_b": UInt8,
            "health": UInt16,
            "forward_speed": Int32,
            "reverse_speed": Int32,
            "jump_speed": Int32,
            "fall_speed": Int32,
            "unknown_c": UInt8,
            "unknown_d": UInt8,
            "sound_table": List(UInt8, maxlen=30, minlen=30),
            "moves": Dict(extra=(Str(pattern=r"^[0-9]+$"), AFMove.schema)),
        }
    )

    def __init__(self):
        self.file_id: int = 0
        self.exec_window: int = 0
        self.endurance: int = 0
        self.unknown_b: int = 0
        self.health: int = 0
        self.forward_speed: int = 0
        self.reverse_speed: int = 0
        self.jump_speed: int = 0
        self.fall_speed: int = 0
        self.unknown_c: int = 0
        self.unknown_d: int = 0
        self.moves: typing.Dict[int, AFMove] = {}
        self.sound_table: typing.List[int] = []

    def serialize(self):
        return {
            "file_id": self.file_id,
            "exec_window": self.exec_window,
            "endurance": self.endurance,
            "unknown_b": self.unknown_b,
            "health": self.health,
            "forward_speed": self.forward_speed,
            "reverse_speed": self.reverse_speed,
            "jump_speed": self.jump_speed,
            "fall_speed": self.fall_speed,
            "unknown_c": self.unknown_c,
            "unknown_d": self.unknown_d,
            "moves": {k: v.serialize() for k, v in self.moves.items()},
            "sound_table": self.sound_table,
        }

    def unserialize(self, data):
        self.file_id = data["file_id"]
        self.exec_window = data["exec_window"]
        self.endurance = data["endurance"]
        self.unknown_b = data["unknown_b"]
        self.health = data["health"]
        self.forward_speed = data["forward_speed"]
        self.reverse_speed = data["reverse_speed"]
        self.jump_speed = data["jump_speed"]
        self.fall_speed = data["fall_speed"]
        self.unknown_c = data["unknown_c"]
        self.unknown_d = data["unknown_d"]
        self.moves = {int(k): AFMove().unserialize(v) for k, v in data["moves"].items()}
        self.sound_table = data["sound_table"]
        return self

    def read(self, parser):
        self.file_id = parser.get_uint16()
        self.exec_window = parser.get_uint16()
        self.endurance = parser.get_uint32()
        self.unknown_b = parser.get_uint8()
        self.health = parser.get_uint16()
        self.forward_speed = parser.get_int32()
        self.reverse_speed = parser.get_int32()
        self.jump_speed = parser.get_int32()
        self.fall_speed = parser.get_int32()
        self.unknown_c = parser.get_uint8()
        self.unknown_d = parser.get_uint8()

        # Read all animations (up to max MOVE_MAX_NUMBER)
        while True:
            move_no = parser.get_uint8()
            if move_no >= self.MOVE_MAX_NUMBER:
                break
            self.moves[move_no] = AFMove().read(parser)

        # Find missing image data by index
        index_table: typing.Dict[int, Sprite] = {}
        for key, m in self.moves.items():
            for idx, sprite in enumerate(m.sprites):
                if sprite.missing:
                    if sprite.index in index_table:
                        sprite.image = index_table[sprite.index].image
                else:
                    index_table[sprite.index] = sprite

        # Read sound table
        for m in range(0, 30):
            sound = parser.get_uint8()
            self.sound_table.append(sound)

        return self

    def write(self, parser):
        parser.put_uint16(self.file_id)
        parser.put_uint16(self.exec_window)
        parser.put_uint32(self.endurance)
        parser.put_uint8(self.unknown_b)
        parser.put_uint16(self.health)
        parser.put_int32(self.forward_speed)
        parser.put_int32(self.reverse_speed)
        parser.put_int32(self.jump_speed)
        parser.put_int32(self.fall_speed)
        parser.put_uint8(self.unknown_c)
        parser.put_uint8(self.unknown_d)

        # Write moves
        for key, move in self.moves.items():
            parser.put_uint8(key)
            move.write(parser)

        # Mark the end of moves
        parser.put_uint8(250)

        # Write sounds
        for sound in self.sound_table:
            parser.put_uint8(sound)

    @property
    def real_endurance(self):
        return self.endurance / 256.0

    @real_endurance.setter
    def real_endurance(self, value):
        self.endurance = int(value * 256.0)

    @property
    def real_forward_speed(self):
        return self.forward_speed / 256.0

    @real_forward_speed.setter
    def real_forward_speed(self, value):
        self.forward_speed = int(value * 256.0)

    @property
    def real_reverse_speed(self):
        return self.reverse_speed / 256.0

    @real_reverse_speed.setter
    def real_reverse_speed(self, value):
        self.reverse_speed = int(value * 256.0)

    @property
    def real_jump_speed(self):
        return self.jump_speed / 256.0

    @real_jump_speed.setter
    def real_jump_speed(self, value):
        self.jump_speed = int(value * 256.0)

    @property
    def real_fall_speed(self):
        return self.fall_speed / 256.0

    @real_fall_speed.setter
    def real_fall_speed(self, value):
        self.fall_speed = int(value * 256.0)