From 3a8f45a04db19fcf2aa64fadc30911243bf6f8b3 Mon Sep 17 00:00:00 2001 From: TfT_02 Date: Sun, 15 Jun 2014 14:22:32 +0200 Subject: [PATCH] Fix bugs with pistons This commit improves piston tracking and fixes a couple of bugs with block tracking. Fixes #2043 --- Changelog.txt | 1 + .../nossr50/listeners/BlockListener.java | 21 ++++----- .../nossr50/runnables/PistonTrackerTask.java | 47 +++++++++++++++++++ .../runnables/StickyPistonTrackerTask.java | 9 +++- .../com/gmail/nossr50/util/BlockUtils.java | 6 +++ 5 files changed, 70 insertions(+), 14 deletions(-) create mode 100644 src/main/java/com/gmail/nossr50/runnables/PistonTrackerTask.java diff --git a/Changelog.txt b/Changelog.txt index 5415cc9f9..3ee3d31d7 100644 --- a/Changelog.txt +++ b/Changelog.txt @@ -15,6 +15,7 @@ Version 1.5.01-dev + Added support for `MATERIAL|data` format in treasures.yml + Added API to experience events to get XP gain reason + Added API to check if an entity is bleeding + = Fixed bug where pistons would mess with the block tracking = Fixed bug where the Updater was running on the main thread. = Fixed bug when players would use /ptp without being in a party = Fixed bug where player didn't have a mcMMOPlayer object in AsyncPlayerChatEvent diff --git a/src/main/java/com/gmail/nossr50/listeners/BlockListener.java b/src/main/java/com/gmail/nossr50/listeners/BlockListener.java index 8503f521c..6380402a3 100644 --- a/src/main/java/com/gmail/nossr50/listeners/BlockListener.java +++ b/src/main/java/com/gmail/nossr50/listeners/BlockListener.java @@ -31,6 +31,7 @@ import com.gmail.nossr50.datatypes.skills.SkillType; import com.gmail.nossr50.datatypes.skills.ToolType; import com.gmail.nossr50.events.fake.FakeBlockBreakEvent; import com.gmail.nossr50.events.fake.FakeBlockDamageEvent; +import com.gmail.nossr50.runnables.PistonTrackerTask; import com.gmail.nossr50.runnables.StickyPistonTrackerTask; import com.gmail.nossr50.skills.alchemy.Alchemy; import com.gmail.nossr50.skills.excavation.ExcavationManager; @@ -67,27 +68,23 @@ public class BlockListener implements Listener { return; } - List blocks = event.getBlocks(); BlockFace direction = event.getDirection(); Block futureEmptyBlock = event.getBlock().getRelative(direction); // Block that would be air after piston is finished + if (futureEmptyBlock.getType() == Material.AIR) { + return; + } + + List blocks = event.getBlocks(); + for (Block b : blocks) { if (BlockUtils.shouldBeWatched(b.getState()) && mcMMO.getPlaceStore().isTrue(b)) { b.getRelative(direction).setMetadata(mcMMO.blockMetadataKey, mcMMO.metadataValue); - if (b.equals(futureEmptyBlock) && futureEmptyBlock.getType() == Material.AIR) { - mcMMO.getPlaceStore().setFalse(b); - } } } - for (Block b : blocks) { - Block nextBlock = b.getRelative(direction); - - if (nextBlock.hasMetadata(mcMMO.blockMetadataKey)) { - mcMMO.getPlaceStore().setTrue(nextBlock); - nextBlock.removeMetadata(mcMMO.blockMetadataKey, plugin); - } - } + // Needed because blocks sometimes don't move when two pistons push towards each other + new PistonTrackerTask(blocks, direction, futureEmptyBlock).runTaskLater(plugin, 2); } /** diff --git a/src/main/java/com/gmail/nossr50/runnables/PistonTrackerTask.java b/src/main/java/com/gmail/nossr50/runnables/PistonTrackerTask.java new file mode 100644 index 000000000..2c5009ff5 --- /dev/null +++ b/src/main/java/com/gmail/nossr50/runnables/PistonTrackerTask.java @@ -0,0 +1,47 @@ +package com.gmail.nossr50.runnables; + +import java.util.List; + +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.scheduler.BukkitRunnable; + +import com.gmail.nossr50.mcMMO; +import com.gmail.nossr50.util.BlockUtils; + +public class PistonTrackerTask extends BukkitRunnable { + private List blocks; + private BlockFace direction; + private Block futureEmptyBlock; + + public PistonTrackerTask(List blocks, BlockFace direction, Block futureEmptyBlock) { + this.blocks = blocks; + this.direction = direction; + this.futureEmptyBlock = futureEmptyBlock; + } + + @Override + public void run() { + // Check to see if futureEmptyBlock is empty - if it isn't; the blocks didn't move + if (!BlockUtils.isPistonPiece(futureEmptyBlock.getState())) { + return; + } + + if (mcMMO.getPlaceStore().isTrue(futureEmptyBlock)) { + mcMMO.getPlaceStore().setFalse(futureEmptyBlock); + } + + for (Block b : blocks) { + Block nextBlock = b.getRelative(direction); + + if (nextBlock.hasMetadata(mcMMO.blockMetadataKey)) { + mcMMO.getPlaceStore().setTrue(nextBlock); + nextBlock.removeMetadata(mcMMO.blockMetadataKey, mcMMO.p); + } + else if (mcMMO.getPlaceStore().isTrue(nextBlock)) { + // Block doesn't have metadatakey but isTrue - set it to false + mcMMO.getPlaceStore().setFalse(nextBlock); + } + } + } +} diff --git a/src/main/java/com/gmail/nossr50/runnables/StickyPistonTrackerTask.java b/src/main/java/com/gmail/nossr50/runnables/StickyPistonTrackerTask.java index 28797b04f..3fa317742 100644 --- a/src/main/java/com/gmail/nossr50/runnables/StickyPistonTrackerTask.java +++ b/src/main/java/com/gmail/nossr50/runnables/StickyPistonTrackerTask.java @@ -2,7 +2,6 @@ package com.gmail.nossr50.runnables; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; -import org.bukkit.block.PistonMoveReaction; import org.bukkit.scheduler.BukkitRunnable; import com.gmail.nossr50.mcMMO; @@ -21,10 +20,16 @@ public class StickyPistonTrackerTask extends BukkitRunnable { @Override public void run() { - if (!BlockUtils.shouldBeWatched(movedBlock.getState()) || movedBlock.getPistonMoveReaction() != PistonMoveReaction.MOVE || !mcMMO.getPlaceStore().isTrue(movedBlock)) { + if (!mcMMO.getPlaceStore().isTrue(movedBlock)) { return; } + if (!BlockUtils.isPistonPiece(movedBlock.getState())) { + // The block didn't move + return; + } + + // The sticky piston actually pulled the block so move the PlaceStore data mcMMO.getPlaceStore().setFalse(movedBlock); mcMMO.getPlaceStore().setTrue(block.getRelative(direction)); } diff --git a/src/main/java/com/gmail/nossr50/util/BlockUtils.java b/src/main/java/com/gmail/nossr50/util/BlockUtils.java index 30dbac2a1..52fe156da 100644 --- a/src/main/java/com/gmail/nossr50/util/BlockUtils.java +++ b/src/main/java/com/gmail/nossr50/util/BlockUtils.java @@ -308,6 +308,12 @@ public final class BlockUtils { return type == Repair.anvilMaterial || type == Salvage.anvilMaterial; } + public static boolean isPistonPiece(BlockState blockState) { + Material type = blockState.getType(); + + return type == Material.PISTON_MOVING_PIECE || type == Material.AIR; + } + /** * Get a HashSet containing every transparent block *