diff --git a/src/main/java/ru/redguy/extendedpistons/ExtendedPistons.java b/src/main/java/ru/redguy/extendedpistons/ExtendedPistons.java index 4e5c30a..57f4f60 100644 --- a/src/main/java/ru/redguy/extendedpistons/ExtendedPistons.java +++ b/src/main/java/ru/redguy/extendedpistons/ExtendedPistons.java @@ -1,4 +1,4 @@ -package ru.redguy.extendedpistons; +package ru.redguy.extendedpistons; //TODO: Block 3th chest is his at the sides, slime blocks, power supply remove, refactor import net.milkbowl.vault.permission.Permission; import org.bukkit.Bukkit; diff --git a/src/main/java/ru/redguy/extendedpistons/PistonExtendsChecker.java b/src/main/java/ru/redguy/extendedpistons/PistonExtendsChecker.java new file mode 100644 index 0000000..c7fe889 --- /dev/null +++ b/src/main/java/ru/redguy/extendedpistons/PistonExtendsChecker.java @@ -0,0 +1,264 @@ +package ru.redguy.extendedpistons; + +import com.google.common.collect.Lists; +import net.minecraft.server.v1_12_R1.*; +import org.bukkit.Location; +import org.bukkit.block.BlockFace; +import org.bukkit.craftbukkit.v1_12_R1.CraftWorld; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +public class PistonExtendsChecker { + private final net.minecraft.server.v1_12_R1.World a; + private final BlockPosition b; + private final BlockPosition c; + private final EnumDirection d; + private final List e = Lists.newArrayList(); + private final List f = Lists.newArrayList(); + private org.bukkit.World bw; + private int maxLength; + + private PistonExtendsChecker(World var1, BlockPosition var2, EnumDirection var3, boolean var4) { + this.a = var1; + this.b = var2; + if (var4) { + this.d = var3; + this.c = var2.shift(var3); + } else { + this.d = var3.opposite(); + this.c = var2.shift(var3, 2); + } + + } + + public PistonExtendsChecker(org.bukkit.World var1, Location var2, BlockFace var3, boolean var4, int maxLength) { + this(((CraftWorld)var1).getHandle(),new BlockPosition(var2.getBlockX(),var2.getBlockY(),var2.getBlockZ()),cast(var3),var4); + this.bw = var1; + this.maxLength = maxLength; + } + + public boolean a() { + this.e.clear(); + this.f.clear(); + IBlockData var1 = this.a.getType(this.c); + if (!BlockPiston.a(var1, this.a, this.c, this.d, false, this.d)) { + if (var1.o() == EnumPistonReaction.DESTROY) { + this.f.add(this.c); + return true; + } else { + System.out.println("A"+var1.getBlock().isTileEntity()); + return false; + } + } else if (!this.a(this.c, this.d)) { + System.out.println("B"); + return false; + } else { + for(int var2 = 0; var2 < this.e.size(); ++var2) { + BlockPosition var3 = (BlockPosition)this.e.get(var2); + if (this.a.getType(var3).getBlock() == Blocks.SLIME && !this.a(var3)) { + System.out.println("C"); + return false; + } + } + return true; + } + } + + private boolean a(BlockPosition var1, EnumDirection var2) { + IBlockData var3 = this.a.getType(var1); + Block var4 = var3.getBlock(); + if (var3.getMaterial() == Material.AIR) { + return true; + } else if (!BlockPiston.a(var3, this.a, var1, this.d, false, var2)) { + return true; + } else if (var1.equals(this.b)) { + return true; + } else if (this.e.contains(var1)) { + return true; + } else { + int var5 = 1; + if (var5 + this.e.size() > maxLength) {//Надо найти почему false и сделать сундуки + return false; + } else { + while(var4 == Blocks.SLIME) { + BlockPosition var6 = var1.shift(this.d.opposite(), var5); + var3 = this.a.getType(var6); + var4 = var3.getBlock(); + if (var3.getMaterial() == Material.AIR || !BlockPiston.a(var3, this.a, var6, this.d, false, this.d.opposite()) || var6.equals(this.b)) { + break; + } + + ++var5; + if (var5 + this.e.size() > maxLength) { + return false; + } + } + + int var12 = 0; + + int var7; + for(var7 = var5 - 1; var7 >= 0; --var7) { + this.e.add(var1.shift(this.d.opposite(), var7)); + ++var12; + } + + var7 = 1; + + while(true) { + BlockPosition var8 = var1.shift(this.d, var7); + int var9 = this.e.indexOf(var8); + if (var9 > -1) { + this.a(var12, var9); + + for(int var10 = 0; var10 <= var9 + var12; ++var10) { + BlockPosition var11 = (BlockPosition)this.e.get(var10); + if (this.a.getType(var11).getBlock() == Blocks.SLIME && !this.a(var11)) { + return false; + } + } + + return true; + } + + var3 = this.a.getType(var8); + if (var3.getMaterial() == Material.AIR) { + return true; + } + + if (!BlockPiston.a(var3, this.a, var8, this.d, true, this.d) || var8.equals(this.b)) { + return false; + } + + if (var3.o() == EnumPistonReaction.DESTROY) { + this.f.add(var8); + return true; + } + + if (this.e.size() >= maxLength) { + return false; + } + + this.e.add(var8); + ++var12; + ++var7; + } + } + } + } + + private void a(int var1, int var2) { + ArrayList var3 = Lists.newArrayList(); + ArrayList var4 = Lists.newArrayList(); + ArrayList var5 = Lists.newArrayList(); + var3.addAll(this.e.subList(0, var2)); + var4.addAll(this.e.subList(this.e.size() - var1, this.e.size())); + var5.addAll(this.e.subList(var2, this.e.size() - var1)); + this.e.clear(); + this.e.addAll(var3); + this.e.addAll(var4); + this.e.addAll(var5); + } + + private boolean a(BlockPosition var1) { + EnumDirection[] var2 = EnumDirection.values(); + int var3 = var2.length; + + for(int var4 = 0; var4 < var3; ++var4) { + EnumDirection var5 = var2[var4]; + if (var5.k() != this.d.k() && !this.a(var1.shift(var5), var5)) { + return false; + } + } + + return true; + } + + public List getMovedBlocks() { + return this.e; + } + + public List getBrokenBlocks() { + return this.f; + } + + public List getMovedBlocksLocations() { + return this.e.stream().map(bp -> new Location(bw,bp.getX(),bp.getY(),bp.getZ())).collect(Collectors.toList()); + } + + public List getBrokenBlocksLocations() { + return this.f.stream().map(bp -> new Location(bw,bp.getX(),bp.getY(),bp.getZ())).collect(Collectors.toList()); + } + + public List getMovedBlocksObjects() { + return this.e.stream().map(bp -> bw.getBlockAt(bp.getX(),bp.getY(),bp.getZ())).collect(Collectors.toList()); + } + + public List getBrokenBlocksObjects() { + return this.f.stream().map(bp -> bw.getBlockAt(bp.getX(),bp.getY(),bp.getZ())).collect(Collectors.toList()); + } + + public static EnumDirection cast(BlockFace face) { + switch (face) { + case UP: + return EnumDirection.UP; + case DOWN: + return EnumDirection.DOWN; + case WEST: + return EnumDirection.WEST; + case SOUTH: + return EnumDirection.SOUTH; + case NORTH: + return EnumDirection.NORTH; + case EAST: + return EnumDirection.EAST; + } + return null; + } + + public static class BlockPiston { + public static boolean a(IBlockData iblockdata, World world, BlockPosition blockposition, EnumDirection enumdirection, boolean flag, EnumDirection enumdirection1) { + Block block = iblockdata.getBlock(); + if (block == Blocks.OBSIDIAN) { + return false; + } else if (!world.getWorldBorder().a(blockposition)) { + return false; + } else if (blockposition.getY() < 0 || enumdirection == EnumDirection.DOWN && blockposition.getY() == 0) { + return false; + } else if (blockposition.getY() > world.getHeight() - 1 || enumdirection == EnumDirection.UP && blockposition.getY() == world.getHeight() - 1) { + return false; + } else { + if (block != Blocks.PISTON && block != Blocks.STICKY_PISTON) { + if (iblockdata.b(world, blockposition) == -1.0F) { + return false; + } + + switch(iblockdata.o().ordinal()) { + case 2: + return flag; + case 3: + return false; + case 4: + default: + break; + case 5: + if (enumdirection == enumdirection1) { + return true; + } + + return false; + } + } else if ((Boolean)iblockdata.get(net.minecraft.server.v1_12_R1.BlockPiston.EXTENDED)) { + return false; + } + + if(block.isTileEntity()) { + return block == Blocks.CHEST || block == Blocks.FURNACE || block == Blocks.LIT_FURNACE; + } else { + return true; + } + } + } + } +} diff --git a/src/main/java/ru/redguy/extendedpistons/WorldListener.java b/src/main/java/ru/redguy/extendedpistons/WorldListener.java index 79892ac..0f9ceff 100644 --- a/src/main/java/ru/redguy/extendedpistons/WorldListener.java +++ b/src/main/java/ru/redguy/extendedpistons/WorldListener.java @@ -27,43 +27,9 @@ public class WorldListener implements Listener { PistonBaseMaterial piston = (PistonBaseMaterial) state.getData(); int maxBlocks = findNearbyPlayerMaxBlocks(block.getLocation()); - ArrayList blocks = new ArrayList<>(); - 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)) { - break; - } else if (b.getPistonMoveReaction().equals(PistonMoveReaction.BREAK)) { - break; - } else if(b.getPistonMoveReaction().equals(PistonMoveReaction.MOVE)) { - if (b.getType() == Material.CHEST || b.getType() == Material.FURNACE || b.getType() == Material.BURNING_FURNACE) { - if (ExtendedPistons.INSTANCE.isAllowedTime()) { - if(b.getType() == Material.CHEST) { - Block b2 = block.getRelative(piston.getFacing(), i+2); - if(b2.getType() == Material.CHEST) { - Chest chest = (Chest) b2.getState(); - InventoryHolder ih = chest.getInventory().getHolder(); - if (ih instanceof DoubleChest) { - isMovable = false; - } else blocks.add(b); - } else blocks.add(b); - } else blocks.add(b); - } else isMovable = false; - } - } 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; - } + PistonExtendsChecker checker = new PistonExtendsChecker(e.getBlock().getWorld(),e.getBlock().getLocation(),piston.getFacing(),true,maxBlocks); - if (!isMovable) { + if (!checker.a()) { e.setCancelled(true); } } @@ -147,51 +113,19 @@ public class WorldListener implements Listener { PistonBaseMaterial piston = (PistonBaseMaterial) state.getData(); int maxBlocks = findNearbyPlayerMaxBlocks(block.getLocation()); - ArrayList 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)) { - break; - } else if (b.getPistonMoveReaction().equals(PistonMoveReaction.BREAK)) { - toBreak = b; - break; - } else if(b.getPistonMoveReaction().equals(PistonMoveReaction.MOVE)) { - if (b.getType() == Material.CHEST || b.getType() == Material.FURNACE || b.getType() == Material.BURNING_FURNACE) { - if (ExtendedPistons.INSTANCE.isAllowedTime()) { - if(b.getType() == Material.CHEST) { - Block b2 = block.getRelative(piston.getFacing(), i+2); - if(b2.getType() == Material.CHEST) { - Chest chest = (Chest) b2.getState(); - InventoryHolder ih = chest.getInventory().getHolder(); - if (ih instanceof DoubleChest) { - isMovable = false; - } else blocks.add(b); - } else blocks.add(b); - } else blocks.add(b); - } else isMovable = false; - } - } 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; - } - + PistonExtendsChecker checker = new PistonExtendsChecker(e.getBlock().getWorld(),block.getLocation(),piston.getFacing(),true,maxBlocks); + boolean isMovable = checker.a(); + List blocks = checker.getMovedBlocksObjects(); + List toBreak = checker.getBrokenBlocksObjects(); 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 block1 : toBreak) { + block1.breakNaturally(); + } for (Block b : blocks) { Block b2 = b.getRelative(piston.getFacing()); b2.setType(b.getType());