0コメント

【Minecraft Plugin】スコアボードをプラグインで操作してみた。

今回はBukkitのPluginにてスコアボードを操作してみたので、備忘録的な感じで書き残しておく。

今回は「PlayerItemBreakEvent」をトリガーに実行させて、ツールを破壊した回数をカウントするメソッドとなっている。

スクリーンショット 2021-12-10 021116.png


package com.github.nekoy3.nekoserverplugin;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerItemBreakEvent;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scoreboard.Objective;
import org.bukkit.scoreboard.Score;
import org.bukkit.scoreboard.Scoreboard;
import org.bukkit.scoreboard.ScoreboardManager;

public class NekoServerPlugin extends JavaPlugin implements Listener{
    //↓ onEnableはロードされた時に実行されるメソッド
    @Override
    public void onEnable() {
        getLogger().info("Hello!");
        getServer().getPluginManager().registerEvents(this,this);
    }
    @EventHandler
    public void itemBreakInfo(PlayerItemBreakEvent e) {
    	ItemMeta item = e.getBrokenItem().getItemMeta();
    	String itemName;
    	if (item.hasDisplayName()) {
    		itemName = item.getDisplayName();
    	} else {
    		itemName = item.getLocalizedName();
    	}
    	Player p = e.getPlayer();
    	ScoreboardManager manager = Bukkit.getScoreboardManager();
    	Scoreboard board = manager.getMainScoreboard();
    	Objective objective = board.getObjective("BrokenItemCount");
    	Score score = objective.getScore(p.getDisplayName());
    	int s = score.getScore() + 1;
    	p.getServer().broadcastMessage(itemName + ChatColor.RED + "が破損してしまった!!" + ChatColor.BLUE + "破損" + s + "回目")
    	score.setScore(s);
    }
}


仕組みは、イベントから受け取った引数からプレイヤーデータと破損したアイテム(ItemMeta型)を取得し(25,32行)、アイテムの表示名を取得(27:31行)、スコアボードを管理するおまじないを記述し(33,34行)、BrokenItemCountスコアボードオブジェクトを取得
プレイヤーデータからプレイヤー名を割り出してそのプレイヤーのBrokenItemCountのスコアを取得する。(35,36行目)

そしたらScore型にgetScoreしint型のスコア値を取得し、1加算(37行目)。プレイヤー当てにメッセージを送信し(38行目)スコアをセットする。(39行目)

例えば「古の剣」という剣を破壊した場合は、「古の剣が破損してしまった!! 破損〇回目」とメッセージが送信される。

しかし問題が、hasDisplayName()(27行)で表示する名前があるか否かを判別し、あればDisplayNameを取得しなければLocalizedNameを取得するように記述したハズが、LocalizedNameが取得できない。
例えば、ただの名前のつけていない鉄の剣を破壊すると「鉄の剣が破損してしまった」と出力しない。itemNameは空白。

LocalizedNameじゃないのか?その辺りがよく分からないので、後々調べてみることにする。


参考リファレンス
LocalizedNameについて
スコアボードのおまじない

ps
コメント行とか言う概念を完璧に忘れていた。解説が見にくい・

この記事へのコメント