diff --git a/Musicreater/main.py b/Musicreater/main.py index c2ae62e..1cc3d47 100644 --- a/Musicreater/main.py +++ b/Musicreater/main.py @@ -155,6 +155,7 @@ class midiConvert: [ self._toCmdList_withDelay_m1, self._toCmdList_withDelay_m2, + self._toCmdList_withDelay_m3, ] ) @@ -1457,7 +1458,6 @@ class midiConvert: speed: float = 1.0, progressbar: Union[bool, tuple] = False, player: str = "@a", - author: str = "Eilles", max_height: int = 64, ): """ @@ -1480,8 +1480,13 @@ class midiConvert: if not os.path.exists(self.outputPath): os.makedirs(self.outputPath) - + struct, size = to_structure(cmdlist,max_height-1) + with open( + os.path.abspath(os.path.join(self.outputPath, f"{self.midFileName}.mcstructure")), + "wb+", + ) as f: + struct.dump(f) diff --git a/Musicreater/utils.py b/Musicreater/utils.py index dcabe83..81fa654 100644 --- a/Musicreater/utils.py +++ b/Musicreater/utils.py @@ -106,13 +106,14 @@ def form_command_block_in_BDX_bytes( lastOutput: `str` 上次输出字符串,注意此处需要留空 :param executeOnFirstTick: `bool` - 执行第一个已选项(循环指令方块是否激活后立即执行,若为False,则从激活时起延迟后第一次执行) + 首刻执行(循环指令方块是否激活后立即执行,若为False,则从激活时起延迟后第一次执行) :param trackOutput: `bool` 是否输出 :return:str """ - block = b"\x24" + particularValue.to_bytes(2, byteorder="big", signed=False) + block = b"\x24" + \ + particularValue.to_bytes(2, byteorder="big", signed=False) for i in [ impluse.to_bytes(4, byteorder="big", signed=False), @@ -147,7 +148,9 @@ def to_BDX_bytes( :return 成功与否,成功返回(True,未经过压缩的源,结构占用大小),失败返回(False,str失败原因) """ - _sideLength = bottem_side_length_of_smallest_square_bottom_box(len(commands), max_height) + _sideLength = bottem_side_length_of_smallest_square_bottom_box( + len(commands), max_height + ) _bytes = b"" y_forward = True @@ -196,7 +199,7 @@ def to_BDX_bytes( now_z += 1 if z_forward else -1 - if ((now_z > _sideLength) and z_forward) or ( + if ((now_z >= _sideLength) and z_forward) or ( (now_z < 0) and (not z_forward) ): now_z -= 1 if z_forward else -1 @@ -224,10 +227,11 @@ def to_BDX_bytes( def form_command_block_in_NBT_struct( command: str, + coordinate: tuple, particularValue: int, impluse: int = 0, condition: bool = False, - needRedstone: bool = True, + alwaysRun: bool = True, tickDelay: int = 0, customName: str = "", executeOnFirstTick: bool = False, @@ -237,6 +241,8 @@ def form_command_block_in_NBT_struct( 使用指定项目返回指定的指令方块结构 :param command: `str` 指令 + :param coordinate: `tuple[int,int,int]` + 此方块所在之相对坐标 :param particularValue: 方块特殊值,即朝向 :0 下 无条件 @@ -262,28 +268,54 @@ def form_command_block_in_NBT_struct( 0脉冲 1循环 2连锁 :param condition: `bool` 是否有条件 - :param needRedstone: `bool` - 是否需要红石 + :param alwaysRun: `bool` + 是否始终执行 :param tickDelay: `int` 执行延时 :param customName: `str` 悬浮字 - lastOutput: `str` - 上次输出字符串,注意此处需要留空 :param executeOnFirstTick: `bool` - 执行第一个已选项(循环指令方块是否激活后立即执行,若为False,则从激活时起延迟后第一次执行) + 首刻执行(循环指令方块是否激活后立即执行,若为False,则从激活时起延迟后第一次执行) :param trackOutput: `bool` 是否输出 :return:str """ - from TrimMCStruct import Block - block = Block("minecraft","command_block") - + from TrimMCStruct import Block, TAG_Long + block = Block( + "minecraft", + "command_block" if impluse == 0 else ( + "repeating_command_block" if impluse == 1 else "chain_command_block"), + states={"conditional_bit": condition, + "facing_direction": particularValue}, + extra_data={ + 'Command': command, + 'CustomName': customName, + 'ExecuteOnFirstTick': executeOnFirstTick, + 'LPCommandMode': 0, + 'LPCondionalMode': False, + 'LPRedstoneMode': False, + 'LastExecution': TAG_Long(0), + 'LastOutput': '', + 'LastOutputParams': [], + 'SuccessCount': 0, + 'TickDelay': tickDelay, + 'TrackOutput': trackOutput, + 'Version': 25, + 'auto': alwaysRun, + 'conditionMet': False, # 是否已经满足条件 + 'conditionalMode': condition, + 'id': 'CommandBlock', + 'isMovable': True, + 'powered': False, # 是否已激活 + 'x': coordinate[0], + 'y': coordinate[1], + 'z': coordinate[2], + } + ) return block - def to_structure( commands: list, max_height: int = 64, @@ -291,12 +323,14 @@ def to_structure( """ :param commands: 指令列表(指令, 延迟) :param max_height: 生成结构最大高度 - :return 成功与否,成功返回(True,未经过压缩的源,结构占用大小),失败返回(False,str失败原因) + :return 成功与否,成功返回(结构类,结构占用大小),失败返回(False,str失败原因) """ # 导入库 - from TrimMCStruct import Block, Structure + from TrimMCStruct import Structure - _sideLength = bottem_side_length_of_smallest_square_bottom_box(len(commands), max_height) + _sideLength = bottem_side_length_of_smallest_square_bottom_box( + len(commands), max_height + ) struct = Structure( (_sideLength, max_height, _sideLength), # 声明结构大小 @@ -310,34 +344,30 @@ def to_structure( now_x = 0 for cmd, delay in commands: - impluse = 2 - condition = False - needRedstone = False - tickDelay = delay - customName = "" - executeOnFirstTick = False - trackOutput = True - _bytes += form_command_block_in_BDX_bytes( - cmd, - (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)) - ) - else 5, - impluse=impluse, - condition=condition, - needRedstone=needRedstone, - tickDelay=tickDelay, - customName=customName, - executeOnFirstTick=executeOnFirstTick, - trackOutput=trackOutput, - ) + coordinate = (now_x, now_y, now_z) + struct.set_block(coordinate, + form_command_block_in_NBT_struct( + command=cmd, + coordinate=coordinate, + particularValue=(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)) + ) + else 5, + impluse=2, + condition=False, + alwaysRun=True, + tickDelay=delay, + customName="", + executeOnFirstTick=False, + trackOutput=True, + )) now_y += 1 if y_forward else -1 @@ -348,27 +378,18 @@ def to_structure( now_z += 1 if z_forward else -1 - if ((now_z > _sideLength) and z_forward) or ( + 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 += key[x][1] now_x += 1 - else: - - _bytes += key[z][int(z_forward)] - - else: - - _bytes += key[y][int(y_forward)] return ( - _bytes, + struct, [ 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], - ) \ No newline at end of file + ) diff --git a/example_mcstructure.py b/example_mcstructure.py new file mode 100644 index 0000000..3f8af86 --- /dev/null +++ b/example_mcstructure.py @@ -0,0 +1,6 @@ + +from Musicreater import midiConvert + +conversion = midiConvert() +conversion.convert(input("midi path:"),input("out path:")) +conversion.to_mcstructure_file_with_delay(3,) \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 772b6ad..0331a85 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ Brotli>=1.0.9 mido>=1.2.10 -TrimMCStruct>=0.0.2 \ No newline at end of file +TrimMCStruct>=0.0.5 \ No newline at end of file