こんにちは、ふじみやです。
前回はいわゆる「木こりMOD」を開発してみましたが、今回は鉄の鉱石ブロックなどを破壊すると原石ではなくインゴットの状態でアイテムがドロップするようなプラグインを開発してみようと思います。
はじめて開発をするという方はぜひ過去記事を参考にしていただければと思います。
Minecraft の Spigot プラグイン開発 こんにちは、ふじみやです。 今回、タイトルは「プラグイン開発」と銘打っていますが、まずはサーバーにプラグインを読み込んで「Hello World!」とサーバーのコンソ…
目次
プラグインの内容
今回は次のようなプラグインにしていきます。
- 破壊すると原石をドロップする鉱石ブロック(銅、鉄、金)を対象とする
- シルクタッチのエンチャントが付与されたツールで対象を破壊した際には発動しない
- 幸運のエンチャントが付与されたツールで対象を破壊した際にはドロップ数が増加
- 対象を破壊した際には原石はドロップせず、代わりにインゴットがドロップする
ただし、以下については考慮していませんので、今後アップデートをしたいと思います。
- コマンドよりプラグインのオン・オフを切り替え
- 適正ツール(ツルハシ)を手に持っている場合のみ効果が発動
- 石炭などの鉱石ブロックと同様に対象を破壊すると経験値がドロップする
- 隣接する同種の鉱石ブロックは一括破壊される
- 一括破壊時にツールの耐久値を減少させる
- 一括破壊によりドロップしたアイテムを全てプレイヤーの目の前に集める
コーディング
ChatGPT と対話を繰り返し、最終的に以下のコードで想定した通りの動きになりました。
なお、プラグイン名は「Refinery」としており、対応バージョンは 1.19.4 です。
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.java.JavaPlugin;
public final class Refinery extends JavaPlugin implements Listener {
@Override
public void onEnable() {
getServer().getPluginManager().registerEvents(this, this);
}
@EventHandler
public void onBlockBreak(BlockBreakEvent event) {
Block block = event.getBlock();
Player player = event.getPlayer();
ItemStack pickaxe = player.getInventory().getItemInMainHand();
// 破壊したブロックが鉱石ブロックの場合、処理を実行(isOreBlock)
if (isOreBlock(block.getType())) {
// ブロックを破壊したツールにシルクタッチのエンチャントが付与されている場合、何もしない
if (pickaxe != null && pickaxe.containsEnchantment(Enchantment.SILK_TOUCH)) {
return;
}
int dropCount = getDropCount(block.getType(), player.getInventory().getItemInMainHand());
ItemStack ingot = getIngot(block.getType(), dropCount);
// 鉱石ブロック破壊による通常のアイテムドロップをキャンセル
event.setDropItems(false);
// インゴットを代わりにドロップ
block.getWorld().dropItemNaturally(block.getLocation(), ingot);
}
}
private boolean isOreBlock(Material material) {
// 鉄・銅・金の鉱石ブロックであれば true
switch (material) {
case IRON_ORE:
case DEEPSLATE_IRON_ORE:
case COPPER_ORE:
case DEEPSLATE_COPPER_ORE:
case GOLD_ORE:
case DEEPSLATE_GOLD_ORE:
return true;
default:
return false;
}
}
private ItemStack getIngot(Material ore, int count) {
switch (ore) {
case IRON_ORE:
case DEEPSLATE_IRON_ORE:
return new ItemStack(Material.IRON_INGOT, count);
case COPPER_ORE:
case DEEPSLATE_COPPER_ORE:
return new ItemStack(Material.COPPER_INGOT, count);
case GOLD_ORE:
case DEEPSLATE_GOLD_ORE:
return new ItemStack(Material.GOLD_INGOT, count);
default:
return null;
}
}
private int getDropCount(Material oreType, ItemStack tool) {
int baseCount = getBaseCount(oreType);
int fortuneLevel = tool.getEnchantmentLevel(Enchantment.LOOT_BONUS_BLOCKS);
int dropCount = baseCount;
if (fortuneLevel > 0) {
int maxDropCount = baseCount + fortuneLevel;
int drop = new java.util.Random().nextInt(maxDropCount);
dropCount = drop + 1;
}
return dropCount;
}
private int getBaseCount(Material oreType) {
switch (oreType) {
case IRON_ORE:
case DEEPSLATE_IRON_ORE:
case GOLD_ORE:
case DEEPSLATE_GOLD_ORE:
return 1;
case COPPER_ORE:
case DEEPSLATE_COPPER_ORE:
int random = new java.util.Random().nextInt(4);
random = random + 2;
return random;
default:
return 0;
}
}
}
テスト
最後に、ビルドが完了したら Minecraft のサーバーを保存しているフォルダ内にある plugins フォルダに作成されたプラグインを保存し、サーバーを起動のうえテストをしてみましょう。
もしちゃんと動かない場合には ChatGPT に聞くなりして修正をしてみてください。
それではまた。
コメント