Minecraft Skript 応用編 Part.8 カスタムGUIにページ機能を実装

# 記事を読む前に
この記事で紹介しているコードにはMundoSKとProtocolLibというアドオンとプラグインが必要です

また、バグがあったため、修正版を[ここ](https://github.com/Monster2408/qiita-CustomGUI/blob/master/main.sk)で配布しています。

## 環境

- Skript version 2.4
- skRayFall version 1.9.12
- MundoSK version 1.8.6-BETA.57
- Skellett version 1.9.6b
- SkQuery version 3.6.5
- ProtocolLib version 4.4.0
- Paper-1613 (MC: 1.12.2)

# 完成品はこのような物
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404179/31d5c601-0efc-899b-6a9c-f438b8ea74f9.png)
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404179/3e46ab54-fb7e-c343-b16b-29aaf3e22ddf.png)
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404179/73a2c794-79c6-7af2-9629-b8a3a9f6544f.png)
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404179/e615e708-11c8-a2a4-c0a8-fac28507a49e.png)
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404179/efa747da-99c0-b1b8-0f96-bdf9804f7700.png)
![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404179/dd72a609-02c9-9dc8-e34c-d5f5e56a890c.png)

見慣れないアイテムがあるかもですが、赤いのはテクスチャの変わった染料で、クエスチョンマークのついた木の素材のようなものはカスタムヘッドです。

動画のほうが見やすいけど宣伝扱いになりそうなので動いてるのが見たい人は私のTwitterにDMで「Minecraft Skript 応用編 Part.8 カスタムGUIにページ機能を実装の動画みたい」って言ってください。

URL送ります。
# 開発理由
私は現在Minecraftで高クオリティDeadbyDaylight再現ミニゲームを作っています。

その過程で、パークやハンター、アイテムなどの選択画面で必要だったので作りました。
# 完成品
```:main.sk
Options:
	GUIName: "&6&lGUI"

	ValueHatena: "ewogICJ0aW1lc3RhbXAiIDogMTU5MzI1MzExNzk0NSwKICAicHJvZmlsZUlkIiA6ICIxYzJiNjk5MWU4Y2U0ZTVkYjRkOGVjM2YwY2RjNWY4ZSIsCiAgInByb2ZpbGVOYW1lIiA6ICJNb25zdGVyMjQwOCIsCiAgInNpZ25hdHVyZVJlcXVpcmVkIiA6IHRydWUsCiAgInRleHR1cmVzIiA6IHsKICAgICJTS0lOIiA6IHsKICAgICAgInVybCIgOiAiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS9jYjQzMmM2YmVlMDE5OWFkNmYwODYwMmNkZjI3ZGY5YjY2NjllMTUwNjMwNWYzZjQ1OTA1YjViMDQ0NDVmMDQ3IgogICAgfQogIH0KfQ=="
	SignatureHatena: "ixWPoDVB4kIPeBk3LLq+4xDDfJe2b0MjhZuogwl+v7DCPsbyJ/puv8IxbQWH27zcrxCLu3rIfLn1tSZZ2EHATBA+HOq2skYXPXp0obrRzznRRFICqWYuTKOvvZCgWHWfToq5DfCWDT4k/TdOd7Kj2N90BJN6CqarRuuzUKCRsiUOglI+aZsUD0pmSMe1fLETxqGtTGGyrgClEdN/E1uYQHfabWjaCc5t86/aFKUC/kzX92k1r9P9QvFoO9qluX3k9WwP+TVTY5hzzccaSKG+SdPUQHXb0jwLFHWrnweqLd6gMlkSA+oGBfPjBPX12WgSuXGaUZkE5hrHsF4yJFyPHN1hy9OCc6+P71si1d5Xynmu/X3eouQoKbkmo+CvkKSxsTTcV95bDHKQMYnx58S63mM2KzblMPy/jEK7RpQKhLPkkFVgtRdXz7/2vSsw0z4WhYq9fMQy+J5O4hkIr8FHBSNg2acbZasouikuANiZO2UXdf3H/7ArW0itscBOztalGdxQfEvrd/pMUCcz8oxGB63Mo+IFbwPQ9WsXb65G4RGk8CWKtqGiARH87bBUCM5R+eN3p51wGA9TvOUfuLeOIAW65XeJk3t/YpmZ93dglRZdImNXMO+bZCtjsTQGo3Yib4HAe7OVevgr9RO0PpwVlM8sL4TVO83dKjgPET/dzD8="

on load:
	set {GUIName} to {@GUIName}

	set {skull.hatena} to skull from skin texture with value {@ValueHatena} signature {@SignatureHatena} named "&7未開放"

	delete {list::*}
	add stone named "aaa" to {list::*}
	add stone named "bbb" to {list::*}
	add stone named "ccc" to {list::*}

function getGUIPage(p:player) :: number:
	set {_item} to slot 52 of {_p}'s current inventory
	set {_sections::*} to name of {_item} split at " "
	set {_text} to {_sections::2}
	return {_text} parsed as number

command /gui:
	trigger:
		open chest with 6 rows named "%{GUIName}%" to player
		set {_page} to 2
		set {_n} to ({_page} - 1) * 45
		loop 45 times:
			set slot loop-number - 1 of player's current inventory to {skull.hatena}
			set slot {_n} - 1 of player's current inventory to {list::%{_n}%}
			remove 1 from {_n}
		set slot 53 of player's current inventory to spectral arrow named "次ページ"
		set slot 52 of player's current inventory to map named "ページ: %{_page} - 1%"
		set slot 51 of player's current inventory to spectral arrow named "前ページ"
		stop

on inventory click:
	name of event-inventory is "%{GUIName}%"
	if clicked item is air:
		stop
	clicked item is set
	if clicked item is spectral arrow named "次ページ":
		play "ui_button_click" to player at volume 1
		set {_page} to getGUIPage(player)
		set {_n} to {_page} * 45 + 1
		loop 45 times:
			set slot loop-number - 1 of player's current inventory to {skull.hatena}
			set slot {_n} - 1 of player's current inventory to {list::%{_n}%}
			add 1 to {_n}
		set slot 53 of player's current inventory to spectral arrow named "次ページ"
		set slot 52 of player's current inventory to map named "ページ: %{_page} + 1%"
		set slot 51 of player's current inventory to spectral arrow named "前ページ"
		stop
	if clicked item is spectral arrow named "前ページ":
		play "ui_button_click" to player at volume 1
		set {_page} to getGUIPage(player)
		{_page} > 1
		set {_n} to ({_page} - 1) * 45
		loop 45 times:
			set slot loop-number - 1 of player's current inventory to {skull.hatena}
			set slot {_n} - 1 of player's current inventory to {list::%{_n}%}
			remove 1 from {_n}
		set slot 53 of player's current inventory to spectral arrow named "次ページ"
		set slot 52 of player's current inventory to map named "ページ: %{_page} - 1%"
		set slot 51 of player's current inventory to spectral arrow named "前ページ"
		stop
```
# 解説
ℓ.1～ℓ.5にかけてはGUIの名前とカスタムヘッドのクエスチョンマークのデータを持ってきています。

ℓ.7～ℓ.15にかけてはオプションをグローバル変数にしたり、カスタムヘッドを作ったり、リストを作っています。

ℓ.8でオプションのGUIの名前をグローバル変数にしています。
グローバル変数にすることで`main.sk`以外のファイルでも`{GUIName}`が使えます。

ℓ.10でオプションで書いたクエスチョンマーク柄のカスタムヘッドのデータを使用してカスタムヘッドを作っています。
これには前述通り、MundoSKとProtocolLibが必要です。

ℓ.12～ℓ.15でリストを作っており、リストにはアイテムを入れています。
ここでは、運営が決めたものを入れてますが、うまくやれば、Minecraft内からでも変更可能にできるでしょう。

ℓ.17～ℓ.21では現在見ているページ数を取得するファンクションを設置しています。

ℓ.23～ℓ.35ではコマンドでGUIを開けるようになっています。

ℓ.36～ではインベントリ内でのクリック操作について書いています。

# 今回初登場の構文
## 構文A スキンからカスタムヘッドを作成
```:構文
set %objects% to skull from %skin%
```
```:例文
set {_skull} to skull from skin texture with value "ewogICJ0aW1lc3RhbXAiIDogMTU5MzI1MzExNzk0NSwKICAicHJvZmlsZUlkIiA6ICIxYzJiNjk5MWU4Y2U0ZTVkYjRkOGVjM2YwY2RjNWY4ZSIsCiAgInByb2ZpbGVOYW1lIiA6ICJNb25zdGVyMjQwOCIsCiAgInNpZ25hdHVyZVJlcXVpcmVkIiA6IHRydWUsCiAgInRleHR1cmVzIiA6IHsKICAgICJTS0lOIiA6IHsKICAgICAgInVybCIgOiAiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS9jYjQzMmM2YmVlMDE5OWFkNmYwODYwMmNkZjI3ZGY5YjY2NjllMTUwNjMwNWYzZjQ1OTA1YjViMDQ0NDVmMDQ3IgogICAgfQogIH0KfQ==" signature "ixWPoDVB4kIPeBk3LLq+4xDDfJe2b0MjhZuogwl+v7DCPsbyJ/puv8IxbQWH27zcrxCLu3rIfLn1tSZZ2EHATBA+HOq2skYXPXp0obrRzznRRFICqWYuTKOvvZCgWHWfToq5DfCWDT4k/TdOd7Kj2N90BJN6CqarRuuzUKCRsiUOglI+aZsUD0pmSMe1fLETxqGtTGGyrgClEdN/E1uYQHfabWjaCc5t86/aFKUC/kzX92k1r9P9QvFoO9qluX3k9WwP+TVTY5hzzccaSKG+SdPUQHXb0jwLFHWrnweqLd6gMlkSA+oGBfPjBPX12WgSuXGaUZkE5hrHsF4yJFyPHN1hy9OCc6+P71si1d5Xynmu/X3eouQoKbkmo+CvkKSxsTTcV95bDHKQMYnx58S63mM2KzblMPy/jEK7RpQKhLPkkFVgtRdXz7/2vSsw0z4WhYq9fMQy+J5O4hkIr8FHBSNg2acbZasouikuANiZO2UXdf3H/7ArW0itscBOztalGdxQfEvrd/pMUCcz8oxGB63Mo+IFbwPQ9WsXb65G4RGk8CWKtqGiARH87bBUCM5R+eN3p51wGA9TvOUfuLeOIAW65XeJk3t/YpmZ93dglRZdImNXMO+bZCtjsTQGo3Yib4HAe7OVevgr9RO0PpwVlM8sL4TVO83dKjgPET/dzD8="
```

`%skin%`は`skin texture with value "%string%" signature "%string%"`で、`value`と`signature`は[Mojang API](https://wiki.vg/Mojang_API#UUID_-.3E_Profile_.2B_Skin.2FCape)から取得可能です。

## 構文B ファンクション作成法
```:構文
function 任意の文字(ローカル変数の文字列:使用する型) :: 返す型:
    # hogehoge
    return {_ローカル変数の文字列}

set {_value} to 任意の文字(使用する型にあったデータ)
```
```:例文
function getaplus3(n: number) :: number:
    add 3 to {_n}
    return {_n}

set {_value} to getaplus3(5)
broadcast "%{_value}%" # broadcast 8
```

まぁ、functionは自作関数だと思ってください（わかるかな？）

分からないことがあればコメントから質問どうぞ

また、ここにてディスカッション専用チャンネルを用意しています。
質問も受け付けています。
[MonsterFreeGroup](https://discord.gg/mQ7RkFJ)

次は[コチラ](https://qiita.com/meoto2408/items/429782b900dc63b4fda4)

前は[コチラ](https://qiita.com/meoto2408/items/5b96e179b6e6d214f08f)