Minecraftのプラグインを作る!Java版1.18.1のPaperMC用

Minecraftのプラグイン作るよ!
今回作るプラグインは敵や動物に近づくと死ぬプラグインです。

開発環境:
Windows10
Apache NetBeans IDE 12.6

Java with Maven -> Java Applicationを選びNext

Project Name:好きな名前をつける
Group Id:ドメインを持っているならそれをつける、ないならデフォルトのままでもいいかも
Version:好きにつける、年月日にすると作った日がわかりやすいかも

Finishを押す。

Project Filesフォルダの下のpom.xmlを編集する。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.comorichico</groupId>
    <artifactId>mobdeath</artifactId>
    <version>20220118</version>
    <packaging>jar</packaging>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
    </properties>
    <repositories>
        <repository>
            <id>papermc</id>
            <url>https://papermc.io/repo/repository/maven-public/</url>
        </repository>
    </repositories>
    <dependencies>
        <dependency>
            <groupId>io.papermc.paper</groupId>
            <artifactId>paper-api</artifactId>
            <version>1.18.1-R0.1-SNAPSHOT</version>
            <type>jar</type>
        </dependency>
        <dependency>
            <groupId>net.kyori</groupId>
            <artifactId>adventure-api</artifactId>
            <version>4.9.3</version>
            <type>jar</type>
        </dependency>
    </dependencies>
    <build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>plugin.yml</include>
                </includes>
            </resource>
        </resources>
    </build>
</project>

上記をコピペして

    <groupId>com.comorichico</groupId>
    <artifactId>mobdeath</artifactId>
    <version>20220118</version>

ここの3行は自分の設定に置き換えてください。

次にSource Packageを右クリック -> New -> Other

Other -> YAML Fileを選びNext

File Nameにpluginと入力、Finishを押す。

plugin.ymlを編集。

name: mobdeath
version: 20220118
description: Die when approaching a mob.
author: comorichico
website: mobdeath.comorichico.com
api-version: 1.18
#---
main: com.comorichico.mobdeath.MobDeath

これも内容は書き換えて使ってください。
api-version: 1.18 はそのままで良いと思います。
mainの内容はこのあと作るクラスファイルと同じ名前にしないと動かなくなります。

パッケージのフォルダ(この場合だとcom.comorichico.mobdeathのフォルダ)を右クリックしてNew -> Java Classでクラスファイルを2つ作ります。MobDeath.javaとDeathCheckTask.javaを作りました。
名前は好きに変えてください。

package com.comorichico.mobdeath;

import org.bukkit.event.Listener;
import org.bukkit.plugin.java.JavaPlugin;

/**
 *
 * @author comorichico
 */
public class MobDeath extends JavaPlugin implements Listener {
    /**
     * 起動時処理
     */
    @Override
    public void onEnable() {
        getLogger().info("プラグインが有効になったよ!");
        // スケジューリングする
        new DeathCheckTask().runTaskTimer(this, 0, 1);
    }
        
    /**
     * 終了時処理
     */
    @Override
    public void onDisable() {
        getLogger().info("プラグインが無効になったよ!");
    }
}

メインになるクラス、MobDeathのコードです。
パッケージ名、クラス名、 author のところは自分用に変えてください。
new DeathCheckTask().runTaskTimer(this, 0, 1);
のところですが、0秒後に開始して1tickごとにタスクを処理するという内容です。

package com.comorichico.mobdeath;

import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit;
import org.bukkit.GameRule;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;

/**
 *
 * @author comorichico
 */
public class DeathCheckTask extends BukkitRunnable{
    @Override
    public void run() {
        String entityname = "";
        for(Player p : Bukkit.getServer().getOnlinePlayers()){
            for(Entity e : p.getNearbyEntities(2, 2, 2)){
                switch (e.getType()) {
                    case AXOLOTL -> entityname = "ウーパールーパー";
                    case BAT -> entityname = "コウモリ";
                    case BEE -> entityname = "ミツバチ";
                    case BLAZE -> entityname = "ブレイズ";
                    case CAT -> entityname = "ネコ";
                    case CAVE_SPIDER -> entityname = "洞窟グモ";
                    case CHICKEN -> entityname = "ニワトリ";
                    case COD -> entityname = "タラ";
                    case COW -> entityname = "ウシ";
                    case CREEPER -> entityname = "クリーパー";
                    case DOLPHIN -> entityname = "イルカ";
                    case DONKEY -> entityname = "ロバ";
                    case DROWNED -> entityname = "ドラウンド";
                    case ELDER_GUARDIAN -> entityname = "エルダーガーディアン";
                    case ENDERMAN -> entityname = "エンダーマン";
                    case ENDERMITE -> entityname = "エンダーマイト";
                    case ENDER_DRAGON -> entityname = "エンダードラゴン";
                    case EVOKER -> entityname = "エヴォーカー";
                    case FOX -> entityname = "キツネ";
                    case GHAST -> entityname = "ガスト";
                    case GIANT -> entityname = "ジャイアント";
                    case GLOW_SQUID -> entityname = "ヒカリイカ";
                    case GOAT -> entityname = "ヤギ";
                    case GUARDIAN -> entityname = "ガーディアン";
                    case HOGLIN -> entityname = "ホグリン";
                    case HORSE -> entityname = "ウマ";
                    case HUSK -> entityname = "ハスク";
                    case ILLUSIONER -> entityname = "イリュージョナー";
                    case IRON_GOLEM -> entityname = "アイアンゴーレム";
                    case LLAMA -> entityname = "ラマ";
                    case MAGMA_CUBE -> entityname = "マグマキューブ";
                    case MULE -> entityname = "ラバ";
                    case MUSHROOM_COW -> entityname = "ムーシュルーム";
                    case OCELOT -> entityname = "ヤマネコ";
                    case PANDA -> entityname = "パンダ";
                    case PARROT -> entityname = "オウム";
                    case PHANTOM -> entityname = "ファントム";
                    case PIG -> entityname = "ブタ";
                    case PIGLIN -> entityname = "ピグリン";
                    case PIGLIN_BRUTE -> entityname = "ピグリンブルート";
                    case PILLAGER -> entityname = "ピリジャー";
                    case POLAR_BEAR -> entityname = "シロクマ";
                    case PUFFERFISH -> entityname = "フグ";
                    case RABBIT -> entityname = "ウサギ";
                    case RAVAGER -> entityname = "ラヴェジャー";
                    case SALMON -> entityname = "サケ";
                    case SHEEP -> entityname = "ヒツジ";
                    case SHULKER -> entityname = "シュルカー";
                    case SILVERFISH -> entityname = "シルバーフィッシュ";
                    case SKELETON -> entityname = "スケルトン";
                    case SKELETON_HORSE -> entityname = "スケルトンホース";
                    case SLIME -> entityname = "スライム";
                    case SPIDER -> entityname = "クモ";
                    case SQUID -> entityname = "イカ";
                    case STRAY -> entityname = "ストレイ";
                    case STRIDER -> entityname = "ストライダー";
                    case TRADER_LLAMA -> entityname = "行商人のラマ";
                    case TROPICAL_FISH -> entityname = "熱帯魚";
                    case TURTLE -> entityname = "カメ";
                    case VEX -> entityname = "ヴェックス";
                    case VILLAGER -> entityname = "村人";
                    case VINDICATOR -> entityname = "ヴィンディケーター";
                    case WANDERING_TRADER -> entityname = "行商人";
                    case WITCH -> entityname = "ウィッチ";
                    case WITHER -> entityname = "ウィザー";
                    case WITHER_SKELETON -> entityname = "ウィザースケルトン";
                    case WOLF -> entityname = "オオカミ";
                    case ZOGLIN -> entityname = "ゾグリン";
                    case ZOMBIE -> entityname = "ゾンビ";
                    case ZOMBIE_HORSE -> entityname = "ゾンビホース";
                    case ZOMBIE_VILLAGER -> entityname = "村人ゾンビ";
                    case ZOMBIFIED_PIGLIN -> entityname = "ゾンビピグリン";
                    default -> {
                    }
                }
                if (!"".equals(entityname)) {
                    if (!p.isDead()) {
                        p.getWorld().setGameRule(GameRule.SHOW_DEATH_MESSAGES, false);
                        p.setHealth(0);
                        p.getWorld().setGameRule(GameRule.SHOW_DEATH_MESSAGES, true);
                        Bukkit.getServer().broadcast(Component.text(p.getName() + "は" + entityname + "に殺されました"));
                        entityname = "";
                    }
                }

            }
        }
    }
}

DeathCheckTask のコードです。
Bukkit.getServer().getOnlinePlayers() でオンラインのプレイヤーを全員取得します。
p.getNearbyEntities(2, 2, 2) はプレイヤーの近くにいるエンティティ(モブキャラ等)を半径2マス(自分を中心に5*5*5の立方体の範囲)で取得しています。
p.getNearbyEntities(3, 3, 3)等にすると範囲を広げることができます。
switch 文は英語を日本語に変換しているだけです。
p.setHealth(0); で体力をゼロにして死ぬようにしているのですが死んだ時のメッセージが流れてしまうため前後の行でメッセージオフにしてあとでオンに直しています。
Bukkit.getServer().broadcast(Component.text(p.getName() + “は” + entityname + “に殺されました”));
の行はゲーム内で「comorichicoはヒツジに殺されました」というようなメッセージを流すために使っています。

ここまで全部できたらメニューからRun -> Build Projectを選んでビルドします。

ビルドすると
C:\Users\[user名]\OneDrive\ドキュメント\NetBeansProjects\mobdeath\target
のフォルダに(OneDriveを使っていない場合は別のフォルダかもしれません)mobdeath-20220118.jarのようなjarファイルが生成されています。

このjarファイルをMinecraftサーバーのpluginsフォルダに入れます。

プラグインを使ってみるとこうなります。

おつかれさまでした!

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です