[Util] Detecting any block being powered by redstone.

Discussion in 'Resources' started by Kazzababe, Aug 18, 2013.

Thread Status:
Not open for further replies.
  1. Offline

    Kazzababe

    I have a listener class here:
    Code:
    import java.util.HashSet;
    import java.util.Set;
     
    import org.apache.commons.lang.ArrayUtils;
    import org.bukkit.Location;
    import org.bukkit.Material;
    import org.bukkit.block.Block;
    import org.bukkit.block.BlockFace;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.EventPriority;
    import org.bukkit.event.Listener;
    import org.bukkit.event.block.BlockPhysicsEvent;
    import org.bukkit.event.block.BlockRedstoneEvent;
    import org.bukkit.plugin.Plugin;
     
    public class RedstoneListener implements Listener {
        private Plugin plugin;
        private Set<Block> redstoneBlocks = new HashSet<Block>();
     
        public RedstoneListener(Plugin plugin) {
            this.plugin = plugin;
        }
     
        @EventHandler(priority = EventPriority.MONITOR)
        public void onBlockRedstone(BlockRedstoneEvent event) {
            Block block = event.getBlock();
            Location location = block.getLocation();
     
            if(event.getOldCurrent() != 0) return;
            if(event.getNewCurrent() <= 0) return;
     
            Block[] adjacentBlocks = this.getAdjacentBlocks(location, true);
            for(Block adjacentBlock : adjacentBlocks) {
                if(adjacentBlock.isBlockPowered()) continue;
                if(!this.isValidMaterial(adjacentBlock.getType())) continue;
         
                this.redstoneBlocks.add(adjacentBlock);
            }
        }
     
        @EventHandler(priority = EventPriority.MONITOR)
        public void onBlockPhysics(BlockPhysicsEvent event) {
            Block block = event.getBlock();
     
            if(this.redstoneBlocks.contains(block)) {
                this.redstoneBlocks.remove(block);
         
                if(block.isBlockPowered()) {
                    BlockPowerUpEvent blockEvent = new BlockPowerUpEvent(block, true);
                    this.plugin.getServer().getPluginManager().callEvent(blockEvent);
             
                    Block[] blocks = this.getAdjacentBlocks(block.getLocation(), false);
                    for(Block adjacentBlock : blocks) {
                        if(!this.isValidMaterial(adjacentBlock.getType())) continue;
                        if(adjacentBlock.isBlockPowered()) continue;
                        if(this.redstoneBlocks.contains(adjacentBlock)) continue;
                 
                        if(adjacentBlock.isBlockIndirectlyPowered()) {
                            blockEvent = new BlockPowerUpEvent(adjacentBlock, false);
                            this.plugin.getServer().getPluginManager().callEvent(blockEvent);
                        }
                    }
                }
            }
        }
     
        private Block[] getAdjacentBlocks(Location location, boolean include) {
            Block block = location.getBlock();
            Block[] blocks = new Block[]{block.getRelative(BlockFace.NORTH),
                    block.getRelative(BlockFace.EAST),
                    block.getRelative(BlockFace.SOUTH),
                    block.getRelative(BlockFace.WEST),
                    block.getRelative(BlockFace.UP),
                    block.getRelative(BlockFace.DOWN), block};
            if(include) ArrayUtils.add(blocks, block);
            return blocks;
        }
     
        private boolean isValidMaterial(Material material) {
            if(material == Material.AIR) return false;
            return true;
        }
    }
    And then the custom listener class:
    Code:
    import org.bukkit.block.Block;
    import org.bukkit.event.block.BlockExpEvent;
     
    public class BlockPowerUpEvent extends BlockExpEvent {
        private boolean strongPower;
     
        public BlockPowerUpEvent(Block block, boolean strongPower) {
            super(block, 0);
            this.strongPower = strongPower;
        }
     
        public boolean isStrongPower() {
            return this.strongPower;
        }
    }
    All you need to do is listen for the "BlockPowerUpEvent". You do that like you would any other event.

    Now this code isn't perfect and there will be a lot of duplicates, where one block is powered strongly and not strongly, and some blocks won't be caught at all, but without a proper implementation, this is the best I could come up with.

    Hope you guys find it useful.
     
  2. Offline

    TomFromCollege

    Why are you extending BlockExpEvent?
    And Why would you add Exp as an argument to the BlockPowerUpEvent?
     
  3. Offline

    Kazzababe


    Directly extending BlockEvent requires to you mess around with event handlers which I have no experience in whatsoever, so I just extended a block event that already did that. As for the second part, I'm actually not sure. I should actually go ahead and change that.
     
  4. Offline

    chasechocolate

    Make it extend BlockEvent and use super(block).
     
    xWatermelon likes this.
  5. Offline

    Kazzababe


    Thats what I did at first, buy it just threw an error when the plugin was enabling.
     
  6. Offline

    chasechocolate

    May I see the error and your class?
     
  7. Offline

    Kazzababe

    chasechocolate

    I don't have it logged, but it was something like this:
    Code:
    17:41:09 [SEVERE] Error occurred while enabling TekkitInspired (
    Is it up to date?): Unable to find handler list for event org.bukkit.event.block
    .BlockEvent
    org.bukkit.plugin.IllegalPluginAccessException: Unable to find handler list for
    event org.bukkit.event.block.BlockEvent
    Class was something like this:
    Code:
    import org.bukkit.block.Block;
    import org.bukkit.event.HandlerList;
     
    public class BlockPowerUpEvent extends BlockEvent {
        private static final HandlerList handlers = new HandlerList();
     
        public BlockPowerUpEvent(Block block) {
            super(block);
        }
     
        public HandlerList getHandlers() {
            return handlers;
        }
    }
     
  8. Offline

    Minecrell

    Kazzababe
    You have to add a public static getter for the handler list in your custom event, not just a public ones. :p
    http://wiki.bukkit.org/Event_API_Reference#Creating_Custom_Events

    So you would need that for your code:

    Code:java
    1. import org.bukkit.block.Block;
    2. import org.bukkit.event.HandlerList;
    3. import org.bukkit.event.block.BlockEvent;
    4.  
    5. public class BlockPowerUpEvent extends BlockEvent {
    6. private static final HandlerList handlers = new HandlerList();
    7.  
    8. private boolean strongPower;
    9.  
    10. public BlockPowerUpEvent(Block block, boolean strongPower) {
    11. super(block);
    12. this.strongPower = strongPower;
    13. }
    14.  
    15. public boolean isStrongPower() {
    16. return this.strongPower;
    17. }
    18.  
    19. public HandlerList getHandlers() {
    20. return handlers;
    21. }
    22.  
    23. public static HandlerList getHandlerList() {
    24. return handlers;
    25. }
    26. }
     
Thread Status:
Not open for further replies.

Share This Page