CobbleOreGenerator

CobbleOreGenerator.java v1.0
刷石机刷石头时有概率生成矿石,矿石种类和权重可配置,配置文件自动生成和加载。
作者: Scriptirc

命令列表

  • cobbleore reload重载刷石机矿石配置

权限列表

  • cobbleore.reload允许重载配置
package com.scriptirc.cobbleore;

import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockFromToEvent;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.Location;

import java.io.File;
import java.io.IOException;
import java.util.*;

/**
 * @pluginName CobbleOreGenerator
 * @author Scriptirc
 * @version 1.0
 * @description 刷石机刷石头时有概率生成矿石,矿石种类和权重可配置,配置文件自动生成和加载。
 * [command]cobbleore reload|重载刷石机矿石配置[/command]
 * [Permission]cobbleore.reload|允许重载配置[/Permission]
 */
public class CobbleOreGenerator extends JavaPlugin implements Listener {
    // 配置文件对象
    private File configFile;
    private YamlConfiguration config;
    // 权重池
    private List<OreEntry> orePool = new ArrayList<>();
    private int totalWeight = 0;

    @Override
    public void onEnable() {
        // 注册事件监听器
        Bukkit.getPluginManager().registerEvents(this, this);
        // 加载配置
        loadConfig();
        getLogger().info("CobbleOreGenerator 已启用!");
    }

    @Override
    public void onDisable() {
        getLogger().info("CobbleOreGenerator 已关闭。");
    }

    // 刷石机核心事件监听
    @EventHandler
    public void onBlockFromTo(BlockFromToEvent event) {
        Block toBlock = event.getToBlock();
        Block fromBlock = event.getBlock();
        // 只处理水或岩浆流动
        if (!(fromBlock.getType() == Material.WATER || fromBlock.getType() == Material.LAVA)) return;
        // 目标方块必须是空气
        if (toBlock.getType() != Material.AIR) return;
        // 检查周围是否形成刷石机结构
        if (isCobbleGen(toBlock)) {
            // Bukkit事件是同步的,直接替换方块
            Material result = getRandomOre();
            if (result != null) {
                // 延迟1tick替换,避免与原版生成冲突
                Bukkit.getScheduler().runTask(this, () -> {
                    toBlock.setType(result);
                });
            }
        }
    }

    // 判断是否为刷石机结构
    private boolean isCobbleGen(Block airBlock) {
        // 检查6个方向是否有水和岩浆
        boolean hasWater = false, hasLava = false;
        for (org.bukkit.block.BlockFace face : org.bukkit.block.BlockFace.values()) {
            Block relative = airBlock.getRelative(face);
            if (relative.getType() == Material.WATER) hasWater = true;
            if (relative.getType() == Material.LAVA) hasLava = true;
            if (hasWater && hasLava) return true;
        }
        return false;
    }

    // 权重随机算法
    private Material getRandomOre() {
        if (orePool.isEmpty() || totalWeight <= 0) return Material.COBBLESTONE;
        int r = new Random().nextInt(totalWeight);
        int sum = 0;
        for (OreEntry entry : orePool) {
            sum += entry.weight;
            if (r < sum) return entry.material;
        }
        return Material.COBBLESTONE;
    }

    // 加载或生成配置文件
    private void loadConfig() {
        configFile = new File(getDataFolder(), "cobbleore.yml");
        if (!configFile.exists()) {
            configFile.getParentFile().mkdirs();
            try {
                configFile.createNewFile();
            } catch (IOException e) {
                getLogger().warning("无法创建配置文件:" + e.getMessage());
            }
        }
        config = YamlConfiguration.loadConfiguration(configFile);
        // 默认配置
        if (!config.contains("ores")) {
            config.set("ores.STONE", 60);
            config.set("ores.COAL_ORE", 15);
            config.set("ores.IRON_ORE", 10);
            config.set("ores.GOLD_ORE", 5);
            config.set("ores.DIAMOND_ORE", 2);
            saveConfigFile();
        }
        reloadOrePool();
    }

    // 保存配置
    private void saveConfigFile() {
        try {
            config.save(configFile);
        } catch (IOException e) {
            getLogger().warning("保存配置失败:" + e.getMessage());
        }
    }

    // 重新加载权重池
    private void reloadOrePool() {
        orePool.clear();
        totalWeight = 0;
        if (config == null) return;
        if (!config.contains("ores")) return;
        for (String key : config.getConfigurationSection("ores").getKeys(false)) {
            int weight = config.getInt("ores." + key, 0);
            Material mat = Material.getMaterial(key);
            if (mat != null && weight > 0) {
                orePool.add(new OreEntry(mat, weight));
                totalWeight += weight;
            }
        }
        if (orePool.isEmpty()) {
            // 至少保证有圆石
            orePool.add(new OreEntry(Material.COBBLESTONE, 1));
            totalWeight = 1;
        }
    }

    // 命令:/cobbleore reload
    @Override
    public boolean onCommand(org.bukkit.command.CommandSender sender, org.bukkit.command.Command cmd, String label, String[] args) {
        if (cmd.getName().equalsIgnoreCase("cobbleore")) {
            if (args.length == 1 && args[0].equalsIgnoreCase("reload")) {
                if (!sender.hasPermission("cobbleore.reload")) {
                    sender.sendMessage("§c你没有权限重载配置。");
                    return true;
                }
                config = YamlConfiguration.loadConfiguration(configFile);
                reloadOrePool();
                sender.sendMessage("§aCobbleOreGenerator 配置已重载。");
                return true;
            }
            sender.sendMessage("§e用法: /cobbleore reload");
            return true;
        }
        return false;
    }

    // 权重池条目
    private static class OreEntry {
        Material material;
        int weight;
        OreEntry(Material material, int weight) {
            this.material = material;
            this.weight = weight;
        }
    }
}

上一篇: MuteManager下一篇: ExpShopMenu

举报内容

意见反馈