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.util.ChainBreakUtils;
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.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.bukkit.inventory.PlayerInventory;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
@@ -20,13 +23,41 @@ 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 final Pos[] BLOCK_RELATIVES = new Pos[]{
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),
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() {
@@ -49,10 +80,10 @@ public final class MainListener implements Listener {
}
List<Block> searchResultBlocks = new ArrayList<>();
bfsSearchBlock(group, searchResultBlocks, Collections.singletonList(eventBlock));
searchResultBlocks.remove(eventBlock);
if (searchResultBlocks.isEmpty()) {
return;
}
event.setCancelled(true);
if (player.getGameMode() == GameMode.CREATIVE) {
breakBlockWithCreative(player, stack, eventBlock, searchResultBlocks);
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) {
ArrayList<Block> nextSearchBlocks = new ArrayList<>();
for (Block block : searchBlocks) {
for (BlockFace face : BLOCK_FACES) {
Block relative = block.getRelative(face);
for (Pos pos : BLOCK_RELATIVES) {
Block relative = block.getRelative(pos.x, pos.y, pos.z);
if (relative.getType() == Material.AIR) {
continue;
}
@@ -95,20 +126,21 @@ public final class MainListener implements Listener {
private void breakBlockWithCreative(Player player, ItemStack stack, Block eventBlock, List<Block> searchResultBlocks) {
List<ItemStack> dropItemList = new ArrayList<>();
World blockWorld = eventBlock.getWorld();
Location blockLocation = eventBlock.getLocation();
for (Block block : searchResultBlocks) {
dropItemList.addAll(block.getDrops(stack, player));
block.setType(Material.AIR, true);
}
PlayerInventory inventory = player.getInventory();
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) {
List<ItemStack> dropItemList = new ArrayList<>();
World blockWorld = eventBlock.getWorld();
Location blockLocation = eventBlock.getLocation();
int energy = nbtItem.getInteger("Energy");
if (energy <= 0) {
return;
@@ -124,18 +156,20 @@ public final class MainListener implements Listener {
}
}
}
PlayerInventory inventory = player.getInventory();
for (ItemStack dropItem : dropItemList) {
blockWorld.dropItem(blockLocation, dropItem);
for (ItemStack value : inventory.addItem(dropItem).values()) {
blockWorld.dropItem(player.getLocation(), value);
}
}
nbtItem.setInteger("Energy", energy);
player.getInventory().setItemInMainHand(nbtItem.getItem());
inventory.setItemInMainHand(nbtItem.getItem());
}
@SuppressWarnings("deprecation")
private void breakBlockWithDurability(Player player, ItemStack stack, Block eventBlock, List<Block> searchResultBlocks) {
List<ItemStack> dropItemList = new ArrayList<>();
World blockWorld = eventBlock.getWorld();
Location blockLocation = eventBlock.getLocation();
short maxDurability = stack.getType().getMaxDurability();
short durability = stack.getDurability();
if (durability >= maxDurability) {
@@ -152,15 +186,29 @@ public final class MainListener implements Listener {
}
}
}
PlayerInventory inventory = player.getInventory();
for (ItemStack dropItem : dropItemList) {
blockWorld.dropItem(blockLocation, dropItem);
for (ItemStack value : inventory.addItem(dropItem).values()) {
blockWorld.dropItem(player.getLocation(), value);
}
}
if (durability >= maxDurability) {
player.getInventory().setItemInMainHand(null);
inventory.setItemInMainHand(null);
player.getWorld().playSound(player.getLocation(), Sound.ENTITY_ITEM_BREAK, 1, 1);
} else {
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;
}
}
}