Przeglądaj źródła

Fix the issues with sticky pistons and slime blocks

This is a fix for issues #2419 and #2494
TfT_02 10 lat temu
rodzic
commit
cfa0daefc5

+ 1 - 1
Changelog.txt

@@ -8,7 +8,7 @@ Key:
   - Removal
 
 Version 1.5.03-dev
-
+ = Fixed bug where blocks would not get tracked correctly when using sticky pistons and slime blocks in certain situations
 
 Version 1.5.02
  + Added option to config.yml for Chimaera Wings to stop using bed spawn points

+ 22 - 19
src/main/java/com/gmail/nossr50/listeners/BlockListener.java

@@ -2,7 +2,6 @@ package com.gmail.nossr50.listeners;
 
 import java.util.List;
 
-import org.bukkit.Bukkit;
 import org.bukkit.GameMode;
 import org.bukkit.Location;
 import org.bukkit.Material;
@@ -65,10 +64,6 @@ public class BlockListener implements Listener {
      */
     @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
     public void onBlockPistonExtend(BlockPistonExtendEvent event) {
-        if (!EventUtils.shouldProcessEvent(event.getBlock(), true)) {
-            return;
-        }
-
         BlockFace direction = event.getDirection();
         Block futureEmptyBlock = event.getBlock().getRelative(direction); // Block that would be air after piston is finished
 
@@ -95,27 +90,35 @@ public class BlockListener implements Listener {
      */
     @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
     public void onBlockPistonRetract(BlockPistonRetractEvent event) {
-        if (!EventUtils.shouldProcessEvent(event.getBlock(), false)) {
-            return;
-        }
+        // event.isSticky() always returns false
+        // if (!event.isSticky()){
+        //     return;
+        // }
 
-        // Don't even work, return ALLWAYS false xD
-        /*if (!event.isSticky()){
-        	return;
-        }*/      
-        
-        // Sticky piston return PISTON_MOVING_PIECE and normal piston PISTON_BASE, so mess stuff
+        // Sticky piston return PISTON_MOVING_PIECE and normal piston PISTON_BASE
         if (event.getBlock().getType() != Material.PISTON_MOVING_PIECE) {
             return;
         }
 
-        // event.getRetractLocation() return wrong side and too far away
-        // Get opposite direction so we get correct block, so mess stuff
-        Block movedBlock = event.getBlock().getRelative(event.getDirection().getOppositeFace());
+        // Get opposite direction so we get correct block
+        BlockFace direction = event.getDirection().getOppositeFace();
+        Block movedBlock = event.getBlock().getRelative(direction);
+
+        // If we're pulling a slime block, it might have something attached to it!
+        if (movedBlock.getRelative(direction).getState().getType() == Material.SLIME_BLOCK) {
+            // Check if any other slime blocks are attached, because they can also pull blocks
+            List<Block> adjacentBlocks = BlockUtils.getAdjacentBlocks(movedBlock.getRelative(direction), Material.SLIME_BLOCK);
+            for (Block b : adjacentBlocks) {
+                new StickyPistonTrackerTask(direction, event.getBlock(), b).runTaskLater(plugin, 2);
+            }
+
+            // Treat the slime block as if it is the sticky piston itself, because pulling
+            // a slime block with a sticky piston is effectively the same as moving a sticky piston.
+            movedBlock = movedBlock.getRelative(direction);
+        }
 
         // Needed only because under some circumstances Minecraft doesn't move the block
-        // Opposite side here too
-        new StickyPistonTrackerTask(event.getDirection().getOppositeFace(), event.getBlock(), movedBlock).runTaskLater(plugin, 2);
+        new StickyPistonTrackerTask(direction, event.getBlock(), movedBlock).runTaskLater(plugin, 2);
     }
 
     /**

+ 0 - 1
src/main/java/com/gmail/nossr50/mcMMO.java

@@ -119,7 +119,6 @@ public class mcMMO extends JavaPlugin {
     public final static String disarmedItemKey     = "mcMMO: Disarmed Item";
     public final static String playerDataKey       = "mcMMO: Player Data";
     public final static String greenThumbDataKey   = "mcMMO: Green Thumb";
-    public final static String pistonDataKey       = "mcMMO: Piston State";
     public final static String databaseCommandKey  = "mcMMO: Processing Database Command";
     public final static String bredMetadataKey     = "mcMMO: Bred Animal";
 

+ 0 - 1
src/main/java/com/gmail/nossr50/runnables/StickyPistonTrackerTask.java

@@ -1,6 +1,5 @@
 package com.gmail.nossr50.runnables;
 
-import org.bukkit.Bukkit;
 import org.bukkit.block.Block;
 import org.bukkit.block.BlockFace;
 import org.bukkit.scheduler.BukkitRunnable;

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

@@ -1,10 +1,14 @@
 package com.gmail.nossr50.util;
 
+import java.util.ArrayList;
 import java.util.HashSet;
+import java.util.List;
 
 import org.bukkit.CropState;
 import org.bukkit.Material;
 import org.bukkit.NetherWartsState;
+import org.bukkit.block.Block;
+import org.bukkit.block.BlockFace;
 import org.bukkit.block.BlockState;
 import org.bukkit.material.CocoaPlant;
 import org.bukkit.material.CocoaPlant.CocoaPlantSize;
@@ -316,6 +320,32 @@ public final class BlockUtils {
         return type == Material.PISTON_MOVING_PIECE || type == Material.AIR;
     }
 
+    /**
+     * Get the adjacent blocks of the base block if it is equal to a certain material
+     *
+     * @param base The base block to check
+     * @param material The Material to check for
+     * @return a list with the adjacent blocks
+     */
+    public static List<Block> getAdjacentBlocks(Block base, Material material) {
+        List<Block> blocks = new ArrayList<Block>();
+
+        if (base.getRelative(BlockFace.NORTH).getType() == material) {
+            blocks.add(base.getRelative(BlockFace.NORTH));
+        }
+        if (base.getRelative(BlockFace.EAST).getType() == material) {
+            blocks.add(base.getRelative(BlockFace.EAST));
+        }
+        if (base.getRelative(BlockFace.SOUTH).getType() == material) {
+            blocks.add(base.getRelative(BlockFace.SOUTH));
+        }
+        if (base.getRelative(BlockFace.WEST).getType() == material) {
+            blocks.add(base.getRelative(BlockFace.WEST));
+        }
+
+        return blocks;
+    }
+
     /**
      * Get a HashSet containing every transparent block
      *

+ 0 - 23
src/main/java/com/gmail/nossr50/util/EventUtils.java

@@ -9,7 +9,6 @@ import org.bukkit.entity.Fish;
 import org.bukkit.entity.Player;
 import org.bukkit.event.player.PlayerFishEvent;
 import org.bukkit.inventory.ItemStack;
-import org.bukkit.metadata.FixedMetadataValue;
 import org.bukkit.plugin.PluginManager;
 
 import com.gmail.nossr50.mcMMO;
@@ -280,26 +279,4 @@ public class EventUtils {
 
         return event;
     }
-
-    /**
-     * There is a bug in CraftBukkit that causes piston events to
-     * fire multiple times. Check this method to see if the piston event
-     * should be processed.
-     *
-     * @param block      Block object of the piston block
-     * @param isExtendEvent should be true when called from BlockPistonExtendEvent
-     *
-     * @return true if the PistonEvent should be processed, false otherwise
-     */
-    public static boolean shouldProcessEvent(Block block, boolean isExtendEvent) {
-        String pistonAction = isExtendEvent ? "EXTEND" : "RETRACT";
-        String lastAction = block.hasMetadata(mcMMO.pistonDataKey) ? block.getMetadata(mcMMO.pistonDataKey).get(0).asString() : "";
-
-        if (!lastAction.equals(pistonAction)) {
-            block.setMetadata(mcMMO.pistonDataKey, new FixedMetadataValue(mcMMO.p, pistonAction));
-            return true;
-        }
-
-        return false;
-    }
 }