Compare commits
2 Commits
cea3d29c7d
...
cfe6a41888
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cfe6a41888 | ||
|
|
7adcda68de |
6
music_quiz/data/minecraft/tags/dialog/quick_actions.json
Normal file
6
music_quiz/data/minecraft/tags/dialog/quick_actions.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"replace": false,
|
||||||
|
"values": [
|
||||||
|
"mq:answer"
|
||||||
|
]
|
||||||
|
}
|
||||||
26
music_quiz/data/mq/dialog/answer.json
Normal file
26
music_quiz/data/mq/dialog/answer.json
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"type": "minecraft:simple_input_form",
|
||||||
|
"title": {
|
||||||
|
"text": "정답 입력",
|
||||||
|
"bold": true
|
||||||
|
},
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"type": "minecraft:text",
|
||||||
|
"key": "text",
|
||||||
|
"label": {
|
||||||
|
"text": "정답"
|
||||||
|
},
|
||||||
|
"width": 300,
|
||||||
|
"max_length": 64,
|
||||||
|
"initial": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"can_close_with_escape": true,
|
||||||
|
"pause": false,
|
||||||
|
"after_action": "close",
|
||||||
|
"action": {
|
||||||
|
"type": "minecraft:dynamic/run_command",
|
||||||
|
"template": "function mq:answer/submit {text:'$(text)'}"
|
||||||
|
}
|
||||||
|
}
|
||||||
10
music_quiz/data/mq/function/answer/iter_aliases.mcfunction
Normal file
10
music_quiz/data/mq/function/answer/iter_aliases.mcfunction
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# aliases 배열 첫 원소와 비교 → 매치 시 즉시 종료, 아니면 pop 후 재귀
|
||||||
|
execute store result score alen func.temp run data get storage mq:tmp aliases
|
||||||
|
execute if score alen func.temp matches 0 run return 0
|
||||||
|
|
||||||
|
data modify storage mq:tmp judge.answer set from storage mq:tmp aliases[0]
|
||||||
|
function mq:answer/macro/match with storage mq:tmp judge
|
||||||
|
data remove storage mq:tmp aliases[0]
|
||||||
|
|
||||||
|
execute if score @s answer matches 1 run return 0
|
||||||
|
function mq:answer/iter_aliases
|
||||||
17
music_quiz/data/mq/function/answer/judge.mcfunction
Normal file
17
music_quiz/data/mq/function/answer/judge.mcfunction
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# 제출자(@s) 로 실행됨 — answer.title 및 alias 들과 비교
|
||||||
|
# 매치되면 @s answer = 1 → check_answer 가 정답처리 흐름으로 진입
|
||||||
|
# 매치 안되면 @s answer = 2 → check_answer 가 reset 처리 (1회 비교 후 초기화)
|
||||||
|
|
||||||
|
# 1) 제목과 비교
|
||||||
|
data modify storage mq:tmp judge.answer set from storage mq:main answer.title
|
||||||
|
function mq:answer/macro/match with storage mq:tmp judge
|
||||||
|
|
||||||
|
# 2) 제목 매치 실패 시 alias 들과 순차 비교 (조기 종료)
|
||||||
|
execute unless score @s answer matches 1 run data modify storage mq:tmp aliases set from storage mq:main answer.alias
|
||||||
|
execute unless score @s answer matches 1 run function mq:answer/iter_aliases
|
||||||
|
|
||||||
|
# 3) 끝까지 매치 실패면 오답 처리 (check_answer 가 reset)
|
||||||
|
execute unless score @s answer matches 1 run scoreboard players set @s answer 2
|
||||||
|
|
||||||
|
# 4) 처리 완료 — 이 제출자의 submit_seq 정리 (다음 큐 항목과 혼동 방지)
|
||||||
|
scoreboard players reset @s submit_seq
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
# queue entry 의 seq 점수를 가진 플레이어(@s) 컨텍스트로 judge 실행
|
||||||
|
$execute as @a[scores={submit_seq=$(seq)},limit=1] run function mq:answer/judge
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
# judge.input 과 judge.answer 가 같으면 @s answer = 1
|
||||||
|
# 매크로 치환으로 answer 필드를 NBT predicate 의 리터럴로 박아넣음
|
||||||
|
$execute if data storage mq:tmp judge {input:"$(answer)"} run scoreboard players set @s answer 1
|
||||||
4
music_quiz/data/mq/function/answer/open.mcfunction
Normal file
4
music_quiz/data/mq/function/answer/open.mcfunction
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# trigger input 으로 호출됨 — 다음 trigger 사용을 위해 즉시 재활성화 후 dialog 표시
|
||||||
|
scoreboard players reset @s input
|
||||||
|
scoreboard players enable @s input
|
||||||
|
dialog show @s mq:answer
|
||||||
17
music_quiz/data/mq/function/answer/process.mcfunction
Normal file
17
music_quiz/data/mq/function/answer/process.mcfunction
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# tick 에서 매 tick 호출됨 — 큐의 가장 먼저 제출된 항목 1개를 처리
|
||||||
|
# 1 tick 당 1건 처리 — 동시 다발 제출은 FIFO 순서로 자동 직렬화됨
|
||||||
|
execute store result score qlen func.temp run data get storage mq:input queue
|
||||||
|
execute if score qlen func.temp matches 0 run return 0
|
||||||
|
|
||||||
|
# 첫번째 항목 = 가장 먼저 제출된 것
|
||||||
|
data modify storage mq:tmp judge set value {input:"", answer:""}
|
||||||
|
data modify storage mq:tmp judge.input set from storage mq:input queue[0].text
|
||||||
|
|
||||||
|
# 매크로로 해당 seq 를 가진 플레이어 찾아서 judge 실행
|
||||||
|
data modify storage mq:tmp _find set value {seq:0}
|
||||||
|
data modify storage mq:tmp _find.seq set from storage mq:input queue[0].seq
|
||||||
|
|
||||||
|
# 항목 제거 (한 번 비교했으면 큐에서 빼기)
|
||||||
|
data remove storage mq:input queue[0]
|
||||||
|
|
||||||
|
function mq:answer/macro/find_submitter with storage mq:tmp _find
|
||||||
14
music_quiz/data/mq/function/answer/submit.mcfunction
Normal file
14
music_quiz/data/mq/function/answer/submit.mcfunction
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
# 정답 dialog 제출 핸들러 — 매크로 인자 {text:"..."} 받음
|
||||||
|
# 퀴즈 진행 중(init=5) 이 아니면 제출 무시
|
||||||
|
execute unless score init main matches 5 run return 0
|
||||||
|
|
||||||
|
# 제출 순번 부여 — seq 는 setanswer 에서 0 으로 초기화됨
|
||||||
|
# 동일 tick 내 동시 제출도 명령 실행 순서대로 1씩 증가하여 고유한 seq 가 부여됨
|
||||||
|
scoreboard players add seq func.temp 1
|
||||||
|
scoreboard players operation @s submit_seq = seq func.temp
|
||||||
|
|
||||||
|
# 큐에 {text, seq} append — process 는 queue[0] (가장 먼저 제출된 것) 부터 처리
|
||||||
|
data modify storage mq:tmp new_entry set value {text:"", seq:0}
|
||||||
|
execute store result storage mq:tmp new_entry.seq int 1 run scoreboard players get @s submit_seq
|
||||||
|
$data modify storage mq:tmp new_entry.text set value "$(text)"
|
||||||
|
data modify storage mq:input queue append from storage mq:tmp new_entry
|
||||||
@@ -13,6 +13,11 @@ scoreboard players set test buttons -1
|
|||||||
|
|
||||||
scoreboard players reset @a answer
|
scoreboard players reset @a answer
|
||||||
|
|
||||||
|
# 정답 입력 큐 / 제출 순번 초기화
|
||||||
|
data remove storage mq:input queue
|
||||||
|
scoreboard players reset @a submit_seq
|
||||||
|
scoreboard players set seq func.temp 0
|
||||||
|
|
||||||
# 트리거 시작
|
# 트리거 시작
|
||||||
scoreboard objectives remove ready
|
scoreboard objectives remove ready
|
||||||
scoreboard objectives add ready trigger
|
scoreboard objectives add ready trigger
|
||||||
@@ -31,8 +36,15 @@ scoreboard objectives add hint trigger
|
|||||||
|
|
||||||
scoreboard objectives remove replay
|
scoreboard objectives remove replay
|
||||||
scoreboard objectives add replay trigger
|
scoreboard objectives add replay trigger
|
||||||
|
|
||||||
|
scoreboard objectives remove input
|
||||||
|
scoreboard objectives add input trigger
|
||||||
# 트리거 끝
|
# 트리거 끝
|
||||||
|
|
||||||
|
# 제출자 식별용 순번 점수 (queue entry 의 seq 와 매칭)
|
||||||
|
scoreboard objectives remove submit_seq
|
||||||
|
scoreboard objectives add submit_seq dummy
|
||||||
|
|
||||||
scoreboard objectives setdisplay sidebar
|
scoreboard objectives setdisplay sidebar
|
||||||
scoreboard objectives remove score
|
scoreboard objectives remove score
|
||||||
scoreboard objectives add score dummy {"text":"점수","bold":true}
|
scoreboard objectives add score dummy {"text":"점수","bold":true}
|
||||||
|
|||||||
@@ -2,6 +2,10 @@ data modify storage mq:main answer set value {title:"", author:"", alias:[]}
|
|||||||
data merge storage func:temp {}
|
data merge storage func:temp {}
|
||||||
data merge storage mq:tmp {}
|
data merge storage mq:tmp {}
|
||||||
|
|
||||||
|
# chat_answer 모드 활성화 플래그 초기화. 모드가 살아있으면 첫 플레이어 로그인 직후
|
||||||
|
# 모드가 다시 1b 로 set 함. 모드가 빠지면 이대로 0b 유지 → 로그인 메세지 미표시.
|
||||||
|
data modify storage chat_answer:status active set value 0b
|
||||||
|
|
||||||
function mq:init/config
|
function mq:init/config
|
||||||
function mq:init/songs
|
function mq:init/songs
|
||||||
function mq:init/buttons
|
function mq:init/buttons
|
||||||
|
|||||||
@@ -8,3 +8,7 @@ title @s title ""
|
|||||||
$setworldspawn $(x) $(y) $(z) $(r) $(f)
|
$setworldspawn $(x) $(y) $(z) $(r) $(f)
|
||||||
$tp @s $(x) $(y) $(z) $(r) $(f)
|
$tp @s $(x) $(y) $(z) $(r) $(f)
|
||||||
gamemode adventure @s
|
gamemode adventure @s
|
||||||
|
|
||||||
|
# chat_answer 모드가 살아있으면 PlayerLoggedInEvent 핸들러가 active=1b 로 set.
|
||||||
|
# mq:load 에서 0b 로 초기화되어 있으므로, 1b 인 상황 = 모드 활성.
|
||||||
|
execute if data storage chat_answer:status {active:1b} run tellraw @s ["",{"text":"[채팅정답] ","color":"green","bold":true},{"text":"모드가 활성화되어 있습니다.","color":"gray"},{"text":" 정답 입력 시 ","color":"gray"},{"text":"채팅","color":"yellow","bold":true},{"text":"으로 바로 제출할 수 있습니다.","color":"gray"}]
|
||||||
|
|||||||
@@ -12,6 +12,15 @@ scoreboard players set skip buttons -1
|
|||||||
scoreboard players set hint buttons -1
|
scoreboard players set hint buttons -1
|
||||||
scoreboard players set replay buttons -1
|
scoreboard players set replay buttons -1
|
||||||
|
|
||||||
|
# 이전 문제의 미처리 정답 입력 정리 + 새 문제의 input trigger 활성화
|
||||||
|
data remove storage mq:input queue
|
||||||
|
scoreboard players reset @a submit_seq
|
||||||
|
scoreboard players set seq func.temp 0
|
||||||
|
scoreboard players enable @a input
|
||||||
|
|
||||||
|
# 정답 입력 안내 (클릭 시 trigger input → tick 에서 dialog 오픈)
|
||||||
|
function mq:tellraw {"text":"","color":"black",msg:[{"text":"[ 정답 입력 ]","color":"green","bold":true,"click_event":{"action":"run_command","command":"/trigger input set 1"},"hover_event":{"action":"show_text","value":{"text":"클릭하여 정답 입력창 열기","color":"gray"}}}]}
|
||||||
|
|
||||||
scoreboard players set init main 5
|
scoreboard players set init main 5
|
||||||
|
|
||||||
function mq:quiz/play_sound
|
function mq:quiz/play_sound
|
||||||
|
|||||||
@@ -4,3 +4,7 @@ function mq:repeat/triggers/handler
|
|||||||
|
|
||||||
execute if score init main matches 2.. run function mq:repeat/timer
|
execute if score init main matches 2.. run function mq:repeat/timer
|
||||||
execute if score init main matches 5..6 run function mq:repeat/check_answer
|
execute if score init main matches 5..6 run function mq:repeat/check_answer
|
||||||
|
|
||||||
|
# 정답 입력 다이얼로그: init=5 (곡 재생 중) 일 때만 열림 / 제출 처리
|
||||||
|
execute if score init main matches 5 as @a[scores={input=1..}] run function mq:answer/open
|
||||||
|
execute if score init main matches 5 run function mq:answer/process
|
||||||
|
|||||||
Reference in New Issue
Block a user