사실 나아중에 만드려고 했는데 맵 만들기 귀찮아서 이거먼저 만들게 됨
이것은 초심자가 만든초심자용이며, 틀린 정보가 있을 수 있음
이 글은 글쓴이 본인의 주관이 매우 많이 첨가되어 있음
0.기본 설명
0-1.버전
이 게시글은 1.21.10버전을 기준으로 만들어졌음
버전이 명시되지 않았다면 1.21.10이라고 생각하면 된다
0-2.도구
도구라고 하는게 맞는진 모르겠는데 일단 이 게시글은 함수 설명시 메모장을 기준으로 설명함
vs코드라는 프로그램이 있지만(아래서 설명 예정), 일단 본인은 쓰지 않으니 모름
메모장과 vs코드의 차이점은 다른데서 알아보셈
0-3.뜻
api는 방장의 그 api를 말하는거임
storage chat같은건 storage minecraft:chat과 같은 의미임
0-4.알아야하는거
맵 안에서 함수를 업데이트했을때는 반드시 /reload를 해야함
이 게시글에서 파란색 밑줄쳐진 기울어진 글씨를 발견한다면 클릭시 다른 사이트로 이동된다
전 게시글에 있는건 다루지 않음
후원api는 다루지 않음별 다를것도 없고, 방장이 후원api는 잘 안다룬다고 했음
1.채팅 api
일단 재밌음
치지직 채팅을 통해
!(명령어) (채팅)
을 입력하면 마인크래프트에
1.채팅자의 닉네임 nick
2.(명령어)부분 command
3.(채팅)부분 chat_all
4.','를 통해 나누어진 chat1,chat2...
예를들어 ㅣ디노니ㅣ라는 사람(본인)이
!정답 마바플보,169.9,momo is dog
라고 입력을 했다면 storage chat에
1.채팅자의 닉네임이 nick:"ㅣ디노니ㅣ"로 저장된다
2.(명령어)부분에 command:"정답"가 저장된다
3.(채팅)부분에 chat_all:"마바플보,169.9,momo is dog"가 저장된다
4.','를 통해 나누어진 채팅은 chat1:"마바플보",chat2:"169.9",chat3:"momo is dog"로 저장된다
이걸 전부 합치면
{nick:"ㅣ디노니ㅣ",command:"정답",chat_all:"마바플보,169.9,momo is dog",chat1:"마바플보",chat2:"169.9",chat3:"momo is dog"}
가 된다
하지만 실제로 저장될때는 storage chat에
{data:[{nick:"ㅣ디노니ㅣ",command:"정답",chat_all:"마바플보,169.9,momo is dog",chat1:"마바플보",chat2:"169.9",chat3:"momo is dog"}]}
로 된다
하지만 채팅이 들어온다면
/function chzzkapi:chat with storage minecraft:chat
가 실행된다
이런 storage를 쓰는 함수매크로는 어떤식으로 될까?
2.storage
난 처음에 함수 매크로를 배웠을때 storage를 잘 쓰지 않으려고 했었음
눈으로 직접 보기 쉽지 않고, 명령어를 통해서만 접근을 해야하기 때문임
하지만 '자유로움'이라는게 아주 큼
마인크래프트를 처음 배울땐 뭐든 해보는게 중요함
storage도 마찬가지임
data merge, modify를 통해 뭐든 넣어보고, data get을 통해 알아봐야함
{nick:"ㅣ디노니ㅣ",command:"정답",chat_all:"마바플보,169.9,momo is dog",chat1:"마바플보",chat2:"169.9",chat3:"momo is dog"}
storage chat에 이런식으로 들어가있을땐
/data get storage chat
으로 이런 출력값을 얻을 수 있고,
/data get storage chat nick
로 nick에 해당하는 "ㅣ디노니ㅣ"를 얻을 수 있음
하지만
{data:[{nick:"ㅣ디노니ㅣ",command:"정답",chat_all:"마바플보,169.9,momo is dog",chat1:"마바플보",chat2:"169.9",chat3:"momo is dog"}]}
이런경우
/data get storage chat
으로 하면 그대로의 출력값을 얻을 수 있지만,
/data get storage chat nick
로 하면 오류가 난다
그 이유는 nick가 바로 밖으로 나와있는 것이 아니기 때문임
그래서 nick를 얻고싶으면
/data get storage chat data[0].nick
로 구해야함
data[0].nick
는 chat의 경로임
data
현재 경로(가장 바깥)에 있는 data임
[0]
data의 [ ]로 둘러쌓여있는 첫번째것을 뜻함
첫번째인데 왜 0이냐구?
그냥 -1하면 된다고 생각하셈
.
.은 그 앞의 경로 안에 무언가 있다는것을 의미함
nick
현재 경로(data[0])에 있는 nick를 의미함
즉, data[0].nick는
data의 첫번째 [ ] 안에 있는 nick를 의미함
저번 게시글에선 가장 바깥에 있는것만 다뤘음
하지만 채팅 api는 가장 바깥에 있는 data는 별로 쓸모가 없음
data[0] 안에 있는것이 중요하지
data get과 마찬가지로 function a:b with에도 경로가 필요함
이런 경우에선 function a:b with storage ...이 들어가겠지
그러니
/function chzzkapi:chat with storage chat
가 들어가야 chat 안에있는걸 꺼내 쓸 수 있지만,
이렇게 하면 data get storage chat과 마찬가지로 data부터 나오기 때문에
/function chzzkapi:chat with storage chat data[0]
을 통해 실행해야 nick이든 chat_all이든 함수매크로를 통해 쓸 수 있는거임
3.채팅 api에 매크로 넣는 방법
하지만 api공지에 따르면 채팅시에는
function chzzkapi:chat with storage chat
으로 실행이 된다
그러면 어떻게 해야할까?
직접
function chzzkapi:chat with storage chat data[0]
로 실행되게 만들어줘야 함
물론 다른 방법들도 많지만, 나는 이게 제일 쉽다고 생각함
이쯤되면 궁금한게이들이 있을거임
그냥 매크로 안에 $(data[0].nick)로 집어넣으면 되는거 아닌가?
하지만 이렇게 매크로에 경로를 넣으면 안된다
매크로에 경로를 넣으면 함수를 인식하지 못해 함수가 사라지게 된다
그래서 나는 chzzkapi:chat에는 함수매크로를 넣지 않음
대신 chzzkapi:chat에는
function chzzkapi:real with storage chat data[0]
을 넣음
그러고 real에 매크로를 사용하지
4.채팅 값 감지하는 방법
채팅 api맵에서는 대체로 그 채팅이 '이것'일때 실행되는 커맨드가 있음
'이것'을 어떻게 정하는 것일까?
execute에는 if data라는게 있음
여기에는 data get이나 function ... with과 마찬가지로 경로를 입력할 수 있지
물론 경로는 경로만 입력할 수 있음
그러면 왜 알려준거냐구?
우린 이걸 쓸거임
경로만 입력할 수 있다고 하지 않았냐구?
'경로는' 경로만 입력할 수 있다고 했지 경로만 입력할 수 있다고는 안했음
이번엔 data get이 아닌 data merge를 봐야함
물론 data get에서 경로는 참고하는게 좋지
명령어는 data merge를 보는걸 추천함
data merge는 data get처럼 경로를 입력하지 않음
대신 처음부터 원하는 내용에 도달할때까지 직접 다 입력해줘야하지
예를들어 storage chat에
{data:[{nick:"ㅣ디노니ㅣ",command:"정답",chat_all:"마바플보,169.9,momo is dog",chat1:"마바플보",chat2:"169.9",chat3:"momo is dog"}]}
이렇게 되어있고, nick를 수정하고 싶다면
/data merge storage chat {data:[{nick:"(수정할 내용)"}]}
을 통해 입력해야 함
자 이제 execute if data로 돌아와서
execute if data에는 경로만 들어가는게 아님
{data:[{nick:"ㅣ디노니ㅣ"}]} 같은것도 들어간다
그래서 execute if data에 {data:[{nick:"ㅣ디노니ㅣ"}]}를 넣으면 어떻게 되느냐
data부터 [0],nick까지 이 값이 일치해야 된다
물론 data에는 [{nick:"ㅣ디노니ㅣ"}]만 있어야 하는건 아님
다른것도 들어가도 된다
써놓은것만 정확히 일치하면 성공함
그러면 채팅의 명령어가 '정답'일때만 뒤에가 실행되게 하려면 어떻게 해야할까?
/execute if data storage chat {data:[{command:"정답"}]} run ...
으로 하면 된다
물론 "정답"이던 '정답'이던 상관 없음
그러면 채팅의 값(chat)이 정답으로 정한 단어일때만 뒤에가 실행되게 하려면 어떻게 해야할까?
여기서부턴 매크로가 들어간다
정답으로 정한 단어를 storage ans의 a에 넣었다고 예를 들어 보자
정답으로는 '정답'을 정했다고 해보자
아까 chzzkapi:chat에는
function chzzkapi:real with storage chat data[0]
를 넣는다고 했었으니 chzzkapi:real에
execute if data ...를 넣으면 되겠노
그런데 어떤걸 넣어야할까?
채팅이 정답인지 감지하는게 쉬울까
아니면 정답이 채팅의 값인지를 감지하는게 쉬울까
먼저 앞에있는거 먼저 만들어보자
execute if data storage chat {data:[{chat_all:"정답"}]}
으로 감지하면 되겠지?
그러면 이번엔 정답이 169.9면 어떻게 해야할까?
execute if data storage chat {data:[{chat_all:"169.9"}]}
로 하면 되겠지?
하지만 이렇게 하면 할때마다 수정을 해야함
매크로를 써서 $execute if data storage chat {data:[{chat_all:"$(a)"}]}로 하면 되는거 아니냐구?
지금은 chat의 data[0]을 바탕으로 실행되고 있으니 a에는 아무것도 없음
그러니 이건 되지 않음
이번엔 뒤에있는걸로 해보자
정답은 ans의 a에 있으니
$execute if data storage ans {a:"$(chat_all)"}
로 하면 되겠노
5.채팅의 내용 출력하기
여기서도 매크로가 들어간다
아까거를 응용해서 간단히 정답이 틀렸을때는
(닉네임)님의 (채팅내용)은 틀렸음
라고 나오고, 맞췄을때는
(닉네임)님의 (채팅내용)이 정답임!
라고 나오게 해보자
아까 $execute if data storage ans {a:"$(chat_all)"}로 감지해서 맞췄는지 여부를 판단할 수 있었으니
chzzkapi:real에
$execute if data storage ans {a:"$(chat_all)"} run tellraw @a "$(nick)님의 $(chat_all)은 정답임!"
$execute unless data storage ans {a:"$(chat_all)"} run tellraw @a "$(nick)님의 $(chat_all)은 틀렸음"
로 하면 되겠노
번외.이스케이프(\n같은거) 막는 방법
채팅 api맵을 할때는 §나 \n같은게 자주 나온다
그러면 막 색이 바뀌거나 줄이 바뀐다
§표 하나 만들어 뒀으니 참고하셈
이걸 막는 방법은 없을까?
궁금해서 물어봐봤음
답변을 정리해주기엔 너무 길어서 해석만 해주겠음
1.스코어보드 추가
2.data[0].chat_all의 글자수 가져오기
3.글자 하나하나씩 검사하기
4.걸리면 멈추기
5.안걸리고 끝에 도달하면 성공
이건 차라리 내 방식을 파일로 주는게 나을 것 같노
이번에 맵 만들었던거에서 떼서 올린다
이건 이스케이프가 감지되면
(닉네임)님의 입력이 실패하였음
라는 텍스트가 출력된다
최종에 도달할때까지 자동 반복되고,
끝나면 chzzkapi:real이 실행된다
이것만 따로 적용시키기 전
/scoreboard objectives add noes dummy
를 채팅으로 입력해야 하구
이걸 실행하기 전 함수에선(chzzkapi:chat 추천)
scoreboard players set a noes -1
scoreboard players set b noes 0
data merge storage noes {a:-1,b:0,nick:"",word:""}
를 넣고
function chzzkapi:noes with storage noes
로 실행시켜야 함
감지하는 이스케이프 들은 여기 맨 아래에 정리되어있음
6.결론
재밌는 api맵이 많이 나오면 좋겠어서 만들어봤음
api맵 하고는 싶은데 만들 자신이 없다! 싶은 게이들은 댓글로 아이디어 주면 만들어보겠음
난 만들고는 싶은데 아이디어가 없거든
아무튼
버그 제보 대환영!!
댓글 0