music_quiz: YP/TS 플러그인 의존 제거, 바닐라 playsound + painting_variant 로 마이그레이션

minecraft_launcher 가 만드는 musicquiz 리소스팩 (track_NN / cover_NN)
과 한 쌍으로 동작한다.

- 음원 재생: yp playall (명령 블록 + auto 토글) → /playsound musicquiz:track_NN
- 정답 이미지: ts placeloc → /summon painting (musicquiz:cover_NN) +
  /kill @e[type=painting,tag=mq_cover]
- stopsound 하드코딩(weather) 4곳을 mq:quiz/stop_sound 매크로 호출로 통일
- check/server, repeat/check_server, status 스코어보드(yp/ts/skript) 등
  플러그인 hello 패킷 대기 로직 일괄 삭제
- 스토리지 재구성: command_block 컴파운드 폐기, audio/image/marker 분리
  (init/config.mcfunction 한 곳에서 수정)
- 곡 단위 volume override 지원 — songs[i].volume 으로 곡별 음량 지정 가능
  (미지정 시 audio.volume fallback)
- 트랙 번호 zero-pad 는 mq:tmp.pad 분기 + 매크로 문자열 조립으로 처리
- max_index 는 songs 배열 길이에서 자동 계산
- 호출 경로 단축: select → setanswer → macro/setanswer → macro/summon →
  play_sound
This commit is contained in:
Claude (owner)
2026-05-13 16:25:05 +09:00
parent b2361187b9
commit cea3d29c7d
29 changed files with 187 additions and 181 deletions

View File

@@ -1,3 +0,0 @@
title @a times 0t 20t 0t
title @a subtitle {"text":"이 맵은 버킷 서버에서 열어야 합니다."}
title @a title {"text":"오류 발생!","color":"red"}

View File

@@ -5,5 +5,5 @@ execute if score init main matches 1..4 run return run function mq:tellraw {"tex
execute if score init main matches 6.. run return run function mq:tellraw {"text":"아직 다음노래가 재생되지 않았습니다.","color":"red",msg:'""'}
execute if score init main matches 10 run return run function mq:tellraw {"text":"퀴즈가 종료되었습니다.","color":"red",msg:'""'}
execute if score init main matches 5 run stopsound @a weather
execute if score init main matches 5 run function mq:quiz/macro/command_block with storage mq:main command_block
execute if score init main matches 5 run function mq:quiz/stop_sound
execute if score init main matches 5 run function mq:quiz/play_sound

View File

@@ -2,7 +2,7 @@ execute if score init main matches 10 run return run function mq:tellraw {"text"
setblock ~ ~ ~ minecraft:air
stopsound @a weather
function mq:quiz/stop_sound
$scoreboard players set max_index main $(max_index)
scoreboard players set init main 1

View File

@@ -1,8 +1,3 @@
scoreboard players set timer status 0
scoreboard players set skript status 0
scoreboard players set yp status 0
scoreboard players set ts status 0
scoreboard players set index main 0
$scoreboard players set max_index main $(max_index)
scoreboard players set score main 0
@@ -43,8 +38,6 @@ scoreboard objectives remove score
scoreboard objectives add score dummy {"text":"점수","bold":true}
scoreboard objectives setdisplay sidebar score
data modify storage mq:main command_block.index set value 1
dialog clear @a
bossbar set mq:process name [{"text":"진행도: ","color": "yellow","bold": true},{"score":{"name":"index","objective": "main"},"color": "yellow","bold": true},{"text":"/","color": "yellow","bold": true},{"score":{"name":"max_index","objective": "main"},"color": "yellow","bold": true}]
@@ -55,9 +48,12 @@ bossbar set mq:process visible false
bossbar set mq:process style notched_10
bossbar set mq:process players @a
data modify storage mq:main command_block.name set value "음악퀴즈"
function mq:quiz/macro/summon with storage mq:main command_block
# 대기 상태 marker 1개만 소환 (answer.title="음악퀴즈" 가 sentinel)
data modify storage mq:main answer set value {title:"음악퀴즈", alias:[]}
data modify storage mq:tmp marker_call set from storage mq:main marker
data modify storage mq:tmp marker_call.name set value "음악퀴즈"
data modify storage mq:tmp marker_call.alias set value []
function mq:quiz/macro/summon with storage mq:tmp marker_call
stopsound @a weather
function mq:images/image_delete with storage mq:main command_block
function mq:quiz/stop_sound
function mq:images/clear

View File

@@ -0,0 +1 @@
kill @e[type=minecraft:painting,tag=mq_cover]

View File

@@ -1,3 +0,0 @@
$data modify storage mq:main command_block.image set value "ts placeloc song$(index).jpg world SOUTH $(x1) $(y1) $(z1) $(x2) $(y2) $(z2) 1 솔리드스킵"
function mq:images/image_set with storage mq:main command_block

View File

@@ -1,4 +0,0 @@
$data modify block $(x) $(y) $(z) Command set value "ts removeall"
$data modify block $(x) $(y) $(z) auto set value 1b
$data modify block $(x) $(y) $(z) auto set value 0b

View File

@@ -1,4 +0,0 @@
$data modify block $(x) $(y) $(z) Command set value "$(image)"
$data modify block $(x) $(y) $(z) auto set value 1b
$data modify block $(x) $(y) $(z) auto set value 0b

View File

@@ -0,0 +1 @@
$summon minecraft:painting $(x) $(y) $(z) {variant:"$(namespace):$(cover)",facing:$(facing)b,Tags:["mq","mq_cover"]}

View File

@@ -0,0 +1,3 @@
data modify storage mq:tmp painting set from storage mq:main image
data modify storage mq:tmp painting.cover set from storage mq:main answer.cover
function mq:images/macro/show with storage mq:tmp painting

View File

@@ -1,26 +1,23 @@
# 음악퀴즈 주제 — tellraw 접두사([ 이름 ])와 사이드바 표시에 사용
data modify storage mq:main title set value "음악퀴즈"
# 곡 개수 — init/songs.mcfunction 의 곡 수와 일치시킬 것
data modify storage mq:main max_index set value 50
# 플레이어 접속 시 텔레포트 위치 (x y z, r=yaw, f=pitch)
data modify storage mq:main spawn set value {x: 144, y: 61, z: -219, r: 180, f: 0}
# 음원 재생용 명령 블록 위치 + 정답 이미지 표시 영역
# x,y,z — 명령 블록 좌표
# r — 명령 블록 정면 방향 (EAST | WEST | SOUTH | NORTH)
# volume yp playall 명령에 넘기는 음량
# x1,y1,z1 — 이미지 표시 영역 한쪽 모서리
# x2,y2,z2 — 이미지 표시 영역 반대 모서리
data modify storage mq:main command_block set value { \
name: "", \
image: "", \
alias: [], \
index: 1, \
volume: 30, \
x: 144, y: 59, z: -219, \
r: "SOUTH", \
x1: 131, y1: 77, z1: -262, \
x2: 157, y2: 91, z2: -262 \
}
# 음원 재생 — minecraft_launcher 리소스팩의 musicquiz:track_NN 사운드 이벤트
# namespace — 리소스팩 네임스페이스 (기본 "musicquiz")
# source — /playsound 채널. stopsound 와 동일해야 함 (기본 "weather")
# volume — 기본 음량. 곡별 override 는 init/songs.mcfunction 의 volume 필드 사용
# pitch — 1.0 = 원본 속도
data modify storage mq:main audio set value {namespace: "musicquiz", source: "weather", volume: 1.0, pitch: 1.0}
# 정답 페인팅 — minecraft_launcher 리소스팩의 musicquiz:cover_NN painting_variant
# namespace — painting_variant 네임스페이스 (기본 "musicquiz")
# x,y,z — 페인팅 entity 좌표 (벽면 앞쪽 블록 위치)
# facing — 페인팅이 바라보는 방향: south=0 / west=1 / north=2 / east=3
data modify storage mq:main image set value {namespace: "musicquiz", x: 144, y: 84, z: -261, facing: 0b}
# 정답 입력용 marker entity 소환 좌표
data modify storage mq:main marker set value {x: 144, y: 59, z: -219}
# 곡 개수 max_index 는 init/songs.mcfunction 의 길이로 자동 계산됨

View File

@@ -1,3 +1,9 @@
# 곡 한 개 = 한 줄.
# 필수 — title, author, alias
# 선택 — volume (이 곡만의 /playsound 음량. 미지정시 init/config.mcfunction
# 의 audio.volume 사용)
# 곡 순서가 리소스팩의 track_NN / cover_NN 인덱스와 1:1 매칭된다.
# 예) {title:"Quiet Song", author:"...", alias:[...], volume:2.0}
data modify storage mq:main songs set value []
data modify storage mq:main songs append value {title:"Lose My Mind", author:"Don Toliver", alias:[" "," "," "]}
data modify storage mq:main songs append value {title:"The Chase", author:"Hearts2Hearts", alias:[" "," "," "]}
@@ -49,3 +55,6 @@ data modify storage mq:main songs append value {title:"XOXZ", author:"IVE", alia
data modify storage mq:main songs append value {title:"여름이었다", author:"H1-KEY", alias:[]}
data modify storage mq:main songs append value {title:"LOV3", author:"식케이", alias:["3","3"]}
data modify storage mq:main songs append value {title:"Drive", author:"Ed Sheeran", alias:["",""]}
# 곡 개수는 songs 배열 길이에서 자동 계산됨
execute store result storage mq:main max_index int 1 run data get storage mq:main songs

View File

@@ -1,4 +1,4 @@
data modify storage mq:main answer set value {author: "", title: "", alias: []}
data modify storage mq:main answer set value {title:"", author:"", alias:[]}
data merge storage func:temp {}
data merge storage mq:tmp {}
@@ -10,24 +10,17 @@ function mq:init/triggers
function mq:tellraw {"text":"서버 리로드 성공!","color":"white","msg":'""'}
scoreboard objectives remove func.temp
scoreboard objectives remove status
scoreboard objectives remove main
scoreboard objectives remove buttons
scoreboard objectives remove answer
scoreboard objectives remove leave_game
scoreboard objectives add func.temp dummy
scoreboard objectives add status dummy
scoreboard objectives add main dummy
scoreboard objectives add buttons dummy
scoreboard objectives add answer dummy
scoreboard objectives add leave_game custom:leave_game
scoreboard players set timer status 0
scoreboard players set skript status 0
scoreboard players set yp status 0
scoreboard players set ts status 0
scoreboard players set two func.temp 2
bossbar add mq:process [{"text":"진행도: ","color": "yellow","bold": true},{"text":"0","color": "yellow","bold": true},{"text":"/","color": "yellow","bold": true},{"text":"0","color": "yellow","bold": true}]

View File

@@ -29,4 +29,4 @@ scoreboard players set replay buttons -3
scoreboard players set timer main 1
function mq:images/image with storage mq:main command_block
function mq:images/show

View File

@@ -1,3 +0,0 @@
$data modify block $(x) $(y) $(z) Command set value "yp playall song$(index) $(volume)"
function mq:quiz/play with storage mq:main command_block

View File

@@ -0,0 +1 @@
$execute as @a at @s run playsound $(namespace):$(track) $(source) @s ~ ~ ~ $(volume) $(pitch)

View File

@@ -1,3 +1,3 @@
$data modify storage mq:main answer set from storage mq:main songs[$(idx)]
$data modify storage mq:main command_block.name set from storage mq:main songs[$(idx)].title
$data modify storage mq:main command_block.alias set from storage mq:main songs[$(idx)].alias
$data modify storage mq:main answer.track set value "track_$(pad)$(num)"
$data modify storage mq:main answer.cover set value "cover_$(pad)$(num)"

View File

@@ -0,0 +1 @@
$stopsound @a $(source)

View File

@@ -1,8 +1,9 @@
$execute unless data storage mq:main {command_block:{name:"음악퀴즈"}} run summon minecraft:marker $(x) $(y) $(z) {Tags:["mq","default"],CustomName:"정답입력시작"}
$execute unless data storage mq:main {answer:{title:"음악퀴즈"}} run summon minecraft:marker $(x) $(y) $(z) {Tags:["mq","default"],CustomName:"정답입력시작"}
$summon minecraft:marker $(x) $(y) $(z) {Tags:["mq","default"],CustomName:"$(name)"}
execute store result score length func.temp run data get storage mq:main command_block.alias
execute if score length func.temp matches 1.. run data modify storage mq:main command_block.name set from storage mq:main command_block.alias[0]
execute if score length func.temp matches 1.. run data remove storage mq:main command_block.alias[0]
execute if score length func.temp matches 1.. run function mq:quiz/macro/summon2 with storage mq:main command_block
$execute unless data storage mq:main {command_block:{name:"음악퀴즈"}} run summon minecraft:marker $(x) $(y) $(z) {Tags:["mq","default"],CustomName:"정답입력종료"}
execute store result score length func.temp run data get storage mq:tmp marker_call.alias
execute if score length func.temp matches 1.. run data modify storage mq:tmp marker_call.name set from storage mq:tmp marker_call.alias[0]
execute if score length func.temp matches 1.. run data remove storage mq:tmp marker_call.alias[0]
execute if score length func.temp matches 1.. run function mq:quiz/macro/summon2 with storage mq:tmp marker_call
$execute unless data storage mq:main {answer:{title:"음악퀴즈"}} run summon minecraft:marker $(x) $(y) $(z) {Tags:["mq","default"],CustomName:"정답입력종료"}

View File

@@ -1,6 +1,6 @@
$summon minecraft:marker $(x) $(y) $(z) {Tags:["mq","default"],CustomName:"$(name)"}
execute store result score length func.temp run data get storage mq:main command_block.alias
execute if score length func.temp matches 1.. run data modify storage mq:main command_block.name set from storage mq:main command_block.alias[0]
execute if score length func.temp matches 1.. run data remove storage mq:main command_block.alias[0]
execute if score length func.temp matches 1.. run function mq:quiz/macro/summon2 with storage mq:main command_block
execute store result score length func.temp run data get storage mq:tmp marker_call.alias
execute if score length func.temp matches 1.. run data modify storage mq:tmp marker_call.name set from storage mq:tmp marker_call.alias[0]
execute if score length func.temp matches 1.. run data remove storage mq:tmp marker_call.alias[0]
execute if score length func.temp matches 1.. run function mq:quiz/macro/summon2 with storage mq:tmp marker_call

View File

@@ -1,6 +0,0 @@
scoreboard players set init main 4
$data modify block $(x) $(y) $(z) auto set value 1b
$data modify block $(x) $(y) $(z) auto set value 0b
function mq:quiz/setanswer

View File

@@ -0,0 +1,5 @@
data modify storage mq:tmp playsound set from storage mq:main audio
data modify storage mq:tmp playsound.track set from storage mq:main answer.track
# 곡 단위 volume override — songs[i].volume 가 없으면 audio.volume 그대로 유지 (no-op)
data modify storage mq:tmp playsound.volume set from storage mq:main answer.volume
function mq:quiz/macro/play_sound with storage mq:tmp playsound

View File

@@ -1,14 +1,20 @@
scoreboard players add init main 3
scoreboard players set timer main 0
execute if score index main >= max_index main run return run function mq:quiz/end with storage mq:main
scoreboard players add index main 1
execute store result storage mq:main command_block.index int 1 run scoreboard players get index main
# 보스바
bossbar set mq:process name [{"text":"진행도: ","color": "yellow","bold": true},{"score":{"name":"index","objective": "main"},"color": "yellow","bold": true},{"text":"/","color": "yellow","bold": true},{"score":{"name":"max_index","objective": "main"},"color": "yellow","bold": true}]
bossbar set mq:process players @a
execute store result bossbar mq:process value run scoreboard players get index main
function mq:quiz/macro/command_block with storage mq:main command_block
# tmp.{idx (0-based, songs[] 인덱스), num (1-based, track_NN), pad ("0"|"")} 구성
execute store result storage mq:tmp num int 1 run scoreboard players get index main
scoreboard players operation song_idx func.temp = index main
scoreboard players remove song_idx func.temp 1
execute store result storage mq:tmp idx int 1 run scoreboard players get song_idx func.temp
execute if score index main matches 1..9 run data modify storage mq:tmp pad set value "0"
execute unless score index main matches 1..9 run data modify storage mq:tmp pad set value ""
function mq:quiz/setanswer

View File

@@ -1,13 +1,17 @@
scoreboard players operation song_idx func.temp = index main
scoreboard players remove song_idx func.temp 1
execute store result storage mq:tmp idx int 1 run scoreboard players get song_idx func.temp
# songs[$(idx)] → answer 로 복사하고, 트랙/커버 id 부여
function mq:quiz/macro/setanswer with storage mq:tmp
# 정답 marker entity 소환 (좌표 + name/alias 합쳐서 macro 호출)
data modify storage mq:tmp marker_call set from storage mq:main marker
data modify storage mq:tmp marker_call.name set from storage mq:main answer.title
data modify storage mq:tmp marker_call.alias set from storage mq:main answer.alias
function mq:quiz/macro/summon with storage mq:tmp marker_call
scoreboard players set stop buttons -1
scoreboard players set skip buttons -1
scoreboard players set hint buttons -1
scoreboard players set replay buttons -1
scoreboard players set init main 5
function mq:quiz/macro/summon with storage mq:main command_block
function mq:quiz/play_sound

View File

@@ -0,0 +1 @@
function mq:quiz/macro/stop_sound with storage mq:main audio

View File

@@ -1,12 +0,0 @@
execute if score timer status matches 20.. \
if score skript status matches 0 \
if score yp status matches 0 \
if score ts status matches 0 \
run return run function mq:check/server
execute if score timer status matches 0.. run scoreboard players add timer status 1
execute if score timer status matches 1..10 run scoreboard players set skript status 0
execute if score timer status matches 1..10 run scoreboard players set yp status 0
execute if score timer status matches 1..10 run scoreboard players set ts status 0
execute if score timer status matches 21.. run scoreboard players set timer status -1

View File

@@ -26,7 +26,7 @@ execute if score init main matches 2 if score timer main matches 100.. run funct
# next song timer
execute if score init main matches 6 if score timer main matches 300 run title @a title {"text":""}
execute if score init main matches 6 if score timer main matches 290 run function mq:images/image_delete with storage mq:main command_block
execute if score init main matches 6 if score timer main matches 290 run function mq:images/clear
execute if score init main matches 6 if score timer main matches 300.. run function mq:quiz/select with storage mq:main
# endding timer

View File

@@ -1,4 +1,3 @@
function mq:repeat/check_server
function mq:repeat/players
function mq:repeat/buttons/handler
function mq:repeat/triggers/handler