Remove NMS

Break blocks
Pulling chests
This commit is contained in:
Ilya 2022-02-10 18:32:11 +03:00
parent 956129f97d
commit 7829f4b145

View File

@ -1,6 +1,6 @@
package ru.redguy.extendedpistons; package ru.redguy.extendedpistons;
import net.minecraft.server.v1_12_R1.BlockPosition; import com.google.common.collect.Lists;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
@ -10,12 +10,12 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockPistonExtendEvent; import org.bukkit.event.block.BlockPistonExtendEvent;
import org.bukkit.event.block.BlockPistonRetractEvent;
import org.bukkit.event.block.BlockRedstoneEvent; import org.bukkit.event.block.BlockRedstoneEvent;
import org.bukkit.material.PistonBaseMaterial; import org.bukkit.material.PistonBaseMaterial;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.*;
public class WorldListener implements Listener { public class WorldListener implements Listener {
@EventHandler(priority = EventPriority.LOW,ignoreCancelled = true) @EventHandler(priority = EventPriority.LOW,ignoreCancelled = true)
@ -24,10 +24,10 @@ public class WorldListener implements Listener {
Block block = e.getBlock(); Block block = e.getBlock();
BlockState state = block.getState(); BlockState state = block.getState();
PistonBaseMaterial piston = (PistonBaseMaterial) state.getData(); PistonBaseMaterial piston = (PistonBaseMaterial) state.getData();
Player player = findNearbyPlayer(block.getLocation()); int maxBlocks = findNearbyPlayerMaxBlocks(block.getLocation());
int maxBlocks = 20;//TODO: get max length
ArrayList<Block> blocks = new ArrayList<>(); ArrayList<Block> blocks = new ArrayList<>();
Block toBreak = null;
boolean isMovable = true; boolean isMovable = true;
Block firstBlock = block.getRelative(piston.getFacing()); Block firstBlock = block.getRelative(piston.getFacing());
if (firstBlock.isLiquid() || firstBlock.isEmpty()) { if (firstBlock.isLiquid() || firstBlock.isEmpty()) {
@ -36,11 +36,14 @@ public class WorldListener implements Listener {
Block b = block.getRelative(piston.getFacing(), i); Block b = block.getRelative(piston.getFacing(), i);
if (b.isLiquid() || b.isEmpty()) break; if (b.isLiquid() || b.isEmpty()) break;
if (b.getPistonMoveReaction().equals(PistonMoveReaction.IGNORE) || b.getPistonMoveReaction().equals(PistonMoveReaction.BLOCK)) { if (b.getPistonMoveReaction().equals(PistonMoveReaction.IGNORE) || b.getPistonMoveReaction().equals(PistonMoveReaction.BLOCK)) {
if (!(b.getType() == Material.CHEST || b.getType() == Material.ENDER_CHEST || b.getType() == Material.FURNACE || b.getType() == Material.BURNING_FURNACE)) { if (!(b.getType() == Material.CHEST || b.getType() == Material.FURNACE || b.getType() == Material.BURNING_FURNACE)) {
isMovable = false; isMovable = false;
} else { } else {
blocks.add(b);//TODO: проверять на возух blocks.add(b);
} }
} else if(b.getPistonMoveReaction().equals(PistonMoveReaction.BREAK)) {
toBreak = b;
break;
} else { } else {
blocks.add(b); blocks.add(b);
} }
@ -57,84 +60,132 @@ public class WorldListener implements Listener {
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onRedstone(BlockRedstoneEvent e) { public void onRedstone(BlockRedstoneEvent e) {
Bukkit.getScheduler().runTask(ExtendedPistons.INSTANCE, () -> { HashMap<BlockFace,BlockState> states = new HashMap<>();
if (e.getOldCurrent() != 0 && e.getNewCurrent() == 0) return; for (BlockFace face : new BlockFace[]{BlockFace.SELF, BlockFace.UP, BlockFace.DOWN, BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, BlockFace.WEST}) {
ArrayList<BlockFace> checkedBlockFaces = new ArrayList<BlockFace>() {{ states.put(face,e.getBlock().getRelative(face).getState());
add(BlockFace.SELF); }
add(BlockFace.UP); Bukkit.getScheduler().runTask(ExtendedPistons.INSTANCE,() -> {
add(BlockFace.DOWN); if (e.getOldCurrent() != 0 && e.getNewCurrent() == 0) {
}}; ArrayList<BlockFace> checkedBlockFaces = new ArrayList<BlockFace>() {{
if(e.getBlock().getType().equals(Material.REDSTONE_WIRE)) { add(BlockFace.SELF);
for (BlockFace blockFace : new BlockFace[]{BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, BlockFace.WEST}) { add(BlockFace.UP);
Block block = e.getBlock().getRelative(blockFace); add(BlockFace.DOWN);
net.minecraft.server.v1_12_R1.World nmsWorld = ((org.bukkit.craftbukkit.v1_12_R1.CraftWorld) block.getWorld()).getHandle(); }};
BlockPosition bp = new BlockPosition(block.getX(), block.getY(), block.getZ()); if (e.getBlock().getType().equals(Material.REDSTONE_WIRE)) {
if (nmsWorld.getBlockPower(bp) != 0) checkedBlockFaces.add(blockFace); for (BlockFace blockFace : new BlockFace[]{BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, BlockFace.WEST}) {
Block block = e.getBlock().getRelative(blockFace);
if (block.getBlockPower() == 0) checkedBlockFaces.add(blockFace);
}
} else {
checkedBlockFaces.add(BlockFace.NORTH);
checkedBlockFaces.add(BlockFace.SOUTH);
checkedBlockFaces.add(BlockFace.EAST);
checkedBlockFaces.add(BlockFace.WEST);
}
for (BlockFace face : checkedBlockFaces) {
Block block = e.getBlock().getRelative(face);
BlockState state = states.get(face);
if (state.getType().equals(Material.PISTON_STICKY_BASE)) {
PistonBaseMaterial piston = (PistonBaseMaterial) state.getData();
Block b = block.getRelative(piston.getFacing(),2);
if(b.getType().equals(Material.CHEST)||b.getType().equals(Material.FURNACE)||b.getType().equals(Material.BURNING_FURNACE)) {
Block b2 = block.getRelative(piston.getFacing());
BlockPistonRetractEvent ev = new BlockPistonRetractEvent(block, Lists.newArrayList(b2),piston.getFacing());
Bukkit.getPluginManager().callEvent(ev);
if(ev.isCancelled()) continue;
b2.setType(b.getType());
b2.setData(b.getData());
if (b.getType().equals(Material.CHEST)) {
Chest oldChest = (Chest) b.getState();
Chest newChest = (Chest) b2.getState();
newChest.getBlockInventory().setContents(oldChest.getBlockInventory().getContents());
oldChest.getBlockInventory().clear();
} else if (b.getType().equals(Material.FURNACE) || b.getType().equals(Material.BURNING_FURNACE)) {
Furnace oldFurnace = (Furnace) b.getState();
Furnace newFurnace = (Furnace) b2.getState();
newFurnace.getInventory().setContents(oldFurnace.getInventory().getContents());
oldFurnace.getInventory().clear();
}
b.setType(Material.AIR);
}
}
} }
} else { } else {
checkedBlockFaces.add(BlockFace.NORTH); ArrayList<BlockFace> checkedBlockFaces = new ArrayList<BlockFace>() {{
checkedBlockFaces.add(BlockFace.SOUTH); add(BlockFace.SELF);
checkedBlockFaces.add(BlockFace.EAST); add(BlockFace.UP);
checkedBlockFaces.add(BlockFace.WEST); add(BlockFace.DOWN);
} }};
for (BlockFace face : checkedBlockFaces) { if (e.getBlock().getType().equals(Material.REDSTONE_WIRE)) {
Block block = e.getBlock().getRelative(face); for (BlockFace blockFace : new BlockFace[]{BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, BlockFace.WEST}) {
if (block.getType().equals(Material.PISTON_BASE) || block.getType().equals(Material.PISTON_STICKY_BASE)) { Block block = e.getBlock().getRelative(blockFace);
BlockState state = block.getState(); if (block.getBlockPower() != 0) checkedBlockFaces.add(blockFace);
PistonBaseMaterial piston = (PistonBaseMaterial) state.getData();
Player player = findNearbyPlayer(block.getLocation());
int maxBlocks = 20;//TODO: get max length
ArrayList<Block> blocks = new ArrayList<>();
Block toBreak = null;
boolean isMovable = true;
Block firstBlock = block.getRelative(piston.getFacing());
if (firstBlock.isLiquid() || firstBlock.isEmpty()) {
} else {
for (int i = 1; i < maxBlocks + 1; i++) {
Block b = block.getRelative(piston.getFacing(), i);
if (b.isLiquid() || b.isEmpty()) break;
if (b.getPistonMoveReaction().equals(PistonMoveReaction.IGNORE) || b.getPistonMoveReaction().equals(PistonMoveReaction.BLOCK)) {
if (!(b.getType() == Material.CHEST || b.getType() == Material.ENDER_CHEST || b.getType() == Material.FURNACE || b.getType() == Material.BURNING_FURNACE)) {
isMovable = false;
} else {
blocks.add(b);//TODO: проверять на возух
}
} else if(b.getPistonMoveReaction().equals(PistonMoveReaction.BREAK)) {
toBreak = b;
break;
} else {
blocks.add(b);
}
}
Block lastBlock = block.getRelative(piston.getFacing(), blocks.size() + 1);
if (!(lastBlock.getPistonMoveReaction().equals(PistonMoveReaction.BREAK) || lastBlock.isEmpty() || lastBlock.isLiquid()))
isMovable = false;
} }
} else {
checkedBlockFaces.add(BlockFace.NORTH);
checkedBlockFaces.add(BlockFace.SOUTH);
checkedBlockFaces.add(BlockFace.EAST);
checkedBlockFaces.add(BlockFace.WEST);
}
for (BlockFace face : checkedBlockFaces) {
Block block = e.getBlock().getRelative(face);
if (block.getType().equals(Material.PISTON_BASE) || block.getType().equals(Material.PISTON_STICKY_BASE)) {
BlockState state = states.get(face);
PistonBaseMaterial piston = (PistonBaseMaterial) state.getData();
int maxBlocks = findNearbyPlayerMaxBlocks(block.getLocation());
ArrayList<Block> blocks = new ArrayList<>();
if (isMovable) { Block toBreak = null;
BlockPistonExtendedExtendEvent event = new BlockPistonExtendedExtendEvent(block, blocks, piston.getFacing()); boolean isMovable = true;
Bukkit.getPluginManager().callEvent(event); Block firstBlock = block.getRelative(piston.getFacing());
if (event.isCancelled()) return; if (firstBlock.isLiquid() || firstBlock.isEmpty()) {
Collections.reverse(blocks); } else {
if(toBreak!=null) toBreak.breakNaturally(); for (int i = 1; i < maxBlocks + 1; i++) {
for (Block b : blocks) { Block b = block.getRelative(piston.getFacing(), i);
Block b2 = b.getRelative(piston.getFacing()); if (b.isLiquid() || b.isEmpty()) break;
b2.setType(b.getType()); if (b.getPistonMoveReaction().equals(PistonMoveReaction.IGNORE) || b.getPistonMoveReaction().equals(PistonMoveReaction.BLOCK)) {
b2.setData(b.getData()); if (!(b.getType() == Material.CHEST || b.getType() == Material.FURNACE || b.getType() == Material.BURNING_FURNACE)) {
if(b.getType().equals(Material.CHEST)) { isMovable = false;
Chest oldChest = (Chest) b.getState(); } else {
Chest newChest = (Chest) b2.getState(); blocks.add(b);
newChest.getBlockInventory().setContents(oldChest.getBlockInventory().getContents()); }
oldChest.getBlockInventory().clear(); } else if (b.getPistonMoveReaction().equals(PistonMoveReaction.BREAK)) {
} else if(b.getType().equals(Material.FURNACE)||b.getType().equals(Material.BURNING_FURNACE)) { toBreak = b;
Furnace oldFurnace = (Furnace) b.getState(); break;
Furnace newFurnace = (Furnace) b2.getState(); } else {
newFurnace.getInventory().setContents(oldFurnace.getInventory().getContents()); blocks.add(b);
oldFurnace.getInventory().clear(); }
}
Block lastBlock = block.getRelative(piston.getFacing(), blocks.size() + 1);
if (!(lastBlock.getPistonMoveReaction().equals(PistonMoveReaction.BREAK) || lastBlock.isEmpty() || lastBlock.isLiquid()))
isMovable = false;
}
if (isMovable) {
BlockPistonExtendedExtendEvent event = new BlockPistonExtendedExtendEvent(block, blocks, piston.getFacing());
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) return;
Collections.reverse(blocks);
if (toBreak != null) toBreak.breakNaturally();
for (Block b : blocks) {
Block b2 = b.getRelative(piston.getFacing());
b2.setType(b.getType());
b2.setData(b.getData());
if (b.getType().equals(Material.CHEST)) {
Chest oldChest = (Chest) b.getState();
Chest newChest = (Chest) b2.getState();
newChest.getBlockInventory().setContents(oldChest.getBlockInventory().getContents());
oldChest.getBlockInventory().clear();
} else if (b.getType().equals(Material.FURNACE) || b.getType().equals(Material.BURNING_FURNACE)) {
Furnace oldFurnace = (Furnace) b.getState();
Furnace newFurnace = (Furnace) b2.getState();
newFurnace.getInventory().setContents(oldFurnace.getInventory().getContents());
oldFurnace.getInventory().clear();
}
b.setType(Material.AIR);
} }
b.setType(Material.AIR);
} }
} }
} }
@ -142,7 +193,12 @@ public class WorldListener implements Listener {
}); });
} }
public Player findNearbyPlayer(Location location) { public int findNearbyPlayerMaxBlocks(Location location) {
return Bukkit.getOnlinePlayers().stream().min(Comparator.comparingDouble(p -> p.getLocation().distance(location))).get(); Optional<Player> op = (Optional<Player>) Bukkit.getOnlinePlayers().stream().min(Comparator.comparingDouble(p -> p.getLocation().distance(location)));
if(op.isPresent()) {
return 20; //TODO
} else {
return 12;
}
} }
} }