Detecting indirectly Powered Blocks

Discussion in 'Spigot Plugin Development' started by WAS, Apr 22, 2017.

  1. WAS

    WAS

    I'm trying detect when redstone is indirectly powering a block.

    For example with my current setup I can prime my TNT with a directly powered TNT block.. but what if that block is not directly powered like so:

    [​IMG]

    I've played around with adding faces I can think of but I can never get it to register a indirectly powered TNT block so it will spawn a normal TNT. Am I just doing it wrong? The initial faces check works alright for directly powered TNT as far as I can tell. The secondary loop is not functioning as intended.

    Code (Java):

      @EventHandler(priority=EventPriority.HIGHEST)
       public void onBlockRedstoneChange(BlockRedstoneEvent e) {

         // Currents
         int newCurrent = e.getNewCurrent();
         int oldCurrent = e.getOldCurrent();
       
         // Direct blocks...
         List<BlockFace> faces = new ArrayList<BlockFace>(){
           private static final long serialVersionUID = -6535364022695998798L; {
           add(BlockFace.UP);
           add(BlockFace.DOWN);
           add(BlockFace.WEST);
           add(BlockFace.EAST);
           add(BlockFace.NORTH);
           add(BlockFace.SOUTH);
         }};
       
         // Indirect extensions...
         List<BlockFace> ifaces = new ArrayList<BlockFace>(){
           private static final long serialVersionUID = -6535364022695998798L; {
           add(BlockFace.UP);
           add(BlockFace.DOWN);
           add(BlockFace.NORTH);
           add(BlockFace.SOUTH);
           add(BlockFace.EAST_NORTH_EAST);
           add(BlockFace.EAST_SOUTH_EAST);
           add(BlockFace.WEST_NORTH_WEST);
           add(BlockFace.WEST_SOUTH_WEST);
           add(BlockFace.NORTH_NORTH_WEST);
           add(BlockFace.NORTH_NORTH_EAST);
           add(BlockFace.SOUTH_SOUTH_WEST);
           add(BlockFace.SOUTH_SOUTH_EAST);
         }};

         // Loop direct faces and their direct faces...
         for ( BlockFace face : faces ) {
         
           Block block = e.getBlock().getRelative(face, 1);
         
           // Loop indirect extensions first
           for ( BlockFace iface : ifaces ) {
           
             Block iblock = e.getBlock().getRelative(iface, 1);
           
             // is powered block TNT
             if ( iblock.getType().equals(Material.TNT)
                 && oldCurrent == 0 && newCurrent >= 1 ) {
           
               if ( TNTManager.containsLocation(iblock.getLocation())
                   && TNTEffects.hasEffect(TNTManager.getType(iblock.getLocation())) ) {
               
                 String type = TNTManager.getType(iblock.getLocation());
                 Map<String, Object> effect = TNTEffects.getEffect(type);
               
                 if ( OnCommand.toggleDebug != null && OnCommand.toggleDebug ) {
                   Bukkit.getLogger().info("BlockRedstoneEvent: "+face+" indirectly powering "+iface+" | TNT triggered at location: "+iblock.getLocation()+" Effect Type: "+type);
                 }
               
                 if ( effect != null ) {
                 
                   iblock.setType(Material.AIR);
                   primeBlock(effect, iblock.getLocation());
               
                 }
               }
             
             }
           
           }
         
           // Is powered block TNT
           if ( block.getType().equals(Material.TNT)
               && oldCurrent == 0 && newCurrent >= 1 ) {

             if ( TNTManager.containsLocation(block.getLocation())
                 && TNTEffects.hasEffect(TNTManager.getType(block.getLocation())) ) {
             
               String type = TNTManager.getType(block.getLocation());
               Map<String, Object> effect = TNTEffects.getEffect(type);
             
               if ( OnCommand.toggleDebug != null && OnCommand.toggleDebug ) {
                 Bukkit.getLogger().info("BlockRedstoneEvent: "+face+" powering | TNT triggered at location: "+block.getLocation()+" Effect Type: "+type);
               }
             
               if ( effect != null ) {
               
                 block.setType(Material.AIR);
                 primeBlock(effect, block.getLocation());
             
               }
             }
           }
         }
     
    #1 WAS, Apr 22, 2017
    Last edited: Apr 22, 2017
  2. Have you tried a simple loop through surrounding blocks without blockfaces? I honestly do not know what BlockFace.EAST_NORTH_EAST even means.

    I would try this:
    Code (Java):
    @EventHandler(priority=EventPriority.HIGHEST)
    public void onBlockRedstoneChange(BlockRedstoneEvent e) {

        // Currents
        int newCurrent = e.getNewCurrent();
        int oldCurrent = e.getOldCurrent();

        if( oldCurrent != 0 || newCurrent < 1) return;

        Int[] add = new int[3];
        add[0] = -1;
        add[1] = 0;
        add[2] = 1;

        for(int addX : add){
            for(int addY : add){
                for(int addZ : add){  
                    // check your TNT stuff
                    // get the block by adding the addX, addY, addZ to the event blocks location
                }
            }
        }
    }
       
    It may look like a trivial solution but maybe this would work. I hope it does... was a pain to type all that on my phone :rolleyes:
     
  3. WAS

    WAS

    Yeah I am just as confused by these faces as well lol. Maybe a corner and subsequently (getDirection) corner facing direction?

    The only issue is I can do this (your example) by just checking all faces and related blocks, but it wouldn't be following redstone rules. I'd have to do more checks for positions instead of simply just checking for the correct faces redstone powers as I imagine how internal mechanics work as to never have any errors in execution.

    Update: Believe I figured it out. Had the wrong block, as I was using e#getBlock instead of the set block to get the relative block, which thus was giving me the same block.

    Only issue is now is kinda same as before. Like with redstone wire it will activate a block above the wire (when it shouldn't)
     
    #3 WAS, Apr 22, 2017
    Last edited: Apr 22, 2017
  4. How about using:
    e.getBlock().isBlockIndirectlyPowered(whateveFace)

    Should give you true if it's indirectly powered by that particular face and you should only need to check NSWE and up/down.

    Or if you just wanted to know if the block or adjacent block was indirectly powered you should be able to use: block.isBlockPowered() or isBlockIndirectlyPowered()


    Sent from my iPhone using Tapatalk
     
  5. WAS

    WAS

    Nope, because both isPowered and isDirectlyPowered have no value as the event is still processing. It would have the last events power. You need to use the current and old current to find out if it's actually being powered in that instance. Then you have determine if that power will power something indirectly when the event is finished.
     
  6. Hmmm interesting, so (looking at your photo) are you trying to make it so the TNT will ignite when the red stone is lit in that configuration?

    What if you listened to a red stone event, and if a TNT block was found adjacent and below the red stone you artificially set the adjacent blocks power and triggered an update. Seems like that could power the tnt


    Sent from my iPhone using Tapatalk
     
  7. WAS

    WAS

    I'm trying to reimplment all vanilla redstone mechanics as it's literally the only way to spawn the custom TNT correctly. Otherwise, I have to spawn normal TNT and then alter the entity at the Prime event, which drastically extends fuse time and also makes it look like crap as there is a new entity spawn animation which offsets the location as the entities exact location is not exact but relative to a location block. -_-

    So basically. I have to rebuild all redstone mechanics (and create a redstone tick delay) or have crappy spawning TNT from redstone, which also not activate special TNT if it falls -_-

    I hate that there is no actual prime TNT event but version which is not a prime event but a ignition event. and I sure hope it's not the excuse I keep hearing that it would be laggy cause there could be lots of TNT... well that is null-in-void because of the Prime event which both covers TNT AND exploding entities.