mirror of
https://github.com/TriM-Organization/Musicreater.git
synced 2024-11-14 11:27:42 +08:00
247 lines
10 KiB
Python
247 lines
10 KiB
Python
"""音创系列的转换功能"""
|
||
# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日
|
||
# 统计:致命(三级)错误:0个;警告(二级)错误:2个;语法(一级)错误:192个
|
||
|
||
|
||
from nmcsup.log import log
|
||
|
||
import amulet
|
||
import amulet_nbt
|
||
from amulet.api.block import Block
|
||
from amulet.api.block_entity import BlockEntity
|
||
from amulet.utils.world_utils import block_coords_to_chunk_coords
|
||
from amulet_nbt import TAG_String, TAG_Compound, TAG_Byte
|
||
|
||
|
||
# 输入一个列表 [ [str, float ], [], ... ] 音符str 值为持续时间float
|
||
def note2list(Notes: list) -> list:
|
||
from nmcsup.const import notes
|
||
|
||
def change(base):
|
||
enwo = {
|
||
'a': 'A',
|
||
'b': 'B',
|
||
'c': 'C',
|
||
'd': "D",
|
||
"e": "E",
|
||
'f': 'F',
|
||
'g': "G"
|
||
}
|
||
nuwo = {
|
||
'6': 'A',
|
||
'7': 'B',
|
||
'1': 'C',
|
||
'2': "D",
|
||
"3": "E",
|
||
'4': 'F',
|
||
'5': "G"
|
||
}
|
||
for k, v in enwo.items():
|
||
if k in base:
|
||
base = base.replace(k, v)
|
||
for k, v in nuwo.items():
|
||
if k in base:
|
||
base = base.replace(k, v)
|
||
return base
|
||
|
||
res = []
|
||
log(" === 音符列表=>音调列表")
|
||
for i in Notes:
|
||
s2 = change(i[0])
|
||
log(' === 正在操作音符' + i[0] + '->' + s2)
|
||
if s2 in notes.keys():
|
||
log(" === 找到此音符,加入:" + str(notes[s2][0]))
|
||
res.append([notes[s2][0], float(i[1])])
|
||
else:
|
||
log(' === ' + s2 + '不在音符表内,此处自动替换为 休止符0 ')
|
||
res.append(['0', float(i[1])])
|
||
log(' === 最终反回' + str(res))
|
||
return res
|
||
|
||
|
||
def mcnote2freq(Notes):
|
||
from nmcsup.const import notes
|
||
mcnback = {}
|
||
for i, j in notes.items():
|
||
mcnback[j[0]] = i
|
||
res = []
|
||
log(" === 我的世界音调表=>频率列表")
|
||
for i in Notes:
|
||
log(' === 正在操作音符' + i[0] + '->' + mcnback[i[0]])
|
||
res.append([notes[mcnback[i[0]]][1], float(i[1])])
|
||
log(' === 最终反回' + str(res))
|
||
return res
|
||
|
||
|
||
# MP3文件转midi文件
|
||
def Mp32Mid(mp3File, midFile):
|
||
from piano_transcription_inference import PianoTranscription, sample_rate, load_audio
|
||
# 加载
|
||
(audio, _) = load_audio(mp3File, sr=sample_rate) # , mono=True
|
||
# 实例化并转换
|
||
PianoTranscription(device="cpu").transcribe(audio, midFile)
|
||
|
||
|
||
# 传入一个音符列表转为指令列表
|
||
def Note2Cmd(Notes: list, ScoreboardName: str, Instrument: str, PlayerSelect: str = '',
|
||
isProsess: bool = False) -> list:
|
||
commands = []
|
||
a = 0.0
|
||
length = len(Notes)
|
||
j = 1
|
||
for i in range(len(Notes)):
|
||
commands.append("execute @a" + PlayerSelect + " ~ ~ ~ execute @s[scores={" + ScoreboardName + "=" + str(
|
||
int((a + 2) * 5 + int(Notes[i][1] * 5))) + "}] ~ ~ ~ playsound " + Instrument + " @s ~ ~ ~ 1000 " + str(
|
||
Notes[i][0]) + " 1000\n")
|
||
a += Notes[i][1]
|
||
if isProsess:
|
||
commands.append("execute @a" + PlayerSelect + " ~ ~ ~ execute @s[scores={" + ScoreboardName + "=" + str(
|
||
int((a + 2) * 5 + int(Notes[i][1] * 5))) + "}] ~ ~ ~ title @s actionbar §e▶ 播放中: §a" + str(
|
||
j) + "/" + str(length) + " || " + str(int(j / length * 1000) / 10) + "\n")
|
||
j += 1
|
||
commands.append("\n\n# 凌云我的世界开发团队 x 凌云软件开发团队 : W-YI(金羿)\n")
|
||
return commands
|
||
|
||
|
||
# def newDataStructureCounterChange():
|
||
|
||
|
||
# 简单载入方块
|
||
# level.set_version_block(posx,posy,posz,"minecraft:overworld",("bedrock", (1, 16, 20)),Block(namespace, name))
|
||
|
||
|
||
# 转入指令列表与位置信息转至世界
|
||
def Cmd2World(cmd: list, world: str, dire: list):
|
||
"""将指令以命令链的形式载入世界\n
|
||
cmd指令列表位为一个序列,中包含指令字符串\n
|
||
world为地图所在位置,需要指向文件夹,dire为指令方块生成之位置"""
|
||
level = amulet.load_level(world)
|
||
cdl = []
|
||
for i in cmd:
|
||
# e = True
|
||
try:
|
||
if (i[:i.index('#')].replace(' ', '') != '\n') and (i[:i.index('#')].replace(' ', '') != ''):
|
||
cdl.append(i[:i.index('#')])
|
||
# e = False
|
||
except:
|
||
cdl.append(i)
|
||
# finally:
|
||
# if e is True:
|
||
# cdl.append(i)
|
||
i = 0
|
||
# 第一个是特殊
|
||
universal_block = Block('universal_minecraft', 'command_block',
|
||
{'conditional': TAG_String("false"), 'facing': TAG_String('up'),
|
||
'mode': TAG_String("repeating")})
|
||
cx, cz = block_coords_to_chunk_coords(dire[0], dire[2])
|
||
chunk = level.get_chunk(cx, cz, "minecraft:overworld")
|
||
offset_x, offset_z = dire[0] - 16 * cx, dire[2] - 16 * cz
|
||
universal_block_entity = BlockEntity('universal_minecraft', 'command_block', dire[0], dire[1], dire[2],
|
||
amulet_nbt.NBTFile(TAG_Compound({'utags': TAG_Compound(
|
||
{'auto': TAG_Byte(0), 'Command': TAG_String(cdl.pop(0))})})))
|
||
chunk.blocks[offset_x, dire[1], offset_z] = level.block_palette.get_add_block(universal_block)
|
||
chunk.block_entities[(dire[0], dire[1], dire[2])] = universal_block_entity
|
||
chunk.changed = True
|
||
# 集体上移
|
||
dire[1] += 1
|
||
# 真正开始
|
||
down = False
|
||
for j in cdl:
|
||
if dire[1] + i >= 255:
|
||
dire[0] += 1
|
||
i = 0
|
||
down = not down
|
||
# 定义此方块
|
||
if dire[1] + i == 254:
|
||
universal_block = Block('universal_minecraft', 'command_block',
|
||
{'conditional': TAG_String("false"), 'facing': TAG_String('east'),
|
||
'mode': TAG_String("chain")})
|
||
else:
|
||
if down:
|
||
universal_block = Block('universal_minecraft', 'command_block',
|
||
{'conditional': TAG_String("false"), 'facing': TAG_String('down'),
|
||
'mode': TAG_String("chain")})
|
||
else:
|
||
universal_block = Block('universal_minecraft', 'command_block',
|
||
{'conditional': TAG_String("false"), 'facing': TAG_String('up'),
|
||
'mode': TAG_String("chain")})
|
||
cx, cz = block_coords_to_chunk_coords(dire[0], dire[2])
|
||
# 获取区块
|
||
chunk = level.get_chunk(cx, cz, "minecraft:overworld")
|
||
offset_x, offset_z = dire[0] - 16 * cx, dire[2] - 16 * cz
|
||
if down:
|
||
# 定义方块实体
|
||
universal_block_entity = BlockEntity('universal_minecraft', 'command_block', dire[0], 254 - i, dire[2],
|
||
amulet_nbt.NBTFile(TAG_Compound({'utags': TAG_Compound(
|
||
{'auto': TAG_Byte(1), 'Command': TAG_String(j)})})))
|
||
|
||
# 将方块加入世界
|
||
chunk.blocks[offset_x, 254 - i, offset_z] = level.block_palette.get_add_block(universal_block)
|
||
chunk.block_entities[(dire[0], 254 - i, dire[2])] = universal_block_entity
|
||
else:
|
||
# 定义方块实体
|
||
universal_block_entity = BlockEntity('universal_minecraft', 'command_block', dire[0], dire[1] + i, dire[2],
|
||
amulet_nbt.NBTFile(TAG_Compound({'utags': TAG_Compound(
|
||
{'auto': TAG_Byte(1), 'Command': TAG_String(j)})})))
|
||
|
||
# 将方块加入世界
|
||
chunk.blocks[offset_x, dire[1] + i, offset_z] = level.block_palette.get_add_block(universal_block)
|
||
chunk.block_entities[(dire[0], dire[1] + i, dire[2])] = universal_block_entity
|
||
# 设置为已更新区块
|
||
chunk.changed = True
|
||
i += 1
|
||
del i, cdl
|
||
# 保存世界并退出
|
||
level.save()
|
||
level.close()
|
||
|
||
|
||
# 音符转成方块再加载到世界里头
|
||
def Blocks2World(world: str, dire: list, Datas: list):
|
||
from nmcsup.const import Blocks
|
||
level = amulet.load_level(world)
|
||
i = 0
|
||
|
||
def setblock(block: str, pos: list):
|
||
"""pos : list[int,int,int]"""
|
||
cx, cz = block_coords_to_chunk_coords(pos[0], pos[2])
|
||
chunk = level.get_chunk(cx, cz, "minecraft:overworld")
|
||
offset_x, offset_z = pos[0] - 16 * cx, pos[2] - 16 * cz
|
||
chunk.blocks[offset_x, pos[1], offset_z] = level.block_palette.get_add_block(Block("minecraft", block))
|
||
chunk.changed = True
|
||
|
||
for j in Datas:
|
||
if dire[1] + 1 >= 255:
|
||
i = 0
|
||
dire[0] += 1
|
||
setblock(Blocks[j[0]], [dire[0], dire[1] + i, dire[2]])
|
||
i = int(i + j[1] + 0.5) # 四舍五入
|
||
level.save()
|
||
level.close()
|
||
|
||
|
||
# 传入音符列表制作播放器指令
|
||
def Notes2Player(Note, dire: list, CmdData: dict):
|
||
"""传入音符列表、坐标、指令数据,生成播放器指令"""
|
||
Notes = {}
|
||
for i in Note:
|
||
Notes[i[0]] = ''
|
||
Notes = list(Notes.keys())
|
||
from nmcsup.const import Blocks
|
||
Cmds = []
|
||
for j in Notes:
|
||
Cmds.append('execute @e[x=' + str(dire[0]) + ',y=' + str(dire[1]) + ',z=' + str(dire[2]) + ',dy=' + str(
|
||
255 - dire[1]) + ',name=' + CmdData['Ent'] + '] ~ ~ ~ detect ~ ~ ~ ' + Blocks[j] + ' 0 execute @a ' +
|
||
CmdData['Pls'] + ' ~ ~ ~ playsound ' + CmdData['Ins'] + ' @s ~ ~ ~ 1000 ' + str(j) + ' 1000\n')
|
||
Cmds += ['#本函数由 金羿 音·创 生成\n', 'execute @e[y=' + str(dire[1]) + ',dy=' + str(255 - dire[1]) + ',name=' + CmdData[
|
||
'Ent'] + '] ~ ~ ~ tp ~ ~1 ~\n',
|
||
'execute @e[y=255,dy=100,name=' + CmdData['Ent'] + '] ~ ~ ~ tp ~1 ' + str(dire[1]) + ' ~\n',
|
||
'#音·创 开发交流群 861684859']
|
||
return Cmds
|
||
|
||
|
||
# 传入音符列表生成方块至世界
|
||
def Datas2BlkWorld(NoteData, world: str, dire: list):
|
||
for i in range(len(NoteData)):
|
||
Blocks2World(world, [dire[0], dire[1], dire[2] + i], NoteData[i])
|