Files
Musicreater/Musicreater/old_plugin/bdx.py

230 lines
7.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- coding: utf-8 -*-
"""
存放有关BDX结构操作的内容
"""
"""
版权所有 © 2025 金羿 & 诸葛亮与八卦阵
Copyright © 2025 Eilles & bgArray
开源相关声明请见 仓库根目录下的 License.md
Terms & Conditions: License.md in the root directory
"""
# 睿乐组织 开发交流群 861684859
# Email TriM-Organization@hotmail.com
# 若需转载或借鉴 许可声明请查看仓库目录下的 License.md
from typing import List
from ..constants import x, y, z
from ..subclass import MineCommand
from .common import bottem_side_length_of_smallest_square_bottom_box
BDX_MOVE_KEY = {
"x": [b"\x0f", b"\x0e", b"\x1c", b"\x14", b"\x15"],
"y": [b"\x11", b"\x10", b"\x1d", b"\x16", b"\x17"],
"z": [b"\x13", b"\x12", b"\x1e", b"\x18", b"\x19"],
}
"""key存储了方块移动指令的数据其中可以用key[x|y|z][0|1]来表示xyz的减或增
而key[][2+]是用来增加指定数目的"""
def bdx_move(axis: str, value: int):
if value == 0:
return b""
if abs(value) == 1:
return BDX_MOVE_KEY[axis][0 if value == -1 else 1]
pointer = sum(
[
value != -1,
value < -1 or value > 1,
value < -128 or value > 127,
value < -32768 or value > 32767,
]
)
return BDX_MOVE_KEY[axis][pointer] + value.to_bytes(
2 ** (pointer - 2), "big", signed=True
)
def form_command_block_in_BDX_bytes(
command: str,
particularValue: int,
impluse: int = 0,
condition: bool = False,
needRedstone: bool = True,
tickDelay: int = 0,
customName: str = "",
executeOnFirstTick: bool = False,
trackOutput: bool = True,
) -> bytes:
"""
使用指定参数生成指定的指令方块放置指令项
Parameters
------------
command: str
指令
particularValue: int
方块特殊值,即朝向
:0 下 无条件
:1 上 无条件
:2 z轴负方向 无条件
:3 z轴正方向 无条件
:4 x轴负方向 无条件
:5 x轴正方向 无条件
:6 下 无条件
:7 下 无条件
:8 下 有条件
:9 上 有条件
:10 z轴负方向 有条件
:11 z轴正方向 有条件
:12 x轴负方向 有条件
:13 x轴正方向 有条件
:14 下 有条件
:14 下 有条件
注意此处特殊值中的条件会被下面condition参数覆写
impluse: int (0|1|2)
方块类型
0脉冲 1循环 2连锁
condition: bool
是否有条件
needRedstone: bool
是否需要红石
tickDelay: int
执行延时
customName: str
悬浮字
lastOutput: str
命令方块的上次输出字符串,注意此处需要留空
executeOnFirstTick: bool
是否启用首刻执行循环指令方块是否激活后立即执行若为False则从激活时起延迟后第一次执行
trackOutput: bool
是否启用命令方块输出
Returns
---------
bytes
用以生成 bdx 结构的字节码
"""
block = b"\x24" + particularValue.to_bytes(2, byteorder="big", signed=False)
for i in [
impluse.to_bytes(4, byteorder="big", signed=False),
bytes(command, encoding="utf-8") + b"\x00",
bytes(customName, encoding="utf-8") + b"\x00",
bytes("", encoding="utf-8") + b"\x00",
tickDelay.to_bytes(4, byteorder="big", signed=True),
executeOnFirstTick.to_bytes(1, byteorder="big"),
trackOutput.to_bytes(1, byteorder="big"),
condition.to_bytes(1, byteorder="big"),
needRedstone.to_bytes(1, byteorder="big"),
]:
block += i
return block
def commands_to_BDX_bytes(
commands_list: List[MineCommand],
max_height: int = 64,
):
"""
指令列表转换为用以生成 bdx 结构的字节码
Parameters
------------
commands: list[tuple[str, int]]
指令列表,每个元素为 (指令, 延迟)
max_height: int
生成结构最大高度
Returns
---------
tuple[bool, bytes, int] or tuple[bool, str]
成功与否,成功返回 (True, 未经过压缩的源, 结构占用大小),失败返回 (False, str失败原因)
"""
_sideLength = bottem_side_length_of_smallest_square_bottom_box(
len(commands_list), max_height
)
_bytes = b""
y_forward = True
z_forward = True
now_y = 0
now_z = 0
now_x = 0
for command in commands_list:
_bytes += form_command_block_in_BDX_bytes(
command.command_text,
(
(1 if y_forward else 0)
if (
((now_y != 0) and (not y_forward))
or (y_forward and (now_y != (max_height - 1)))
)
else (
(3 if z_forward else 2)
if (
((now_z != 0) and (not z_forward))
or (z_forward and (now_z != _sideLength - 1))
)
else 5
)
),
impluse=2,
condition=command.conditional,
needRedstone=False,
tickDelay=command.delay,
customName=command.annotation_text,
executeOnFirstTick=False,
trackOutput=True,
)
# (1 if y_forward else 0) if ( # 如果y+则向上,反之向下
# ((now_y != 0) and (not y_forward)) # 如果不是y轴上首个方块
# or (y_forward and (now_y != (max_height - 1))) # 如果不是y轴上末端方块
# ) else ( # 否则即是y轴末端或首个方块
# (3 if z_forward else 2) if ( # 如果z+则向z轴正方向反之负方向
# ((now_z != 0) and (not z_forward)) # 如果不是z轴上的首个方块
# or (z_forward and (now_z != _sideLength - 1)) # 如果不是z轴上的末端方块
# ) else 5 # 否则则要面向x轴正方向
# )
now_y += 1 if y_forward else -1
if ((now_y >= max_height) and y_forward) or ((now_y < 0) and (not y_forward)):
now_y -= 1 if y_forward else -1
y_forward = not y_forward
now_z += 1 if z_forward else -1
if ((now_z >= _sideLength) and z_forward) or (
(now_z < 0) and (not z_forward)
):
now_z -= 1 if z_forward else -1
z_forward = not z_forward
_bytes += BDX_MOVE_KEY[x][1]
now_x += 1
else:
_bytes += BDX_MOVE_KEY[z][int(z_forward)]
else:
_bytes += BDX_MOVE_KEY[y][int(y_forward)]
return (
_bytes,
[
now_x + 1,
max_height if now_x or now_z else now_y,
_sideLength if now_x else now_z,
],
[now_x, now_y, now_z],
)