Browse Source

Fix bugs with pistons

This commit improves piston tracking and fixes a couple of bugs with
block tracking.

Fixes #2043
TfT_02 11 years ago
parent
commit
3a8f45a04d

+ 1 - 0
Changelog.txt

@@ -15,6 +15,7 @@ Version 1.5.01-dev
  + Added support for `MATERIAL|data` format in treasures.yml
  + Added support for `MATERIAL|data` format in treasures.yml
  + Added API to experience events to get XP gain reason
  + Added API to experience events to get XP gain reason
  + Added API to check if an entity is bleeding
  + 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 where the Updater was running on the main thread.
  = Fixed bug when players would use /ptp without being in a party
  = Fixed bug when players would use /ptp without being in a party
  = Fixed bug where player didn't have a mcMMOPlayer object in AsyncPlayerChatEvent
  = Fixed bug where player didn't have a mcMMOPlayer object in AsyncPlayerChatEvent

+ 9 - 12
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.datatypes.skills.ToolType;
 import com.gmail.nossr50.events.fake.FakeBlockBreakEvent;
 import com.gmail.nossr50.events.fake.FakeBlockBreakEvent;
 import com.gmail.nossr50.events.fake.FakeBlockDamageEvent;
 import com.gmail.nossr50.events.fake.FakeBlockDamageEvent;
+import com.gmail.nossr50.runnables.PistonTrackerTask;
 import com.gmail.nossr50.runnables.StickyPistonTrackerTask;
 import com.gmail.nossr50.runnables.StickyPistonTrackerTask;
 import com.gmail.nossr50.skills.alchemy.Alchemy;
 import com.gmail.nossr50.skills.alchemy.Alchemy;
 import com.gmail.nossr50.skills.excavation.ExcavationManager;
 import com.gmail.nossr50.skills.excavation.ExcavationManager;
@@ -67,27 +68,23 @@ public class BlockListener implements Listener {
             return;
             return;
         }
         }
 
 
-        List<Block> blocks = event.getBlocks();
         BlockFace direction = event.getDirection();
         BlockFace direction = event.getDirection();
         Block futureEmptyBlock = event.getBlock().getRelative(direction); // Block that would be air after piston is finished
         Block futureEmptyBlock = event.getBlock().getRelative(direction); // Block that would be air after piston is finished
 
 
+        if (futureEmptyBlock.getType() == Material.AIR) {
+            return;
+        }
+
+        List<Block> blocks = event.getBlocks();
+
         for (Block b : blocks) {
         for (Block b : blocks) {
             if (BlockUtils.shouldBeWatched(b.getState()) && mcMMO.getPlaceStore().isTrue(b)) {
             if (BlockUtils.shouldBeWatched(b.getState()) && mcMMO.getPlaceStore().isTrue(b)) {
                 b.getRelative(direction).setMetadata(mcMMO.blockMetadataKey, mcMMO.metadataValue);
                 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);
     }
     }
 
 
     /**
     /**

+ 47 - 0
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<Block> blocks;
+    private BlockFace direction;
+    private Block futureEmptyBlock;
+
+    public PistonTrackerTask(List<Block> 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);
+            }
+        }
+    }
+}

+ 7 - 2
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.Block;
 import org.bukkit.block.BlockFace;
 import org.bukkit.block.BlockFace;
-import org.bukkit.block.PistonMoveReaction;
 import org.bukkit.scheduler.BukkitRunnable;
 import org.bukkit.scheduler.BukkitRunnable;
 
 
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.mcMMO;
@@ -21,10 +20,16 @@ public class StickyPistonTrackerTask extends BukkitRunnable {
 
 
     @Override
     @Override
     public void run() {
     public void run() {
-        if (!BlockUtils.shouldBeWatched(movedBlock.getState()) || movedBlock.getPistonMoveReaction() != PistonMoveReaction.MOVE || !mcMMO.getPlaceStore().isTrue(movedBlock)) {
+        if (!mcMMO.getPlaceStore().isTrue(movedBlock)) {
             return;
             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().setFalse(movedBlock);
         mcMMO.getPlaceStore().setTrue(block.getRelative(direction));
         mcMMO.getPlaceStore().setTrue(block.getRelative(direction));
     }
     }

+ 6 - 0
src/main/java/com/gmail/nossr50/util/BlockUtils.java

@@ -308,6 +308,12 @@ public final class BlockUtils {
         return type == Repair.anvilMaterial || type == Salvage.anvilMaterial;
         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
      * Get a HashSet containing every transparent block
      *
      *