feat(hamster-chain-break): 连锁破坏插件
This commit is contained in:
2
hamster-chain-break/build.gradle
Normal file
2
hamster-chain-break/build.gradle
Normal file
@@ -0,0 +1,2 @@
|
||||
version = '1.0.0'
|
||||
setArchivesBaseName("HamsterChainBreak")
|
@@ -0,0 +1,26 @@
|
||||
package cn.hamster3.mc.plugin.chain.breaks;
|
||||
|
||||
import cn.hamster3.mc.plugin.chain.breaks.core.ConfigManager;
|
||||
import cn.hamster3.mc.plugin.chain.breaks.listener.MainListener;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
public class ChainBreakPlugin extends JavaPlugin {
|
||||
private static ChainBreakPlugin instance;
|
||||
|
||||
public static ChainBreakPlugin getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
instance = this;
|
||||
ConfigManager.init();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
Bukkit.getPluginManager().registerEvents(MainListener.INSTANCE, this);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,22 @@
|
||||
package cn.hamster3.mc.plugin.chain.breaks.config;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
public class ToolGroup {
|
||||
private final String name;
|
||||
private final List<String> toolTypes;
|
||||
private final List<String> blockTypes;
|
||||
private final List<String> skipBlockTypes;
|
||||
|
||||
public ToolGroup(@NotNull ConfigurationSection config) {
|
||||
name = config.getName();
|
||||
toolTypes = config.getStringList("tool-types");
|
||||
blockTypes = config.getStringList("block-types");
|
||||
skipBlockTypes = config.getStringList("skip-block-types");
|
||||
}
|
||||
}
|
@@ -0,0 +1,34 @@
|
||||
package cn.hamster3.mc.plugin.chain.breaks.core;
|
||||
|
||||
import cn.hamster3.mc.plugin.chain.breaks.ChainBreakPlugin;
|
||||
import cn.hamster3.mc.plugin.chain.breaks.config.ToolGroup;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public final class ConfigManager {
|
||||
private static List<ToolGroup> toolGroups;
|
||||
|
||||
private ConfigManager() {
|
||||
}
|
||||
|
||||
public static void init() {
|
||||
ChainBreakPlugin plugin = ChainBreakPlugin.getInstance();
|
||||
plugin.saveDefaultConfig();
|
||||
plugin.reloadConfig();
|
||||
FileConfiguration pluginConfig = plugin.getConfig();
|
||||
|
||||
toolGroups = new ArrayList<>();
|
||||
ConfigurationSection toolGroupsConfig = pluginConfig.getConfigurationSection("tool-groups");
|
||||
for (String key : toolGroupsConfig.getKeys(false)) {
|
||||
ToolGroup group = new ToolGroup(toolGroupsConfig.getConfigurationSection(key));
|
||||
toolGroups.add(group);
|
||||
}
|
||||
}
|
||||
|
||||
public static List<ToolGroup> getToolGroups() {
|
||||
return toolGroups;
|
||||
}
|
||||
}
|
@@ -0,0 +1,106 @@
|
||||
package cn.hamster3.mc.plugin.chain.breaks.listener;
|
||||
|
||||
import cn.hamster3.mc.plugin.chain.breaks.config.ToolGroup;
|
||||
import cn.hamster3.mc.plugin.chain.breaks.util.ChainBreakUtils;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
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.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public final class MainListener implements Listener {
|
||||
public static final MainListener INSTANCE = new MainListener();
|
||||
private static final BlockFace[] BLOCK_FACES = new BlockFace[]{
|
||||
BlockFace.NORTH,
|
||||
BlockFace.EAST,
|
||||
BlockFace.SOUTH,
|
||||
BlockFace.WEST,
|
||||
BlockFace.UP,
|
||||
BlockFace.DOWN
|
||||
};
|
||||
|
||||
private MainListener() {
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onBlockBreak(BlockBreakEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
if (player.isSneaking()) {
|
||||
return;
|
||||
}
|
||||
ItemStack stack = player.getInventory().getItemInMainHand();
|
||||
ToolGroup group = ChainBreakUtils.getToolGroup(stack);
|
||||
if (group == null) {
|
||||
return;
|
||||
}
|
||||
if (!ChainBreakUtils.isToolGroupBlock(group, event.getBlock())) {
|
||||
return;
|
||||
}
|
||||
List<Block> resultBlocks = new ArrayList<>();
|
||||
bfsSearchBlock(group, resultBlocks, Collections.singletonList(event.getBlock()));
|
||||
resultBlocks.remove(event.getBlock());
|
||||
if (resultBlocks.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (player.getGameMode() == GameMode.CREATIVE) {
|
||||
for (Block block : resultBlocks) {
|
||||
block.breakNaturally(stack);
|
||||
}
|
||||
return;
|
||||
}
|
||||
short maxDurability = stack.getType().getMaxDurability();
|
||||
short durability = stack.getDurability();
|
||||
for (Block block : resultBlocks) {
|
||||
if (block.breakNaturally(stack)) {
|
||||
durability++;
|
||||
if (durability >= maxDurability) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (durability >= maxDurability) {
|
||||
player.getInventory().setItemInMainHand(null);
|
||||
player.getWorld().playSound(player.getLocation(), Sound.ENTITY_ITEM_BREAK, 1, 1);
|
||||
} else {
|
||||
stack.setDurability(durability);
|
||||
}
|
||||
}
|
||||
|
||||
private void bfsSearchBlock(@NotNull ToolGroup group, @NotNull List<Block> result, @NotNull List<Block> searchBlocks) {
|
||||
ArrayList<Block> nextSearchBlocks = new ArrayList<>();
|
||||
for (Block block : searchBlocks) {
|
||||
for (BlockFace face : BLOCK_FACES) {
|
||||
Block relative = block.getRelative(face);
|
||||
if (relative.getType() == Material.AIR) {
|
||||
continue;
|
||||
}
|
||||
if (result.contains(relative)) {
|
||||
continue;
|
||||
}
|
||||
if (!ChainBreakUtils.isToolGroupBlock(group, relative)) {
|
||||
continue;
|
||||
}
|
||||
result.add(relative);
|
||||
nextSearchBlocks.add(relative);
|
||||
if (result.size() > 300) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nextSearchBlocks.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
bfsSearchBlock(group, result, nextSearchBlocks);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,38 @@
|
||||
package cn.hamster3.mc.plugin.chain.breaks.util;
|
||||
|
||||
import cn.hamster3.mc.plugin.chain.breaks.config.ToolGroup;
|
||||
import cn.hamster3.mc.plugin.chain.breaks.core.ConfigManager;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class ChainBreakUtils {
|
||||
|
||||
@Nullable
|
||||
public static ToolGroup getToolGroup(@Nullable ItemStack stack) {
|
||||
if (stack == null) {
|
||||
return null;
|
||||
}
|
||||
String name = stack.getType().name().toLowerCase();
|
||||
for (ToolGroup group : ConfigManager.getToolGroups()) {
|
||||
for (String type : group.getToolTypes()) {
|
||||
if (name.matches(type)) {
|
||||
return group;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
|
||||
public static boolean isToolGroupBlock(@NotNull ToolGroup group, @NotNull Block block) {
|
||||
String name = block.getType().name().toLowerCase();
|
||||
for (String type : group.getBlockTypes()) {
|
||||
if (name.matches(type)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
17
hamster-chain-break/src/main/resources/config.yml
Normal file
17
hamster-chain-break/src/main/resources/config.yml
Normal file
@@ -0,0 +1,17 @@
|
||||
# 方块破坏的间隔时间
|
||||
# 单位: tick
|
||||
break-interval: 5
|
||||
|
||||
tool-groups:
|
||||
axe:
|
||||
tool-types:
|
||||
- ".*_axe"
|
||||
block-types:
|
||||
- ".*_wood"
|
||||
- ".*_log"
|
||||
- ".*_leaves"
|
||||
pickaxe:
|
||||
tool-types:
|
||||
- ".*_pickaxe"
|
||||
block-types:
|
||||
- ".*_ore"
|
8
hamster-chain-break/src/main/resources/plugin.yml
Normal file
8
hamster-chain-break/src/main/resources/plugin.yml
Normal file
@@ -0,0 +1,8 @@
|
||||
name: HamsterChainBreak
|
||||
main: cn.hamster3.mc.plugin.chain.breaks.ChainBreakPlugin
|
||||
version: ${version}
|
||||
api-version: 1.13
|
||||
|
||||
author: MiniDay
|
||||
website: https://github.com/MiniDay/hamster-little-plugins
|
||||
description: 仓鼠连锁破坏:一键挖矿 & 砍树
|
Reference in New Issue
Block a user