mirror of
				https://github.com/mcMMO-Dev/mcMMO.git
				synced 2025-11-03 10:33:43 +01:00 
			
		
		
		
	Fix bugs with pistons
This commit improves piston tracking and fixes a couple of bugs with block tracking. Fixes #2043
This commit is contained in:
		@@ -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
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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) {
 | 
					        // Needed because blocks sometimes don't move when two pistons push towards each other
 | 
				
			||||||
            Block nextBlock = b.getRelative(direction);
 | 
					        new PistonTrackerTask(blocks, direction, futureEmptyBlock).runTaskLater(plugin, 2);
 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (nextBlock.hasMetadata(mcMMO.blockMetadataKey)) {
 | 
					 | 
				
			||||||
                mcMMO.getPlaceStore().setTrue(nextBlock);
 | 
					 | 
				
			||||||
                nextBlock.removeMetadata(mcMMO.blockMetadataKey, plugin);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -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));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user