feature image

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

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

この記事は、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 icon
この記事を書いた人
azulene_c10h8

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

この記事をシェア

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

関連する記事

2019年12月21日
モデリングを始めてみたい君へ、MagicaVoxelのススメ
isak icon isak
2019年12月13日
ゲーム紹介「League of Legends」【AdC2019 44日目】
Yataka_ML icon Yataka_ML
2019年12月25日
TensorFlow.jsでwasmを使ってみるためにコントリビュートした【AdC2019 56日目】
sappi_red icon sappi_red
2019年12月25日
無料でDTM環境構築 電子音系編
liquid1224 icon liquid1224
2019年12月4日
部内製チャットサービス「traQ」UIのこれまで 【AdC2019 35日目】
spa icon spa
2019年12月23日
無料でDTM環境構築 生音系編
kashiwade icon kashiwade
記事一覧 タグ一覧 Google アナリティクスについて 特定商取引法に基づく表記