2019年12月2日 | ブログ記事

階段にたむろするヤンキープラグインを作った話

azulene_c10h8

この記事は、traPアドベントカレンダー2019 33日目の記事です。
はじめまして、19のあずです。班やプロジェクトには所属してません。まぁ、どっちも@Nullableなので耐えますね。
今日は僕の趣味の一つであるSpigotのPlugin開発の大まかな流れについて書きます。
今回作ったのは階段にたむろするヤンキーになれる機能を追加したプラグインです。割と有名な機能で既にChairs等のプラグインが公開されてはいますが、なぜかお世話になってるサーバーで動かなかった(らしい)ので作りました。

SpigotとPluginについて

SpigotとかPluginとかってなんだよ、ってなりますよね。まぁ聞いて下さい。
いきなりですがみなさん、Minecraftのサーバーを建てたい!!って思ったことありますか?
もちろん公式サーバーを使っても良いのですが、世の中には人の建築物を大爆発させるのが趣味な【検閲済み】野郎がいます。キレていいです。

その建築物を直す際、みなさんならばどうしますか?

ブロックを1つ1つ置き直すのも一つの手かもしれませんが、時間がかかりすぎます。鼻からスパゲティ食べる訓練をしたほうが明らかにアドです。

もし、ロールバック機能があればコマンドでらくらく直せますね? 午後の紅茶を午前に飲みながら優雅に過ごせますね?
そんな 拡張機能(Plugin) を追加することのできるサーバーの一つにSpigotってのがあるわけですよ。やったね、また賢くなれましたね。

ただ、ほしい機能を持つPluginが必ずしもあるか、と言われると微妙です。
まぁ、無かったらその機能は…残念ですが……諦めろと……

私は言いません

無ければ作ればいいんです。僕の母親のお爺ちゃんのお孫さんの息子さんが言ってました。

必要なもの

ここでは、SpigotのPluginを作るにあたり、必要そうなものを以下に挙げてみます。

ggり力

おそらく、これが一番大切です。ちなみに僕の友人にこのことを言ったら「胡散臭すぎて草」と言われました辛い。
特に、変なPluginを作る人は†英語力†も必要になります。たいてい、僕たちの起こす問題は外人兄貴がSpigotのフォーラムにて先に質問しています。

いいですか、外人兄貴は僕たちをひとつ上のステージに引き上げてくれます。大好きです、外人兄貴。(唐突の告白)

ちなみに僕は皆無です。とりあえずhow toってつけておけ。

Javaの知識

ここでも妥協をするな、と言いたいところですが、僕は皆無です。Enum型を えなむ って呼んだり、Char型を ちゃー って読む程度には無知です。
そんな僕でも3~4年位開発できてるので、まぁいいんじゃないんですかね?

Minecraftの知識

ここは質にこだわるべきです。ちなみに僕は皆無です。金人参は良いぞ。

制作意欲

これがあると開発が圧倒的に楽になります。メンタルis精神力!!
ちなみに僕は皆無です。虚無から意欲を錬成せよ。

バグに(ry

メンタルis精神力!!
ちなみに僕は皆無です。杏仁豆腐メンタルです。

さて、必要なものは揃っていますか?
揃って無くても作ってみましょう

Step1 プラグインの仕様を考えよう

階段に座る機能は無いので、色々つかって座ってるを再現します。殆どのイス系のプラグインでは、階段の中に矢を埋めて、その矢に座らせています。今回作ったのも全く同じ仕組みです。

Step2 組んでみる

Spigot(Bukkit)は所謂イベントドリブンっていうやつです。かなり多くのイベントがBukkitで用意されています。(ブロックの設置・破壊からチャンクの読み込み、気候の変化まで)
今回はブロックをクリックした、というイベントに反応させます。

(中略)

というわけでなんやかんやできました。重要なところだけ載せてます。

Block block = event.getClickedBlock(); //クリックしたブロックの取得
String dataStr = "[half=bottom]"; //階段は下付きになっているか
BlockData data = Bukkit.createBlockData(block.getType(), dataStr);
if(block.getBlockData().matches(data)) {//dataStrと一致するか
event.setCancelled(true);
if(player.isGliding()) {//エリトラで滑空中なら滑空をキャンセル
    player.setGliding(false);
}
Arrow arrow = (Arrow) player.getWorld().spawnEntity(block.getLocation().add(new Vector(0.5, 0, 0.5)), EntityType.ARROW);//矢をうまいこと階段の中に埋め込む
arrow.setGravity(false);//重力無視
arrow.setInvulnerable(true);//無敵
arrow.addPassenger(player);//プレイヤーを矢に乗っける
reloadArrow(arrow);

これがreloadArrow()の中身です

new BukkitRunnable() {//スケジューラーってやつです
            @Override
            public void run() {
                boolean hasPlayer = false;
                for(Entity e : arrow.getPassengers()) {//矢に乗ってるエンティティ全部を調べます
                    if(e == null) {//よくわからんけど取れなかったら飛ばします
                        continue;
                    }
                    if(Objects.equals(e.getType(), EntityType.PLAYER)) {
                    //プレイヤーがいたらhasPlayerをtrueにしてやります
                        hasPlayer = true;
                    }
                }
                try {
                    if((arrow.getLocation().subtract(new Vector(0.5, 0, 0.5)).getBlock().getBlockData() instanceof Stairs) && (Objects.equals(arrow.getLocation().add(new Vector(-0.5, 1, -0.5)).getBlock().getType(), Material.AIR)) && hasPlayer) {
                        /*(条件文汚い)
                        ・矢が埋まってる座標のブロックは階段かどうか
                        ・階段の上は空気であるかどうか
                        ・プレイヤーは乗っているか
                        上記3つがすべて揃ったときのみ、矢が延命され、再度reloadArrow()が呼び出されます
                        */
                        arrow.setTicksLived(1);
                        reloadArrow(arrow);
                    }
                    else {
                        arrow.remove();
                    }
                }
                catch(Exception e) {
                    arrow.remove();
                }
            }
        }.runTaskLater(AzulePlugin.getInstance(), 10);//10Tick(1Tickは1/20秒)後に実行します

Step3 バグをひたすら潰す

頑張りましょう。頑張れば頑張るほど、頑張れます。

Step4 ツイッターで自慢しよう!!

僕はツイッターしてませんけど

†完成した†

というわけでこんな感じに階段に座り込んじゃうことができます
ただ、やっぱまだ改善すべき点はあります

2019-12-02_11.58.41

改善すべき点

階段からモクモク煙が出る

ArrowクラスにsetColor(Color)っていうのがあるので、これにnullをあげる & try-catchで挟んであげればモクモクは消えます…が、エラーを握りつぶすことになるのでやりたくないです。今度考えます。

他にもこんなのが作れます

プラグインはすごいんです。
発想次第でこんな感じにミニマムブロックを作ることだってできます。
2019-10-14_16.14.01

最後に

はい、すっごくガバガバな内容の記事で各方面から怒られそうですが、プラグイン作るのは楽しいよっていうお話でした。みんなもプラグインを作ろうね!!!

明日12/3の担当は @tarorynさん @Eruさんのお二人です。お楽しみに!!!

参考

これからマイクラ鯖を建てたい人に言いたい事
(https://jyn.jp/to-begin-minecraft-server/#Spigot)

この記事を書いた人
azulene_c10h8

初心者じゃばらーです Spigotのプラグインを作ってニヤニヤするのが趣味です †マイクラで進捗†

この記事をシェア

このエントリーをはてなブックマークに追加

関連する記事

2019年12月11日
円周率が無理数であることの証明【AdC2019 42日目】
Tarara
2019年12月11日
ぷよぷよってナンですか?【AdC2019 42日目】
arahi10
2019年12月10日
ブログ投稿ツイートを無理やり自動化した話【AdC2019 41日目】
xecua
2019年12月10日
理工系科目英語クラスについて【AdC2019 41日目】
kano
2019年12月9日
大学生活を豊かにする自己管理ツール集【AdC2019 40日目】
Deka
2019年12月8日
ハッカソンに参加して素材を作った話
NABE

活動の紹介

カテゴリ

タグ