feat(hamster-chain-break): 将掉落物直接发送至玩家身边

This commit is contained in:
2023-06-07 12:53:03 +08:00
parent 7d1e575a8c
commit 3831a51f34

View File

@@ -4,14 +4,17 @@ import cn.hamster3.mc.plugin.chain.breaks.config.ToolGroup;
import cn.hamster3.mc.plugin.chain.breaks.core.ConfigManager; import cn.hamster3.mc.plugin.chain.breaks.core.ConfigManager;
import cn.hamster3.mc.plugin.chain.breaks.util.ChainBreakUtils; import cn.hamster3.mc.plugin.chain.breaks.util.ChainBreakUtils;
import de.tr7zw.nbtapi.NBTItem; import de.tr7zw.nbtapi.NBTItem;
import org.bukkit.*; import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.World;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.ArrayList; import java.util.ArrayList;
@@ -20,13 +23,41 @@ import java.util.List;
public final class MainListener implements Listener { public final class MainListener implements Listener {
public static final MainListener INSTANCE = new MainListener(); public static final MainListener INSTANCE = new MainListener();
private static final BlockFace[] BLOCK_FACES = new BlockFace[]{ private final Pos[] BLOCK_RELATIVES = new Pos[]{
BlockFace.NORTH, new Pos(1, 1, 1),
BlockFace.EAST, new Pos(1, 1, 0),
BlockFace.SOUTH, new Pos(1, 1, -1),
BlockFace.WEST,
BlockFace.UP, new Pos(1, 0, 1),
BlockFace.DOWN new Pos(1, 0, 0),
new Pos(1, 0, -1),
new Pos(1, -1, 1),
new Pos(1, -1, 0),
new Pos(1, -1, -1),
new Pos(0, 1, 1),
new Pos(0, 1, 0),
new Pos(0, 1, -1),
new Pos(0, 0, 1),
new Pos(0, 0, -1),
new Pos(0, -1, 1),
new Pos(0, -1, 0),
new Pos(0, -1, -1),
new Pos(-1, 1, 1),
new Pos(-1, 1, 0),
new Pos(-1, 1, -1),
new Pos(-1, 0, 1),
new Pos(-1, 0, 0),
new Pos(-1, 0, -1),
new Pos(-1, -1, 1),
new Pos(-1, -1, 0),
new Pos(-1, -1, -1)
}; };
private MainListener() { private MainListener() {
@@ -49,10 +80,10 @@ public final class MainListener implements Listener {
} }
List<Block> searchResultBlocks = new ArrayList<>(); List<Block> searchResultBlocks = new ArrayList<>();
bfsSearchBlock(group, searchResultBlocks, Collections.singletonList(eventBlock)); bfsSearchBlock(group, searchResultBlocks, Collections.singletonList(eventBlock));
searchResultBlocks.remove(eventBlock);
if (searchResultBlocks.isEmpty()) { if (searchResultBlocks.isEmpty()) {
return; return;
} }
event.setCancelled(true);
if (player.getGameMode() == GameMode.CREATIVE) { if (player.getGameMode() == GameMode.CREATIVE) {
breakBlockWithCreative(player, stack, eventBlock, searchResultBlocks); breakBlockWithCreative(player, stack, eventBlock, searchResultBlocks);
return; return;
@@ -68,8 +99,8 @@ public final class MainListener implements Listener {
private void bfsSearchBlock(@NotNull ToolGroup group, @NotNull List<Block> result, @NotNull List<Block> searchBlocks) { private void bfsSearchBlock(@NotNull ToolGroup group, @NotNull List<Block> result, @NotNull List<Block> searchBlocks) {
ArrayList<Block> nextSearchBlocks = new ArrayList<>(); ArrayList<Block> nextSearchBlocks = new ArrayList<>();
for (Block block : searchBlocks) { for (Block block : searchBlocks) {
for (BlockFace face : BLOCK_FACES) { for (Pos pos : BLOCK_RELATIVES) {
Block relative = block.getRelative(face); Block relative = block.getRelative(pos.x, pos.y, pos.z);
if (relative.getType() == Material.AIR) { if (relative.getType() == Material.AIR) {
continue; continue;
} }
@@ -95,20 +126,21 @@ public final class MainListener implements Listener {
private void breakBlockWithCreative(Player player, ItemStack stack, Block eventBlock, List<Block> searchResultBlocks) { private void breakBlockWithCreative(Player player, ItemStack stack, Block eventBlock, List<Block> searchResultBlocks) {
List<ItemStack> dropItemList = new ArrayList<>(); List<ItemStack> dropItemList = new ArrayList<>();
World blockWorld = eventBlock.getWorld(); World blockWorld = eventBlock.getWorld();
Location blockLocation = eventBlock.getLocation();
for (Block block : searchResultBlocks) { for (Block block : searchResultBlocks) {
dropItemList.addAll(block.getDrops(stack, player)); dropItemList.addAll(block.getDrops(stack, player));
block.setType(Material.AIR, true); block.setType(Material.AIR, true);
} }
PlayerInventory inventory = player.getInventory();
for (ItemStack dropItem : dropItemList) { for (ItemStack dropItem : dropItemList) {
blockWorld.dropItem(blockLocation, dropItem); for (ItemStack value : inventory.addItem(dropItem).values()) {
blockWorld.dropItem(player.getLocation(), value);
}
} }
} }
private void breakBlockWithEnergy(Player player, ItemStack stack, NBTItem nbtItem, Block eventBlock, List<Block> searchResultBlocks) { private void breakBlockWithEnergy(Player player, ItemStack stack, NBTItem nbtItem, Block eventBlock, List<Block> searchResultBlocks) {
List<ItemStack> dropItemList = new ArrayList<>(); List<ItemStack> dropItemList = new ArrayList<>();
World blockWorld = eventBlock.getWorld(); World blockWorld = eventBlock.getWorld();
Location blockLocation = eventBlock.getLocation();
int energy = nbtItem.getInteger("Energy"); int energy = nbtItem.getInteger("Energy");
if (energy <= 0) { if (energy <= 0) {
return; return;
@@ -124,18 +156,20 @@ public final class MainListener implements Listener {
} }
} }
} }
PlayerInventory inventory = player.getInventory();
for (ItemStack dropItem : dropItemList) { for (ItemStack dropItem : dropItemList) {
blockWorld.dropItem(blockLocation, dropItem); for (ItemStack value : inventory.addItem(dropItem).values()) {
blockWorld.dropItem(player.getLocation(), value);
}
} }
nbtItem.setInteger("Energy", energy); nbtItem.setInteger("Energy", energy);
player.getInventory().setItemInMainHand(nbtItem.getItem()); inventory.setItemInMainHand(nbtItem.getItem());
} }
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
private void breakBlockWithDurability(Player player, ItemStack stack, Block eventBlock, List<Block> searchResultBlocks) { private void breakBlockWithDurability(Player player, ItemStack stack, Block eventBlock, List<Block> searchResultBlocks) {
List<ItemStack> dropItemList = new ArrayList<>(); List<ItemStack> dropItemList = new ArrayList<>();
World blockWorld = eventBlock.getWorld(); World blockWorld = eventBlock.getWorld();
Location blockLocation = eventBlock.getLocation();
short maxDurability = stack.getType().getMaxDurability(); short maxDurability = stack.getType().getMaxDurability();
short durability = stack.getDurability(); short durability = stack.getDurability();
if (durability >= maxDurability) { if (durability >= maxDurability) {
@@ -152,15 +186,29 @@ public final class MainListener implements Listener {
} }
} }
} }
PlayerInventory inventory = player.getInventory();
for (ItemStack dropItem : dropItemList) { for (ItemStack dropItem : dropItemList) {
blockWorld.dropItem(blockLocation, dropItem); for (ItemStack value : inventory.addItem(dropItem).values()) {
blockWorld.dropItem(player.getLocation(), value);
}
} }
if (durability >= maxDurability) { if (durability >= maxDurability) {
player.getInventory().setItemInMainHand(null); inventory.setItemInMainHand(null);
player.getWorld().playSound(player.getLocation(), Sound.ENTITY_ITEM_BREAK, 1, 1); player.getWorld().playSound(player.getLocation(), Sound.ENTITY_ITEM_BREAK, 1, 1);
} else { } else {
stack.setDurability(durability); stack.setDurability(durability);
} }
} }
private static class Pos {
private final int x;
private final int y;
private final int z;
public Pos(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
}
} }