feat(hamster-chain-break): 连锁破坏插件

This commit is contained in:
2023-06-01 11:52:27 +08:00
parent ded3596584
commit fa272d336f
8 changed files with 253 additions and 0 deletions

View File

@@ -0,0 +1,2 @@
version = '1.0.0'
setArchivesBaseName("HamsterChainBreak")

View File

@@ -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);
}
}

View File

@@ -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");
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View 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"

View 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: 仓鼠连锁破坏:一键挖矿 & 砍树