マイクラで進行度に応じて本の内容を書き換える


この記事は、[筑波NSミライラボ Advent Calendar 2023](https://qiita.com/advent-calendar/2023/tsukuba-ns-mirailabo)、24日目の記事です。

https://qiita.com/advent-calendar/2023/tsukuba-ns-mirailabo

# はじめに
こんにちは、N高等学校通学コース所属の@ShotaKobayashiです
他の人の記事のレベルが高すぎて萎縮しちゃってますが頑張って書いて行きます
# 作ったもの
マイクラでクエストなどの進行度に応じて本の中身を書き換えるfunction
# 作ったきっかけ
マイクラでRPGを作成していて、受注したクエストなどがわからないと不便だよなあと思ったので作ることにしました。
# 作ってみよう
まずは実践あるのみ！早速作って行きましょう
とりあえず今考えている仕組みは
1. クエストの進行度を取得し、進行度に応じた本の内容をストレージに保存
1. 本を与えるときにストレージの中身を引数として本の中身に代入

意外とこれだけなのですぐできそうですね(フラグ)

ということでとりあえずクエストを2つ作ってきました
トムさんとガイモンさんです
![スクリーンショット 2023-12-17 17.33.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583146/7d648eb6-e47f-5b25-fad0-f8a954003beb.png)
トムさんのクエストを受注してみました。
この状態でのクエストの進行度を管理するストレージの中身はこんな感じ(トムさんのクエストは00)
![スクリーンショット 2023-12-17 17.42.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583146/ef735054-8408-a8cf-0935-2c26e89c1344.png)

ここから少しコードを書いて行きます
まずは実際に本を入手するコマンド
```.mcfunction
clear @p written_book{Tags:["quest"]}
$give @p written_book{pages:[$(str1)$(str2)],title:"受注クエスト一覧",author:LegendaryHori,Tags:["quest"],CustomModelData:1}
```
$()とは、最近のアップデートで追加されたコマンドマクロというもので、関数の引数として使うことができるものです
このコードでは1行目ですでに持っている本を削除し、2行目で新しく本を与えています
pages:[]の中に文字を入れると、実際に本が書き込まれた状態で取得できます

次はクエストの進行度に応じた本の中身を書いて行きます
これでクエストが未受注、受注、クリア済みの3パターンの記述です
```.mcfunction
#00未受注
execute if data storage minecraft:quest {00:{is:false,finish:false}} run data merge storage minecraft:questtext {str1:""}
#00受注
execute if data storage minecraft:quest {00:{is:true,finish:false}} run data merge storage minecraft:questtext {str1:'\'["",{"text":"頼まれごと","color":"dark_green","bold":true},{"text":"\\n","color":"reset","bold":true},{"text":"\\n特別なりんご集め\\n","color":"green","bold":true},{"text":"\\n村人のトムがアップルパイ\\nを作りたいみたいだ。\\n材料となる","color":"reset","bold":false},{"text":"特別なりんご","color":"aqua","bold":false},{"text":"を\\n5個持って行ってあげよう","color":"reset","bold":false}]\','}
#00クリア
execute if data storage minecraft:quest {00:{is:true,finish:true}} run data merge storage minecraft:questtext {str1:'\'["",{"text":"頼まれごと","color":"dark_green","bold":true},{"text":"\\n","color":"reset","bold":true},{"text":"\\n特別なりんご集め\\n","color":"green","strikethrough":true,"bold":true},{"text":"\\n村人のトムがアップルパイ\\nを作りたいみたいだ。\\n材料となる","color":"reset","bold":false},{"text":"特別なりんご","color":"aqua","bold":false},{"text":"を\\n5個持って行ってあげよう","color":"reset","bold":false},{"text":"\\n\\nクリア済","color":"red","bold":true}]\','}
```

実行するときはこう
functionの後にwithで引数となるストレージを指定します
```.mcfunction
function testdatapacks:function_get_questbook with storage minecraft:questtext
```

実際に動かしてみるとエラーが起きてしまいました
無効なエスケープシーケンス。。。\nがちゃんと使えてないですね
![スクリーンショット 2023-12-17 18.15.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583146/d5d501ab-2270-18f0-0ea2-f21e5fc85446.png)
\nを消してみると一応実行されたのでエラーの原因はこれだけらしい
![スクリーンショット 2023-12-17 18.21.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583146/7d55eb1d-9a3e-c33b-62ba-dd4c5f083c17.png)
マイクラのテキストフォーマットについて調べてみるとスペースで改行できるらしい？記事を見つけたのでやってみる
```スペースでの改行を試す.
{str1:'\'["",{"text":"頼まれごと ","color":"dark_green","bold":true},{"text":"","color":"reset","bold":true},{"text":" 特別なりんご集め ","color":"green","bold":true},{"text":"村人のトムがアップルパイを作りたいみたいだ。 材料となる","color":"reset","bold":false},{"text":"特別なりんご","color":"aqua","bold":false},{"text":"を5個持って行ってあげよう","color":"reset","bold":false}]\','}
```
```書きたい文章.
頼まれごと

特別なりんご集め

村人のトムがアップルパイ
を作りたいみたいだ。
材料となる特別なリンゴを
5個持っていってあげよう
```
改行に成功はしたが2連続改行はできていない。。
![スクリーンショット 2023-12-17 21.38.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583146/0f17b5b7-cf2b-e81f-c18b-5ddc8343bfb5.png)

引数を使用せずに手打ちで本の中身を入力した際は\nが使えたので何かやり方はあるはず、
\を増やしてみるか..?
```.mcfunction
#00未受注
execute if data storage minecraft:quest {00:{is:false,finish:false}} run data merge storage minecraft:questtext {str1:""}
#00受注
execute if data storage minecraft:quest {00:{is:true,finish:false}} run data merge storage minecraft:questtext {str1:'\'["",{"text":"頼まれごと","color":"dark_green","bold":true},{"text":"\\\\n","color":"reset","bold":true},{"text":"\\\\n特別なりんご集め\\\\n","color":"green","bold":true},{"text":"\\\\n村人のトムがアップルパイ\\\\nを作りたいみたいだ。\\\\n材料となる","color":"reset","bold":false},{"text":"特別なりんご","color":"aqua","bold":false},{"text":"を\\\\n5個持って行ってあげよう","color":"reset","bold":false}]\','}
#00クリア
execute if data storage minecraft:quest {00:{is:true,finish:true}} run data merge storage minecraft:questtext {str1:'\'["",{"text":"頼まれごと","color":"dark_green","bold":true},{"text":"\\\\n","color":"reset","bold":true},{"text":"\\\\n特別なりんご集め\\\\n","color":"green","strikethrough":true,"bold":true},{"text":"\\\\n村人のトムがアップルパイ\\\\nを作りたいみたいだ。\\\\n材料となる","color":"reset","bold":false},{"text":"特別なりんご","color":"aqua","bold":false},{"text":"を\\\\n5個持って行ってあげよう","color":"reset","bold":false},{"text":"\\\\n\\\\nクリア済","color":"red","bold":true}]\','}
```
改行部分の記述を試しに\ \ \ \nにしてみると
いけた、なんで、、？
![スクリーンショット 2023-12-17 21.56.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583146/05de2f5a-93a8-691b-56c1-4ac058dd6440.png)
なんかいけました。
いけたからいいか(良くない)
とりあえずいけたのでガイモンさんの方も同じように修正
こんな感じになりました

##### 受注のみ(未クリア)
![スクリーンショット 2023-12-17 21.56.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583146/05de2f5a-93a8-691b-56c1-4ac058dd6440.png)
##### クリア済み
![スクリーンショット 2023-12-17 22.05.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583146/fb9e6e79-b7f0-f8ba-d887-81a943ecd654.png)
クエストを受注したとき、クリアしたときに自動的にfunctionを実行してくれるようにしたので常に最新の状態になります

# まとめ
今回使用したコマンドマクロという機能はマイクラに追加されたばかりの機能だったのでネットに情報が少なく、調べるのが一番大変でした笑
\nで改行できないのがわからなすぎて同じところで詰まる人がいなくなるといいなあと思います
マイクラでテキストを引数として追加するとき、改行するには「\ \ \ \n」と記入する←これを覚えておきましょう!
ちなみになんで\ \ \ \nでいけたのかいまだにわかってないので誰か教えてください