Execute Command on Redstone Pulse

Discussion in 'Plugin Development' started by coolo1, Nov 5, 2012.

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

    coolo1

    What I am trying to do is create a plugin that executes a command when a block gets a redstone pulse AND while a certain dropped item is touching it. What would the easiest way to do this be? Thanks, Coolo.
     
  2. Offline

    Sheepii

    The eventHandler you're looking for is BlockRedstoneEvent

    Also, it would be
    Code:
    ((Entity) event.getBlock().getLocation()).getNearbyEntities(2,2,2).contains(Material.THINGHERE);
    
    2,2,2 can be changed to as it works in xyz. If you want it on top do 0,1,0. If you just want it around it do (1,1,1) Unfortunately I don't know how to make it just the top. I guess you could get the location and add 1 y. Then get nearby entities for (0,0,0). Meh, just work around with it.
     
  3. a Location is never entity, so your code fails
     
  4. Offline

    fireblast709

    how would you locate your block?
     
  5. Offline

    Sheepii

    First off, I didn't test this code, I didn't do anything with it. I didn't even have Eclipse open or the API. So here's what you can do seeing as your usefulness of telling me I'm wrong is second to none and don't contribute anything to the conversation other than to boost your personal manly internet ego. You're going to explain to OP how to iterate through all entities on the server and see if they're near an event that is activated by BlockRedstoneEvent, I'll check back and answer OP's question tomorrow if that is, you can't answer it.

    eh screw it.
    Code:
    public void test(BlockRedstoneEvent event)
        {
            World world = event.getBlock().getWorld();
            Location loc = event.getBlock().getLocation();
            loc.add(0,1,0);
            if(!((World) world.getBlockAt(loc)).getEntities().contains(EntityType.Whatever)
            {return;}
            else{
                //Do what you want it to do
    }
    }
            
    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 29, 2016
    ZeusAllMighty11 and devilquak like this.
  6. Offline

    fireblast709

    SaintMotherfuckingX I have no clue what kind of black magic you are performing here:
    Code:java
    1. ((World) world.getBlockAt(loc))

    casting a Block to World???

    coolo1 here ya go. Might not be as specific as you want, but it gets close
    Code:text
    1. @EventHandler
    2. public void onRedstone(BlockRedstoneEvent event)
    3. {
    4. if(event.getNewCurrent() > 0) // Idk what the current must be, just assuming this would pass on
    5. {
    6. Block redstone = event.getBlock();
    7. List<Entity>es = Bukkit.getWorld("").getEntities();
    8. boolean isItemNear = false;
    9. for(Entity e : es)
    10. {
    11. if(e.getType() == EntityType.DROPPED_ITEM) //FIRST check if the entity is right
    12. {
    13. Location x = e.getLocation();
    14. double distance = x.distanceSquared(redstone.getLocation());
    15. if(distance <= 4 ) // If the distance is 2 from the redstone block, squared
    16. {
    17. if(((Item) e).getItemStack().getType() == Material.DIAMOND_BLOCK) // For diamond blocks
    18. {
    19. isItemNear = true;
    20. break; // To save us checking in the future, we already know its there right
    21. }
    22. }
    23. }
    24. }
    25. if(!isItemNear) // No item found?
    26. {
    27. // RETURN IMMEDIATELY! there is nothing useful up ahead anyway
    28. return;
    29. }
    30.  
    31. ArrayList<Block> blocks = new ArrayList<Block>();
    32. blocks.add(event.getBlock().getRelative(BlockFace.DOWN, 1));
    33. blocks.add(event.getBlock().getRelative(BlockFace.NORTH, 1));
    34. blocks.add(event.getBlock().getRelative(BlockFace.EAST, 1));
    35. blocks.add(event.getBlock().getRelative(BlockFace.WEST, 1));
    36. blocks.add(event.getBlock().getRelative(BlockFace.SOUTH, 1));
    37. for(Block b : blocks)
    38. {
    39. if(b.isBlockPowered() || b.isBlockIndirectlyPowered())
    40. {
    41. // Do whatever to check
    42. }
    43. }
    44. }
    45. }
     
  7. Offline

    coolo1

    Thanks, sorry if I am being an idiot, but where would I specify what the block has to be? I will tell you if it works!
     
  8. Offline

    fireblast709

    Do you mean the dropped item or the block that is connected to the redstone?
     
  9. Offline

    coolo1

    The block connected to the redstone, also, how would I get this to execute a default server command through the console?
     
  10. Offline

    fireblast709

    Change the last for-loop for this (has an extra if-statement)
    Code:java
    1. for(Block b : blocks)
    2. {
    3. if(b.getType == Material.[material])
    4. {
    5. if(b.isBlockPowered() || b.isBlockIndirectlyPowered())
    6. {
    7. // Do whatever to check
    8. }
    9. }
    10. }

    Also, executing a command through console...
    Code:java
    1. ConsoleCommandSender ccs = Bukkit.getServer().getConsoleSender();
    2. Bukkit.getServer().dispatchCommand(ccs, "/derp");


    getType should be getType(), my bad xD. Material.[material] should be something like Material.STONE or Material.DIAMOND_BLOCK

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 29, 2016
  11. Offline

    coolo1

    Thanks for the help, I literally tried that as you posted!
    [Edit] fireblast709 Just tested it, I set the command to toggledownfall, item to redstone and block to lapis block, it started properly, but when I threw redstone at a lapis block and powered it, nothing happened...
     
  12. Offline

    fireblast709

    Lets start with the code, so I can test :3
     
  13. Offline

    coolo1

    fireblast709 Here is my code so far.
    Show Spoiler
    Code:
    package net.coolo.plugins.WeatherMachine;
    import java.util.ArrayList;
    import java.util.List;
     
    import org.bukkit.Bukkit;
    import org.bukkit.Location;
    import org.bukkit.Material;
    import org.bukkit.plugin.PluginDescriptionFile;
    import org.bukkit.plugin.java.JavaPlugin;
    import org.bukkit.block.Block;
    import org.bukkit.block.BlockFace;
    import org.bukkit.command.ConsoleCommandSender;
    import org.bukkit.entity.Entity;
    import org.bukkit.entity.EntityType;
    import org.bukkit.entity.Item;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.block.BlockRedstoneEvent;
     
    public final class WeatherMachine extends JavaPlugin {
     
    @Override
        public void onEnable(){
    PluginDescriptionFile pdf = this.getDescription(); //Gets plugin.yml
    getLogger().info("Weather Machine version "+ pdf.getVersion()+" has been succesfully enabled");
        }
     
        @Override
        public void onDisable() {
            getLogger().info("Weather Machine has been disabled.");
        }
        @EventHandler
        public void onRedstone(BlockRedstoneEvent event)
        {
            if(event.getNewCurrent() > 0) // Idk what the current must be, just assuming this would pass on
            {
                Block redstone = event.getBlock();
                List<Entity>es = Bukkit.getWorld("").getEntities();
                boolean isItemNear = false;
                for(Entity e : es)
                {
                    if(e.getType() == EntityType.DROPPED_ITEM) //FIRST check if the entity is right
                    {
                        Location x = e.getLocation();
                        double distance = x.distanceSquared(redstone.getLocation());
                        if(distance <= 4 ) // If the distance is 2 from the redstone block, squared
                        {
                            if(((Item) e).getItemStack().getType() == Material.REDSTONE) // For diamond blocks
                            {
                                isItemNear = true;
                                break; // To save us checking in the future, we already know its there right
                            }
                        }
                    }
                }
                if(!isItemNear) // No item found?
                {
                    // RETURN IMMEDIATELY! there is nothing useful up ahead anyway
                    return;
                }
     
                ArrayList<Block> blocks = new ArrayList<Block>();
                blocks.add(event.getBlock().getRelative(BlockFace.DOWN, 1));
                blocks.add(event.getBlock().getRelative(BlockFace.NORTH, 1));
                blocks.add(event.getBlock().getRelative(BlockFace.EAST, 1));
                blocks.add(event.getBlock().getRelative(BlockFace.WEST, 1));
                blocks.add(event.getBlock().getRelative(BlockFace.SOUTH, 1));
                for(Block b :  blocks)
                {
                    if(b.getType() == Material.LAPIS_BLOCK)
                    {
                        if(b.isBlockPowered() || b.isBlockIndirectlyPowered())
                        {
                      ConsoleCommandSender ccs = Bukkit.getServer().getConsoleSender();
                            Bukkit.getServer().dispatchCommand(ccs, "/toggledownfall");
                            getLogger().fine("WeatherMachine Used!"); //For debug
                        }
                    }
                }
        }
    }
    }
    
     
  14. Offline

    fireblast709

    coolo1 at the moment I got as far as to tell you that somehow it is not detecting redstone changes: the power stays 0
    [EDIT] I switched to event.getOldCurrent() and it is picking up the command, not to get that working (Command not found x3)
    [EDIT 2] Ok now I got my logic straight (and bukkit got it wrong? Gonna test that later)
    Code:java
    1. @EventHandler
    2. public void onRedstone(BlockRedstoneEvent event)
    3. {
    4. if(!(event.getOldCurrent() > 0)) // Idk what the current must be, just assuming this would pass on
    5. {
    6. Block redstone = event.getBlock();
    7. List<Entity>es = redstone.getWorld().getEntities();
    8. boolean isItemNear = false;
    9. for(Entity e : es)
    10. {
    11. if(e.getType() == EntityType.DROPPED_ITEM) //FIRST check if the entity is right
    12. {
    13. if(((Item) e).getItemStack().getType() == Material.REDSTONE) // For diamond blocks
    14. {
    15. Location x = e.getLocation();
    16. double distance = x.distanceSquared(redstone.getLocation());
    17. if(distance <= 4 ) // If the distance is 2 from the redstone block, squared
    18. {
    19. isItemNear = true;
    20. break; // To save us checking in the future, we already know its there right
    21. }
    22. }
    23. }
    24. }
    25. if(!isItemNear) // No item found?
    26. {
    27. // RETURN IMMEDIATELY! there is nothing useful up ahead anyway
    28. return;
    29. }
    30.  
    31. ArrayList<Block> blocks = new ArrayList<Block>();
    32. blocks.add(event.getBlock().getRelative(BlockFace.DOWN, 1));
    33. blocks.add(event.getBlock().getRelative(BlockFace.NORTH, 1));
    34. blocks.add(event.getBlock().getRelative(BlockFace.EAST, 1));
    35. blocks.add(event.getBlock().getRelative(BlockFace.WEST, 1));
    36. blocks.add(event.getBlock().getRelative(BlockFace.SOUTH, 1));
    37. for(Block b : blocks)
    38. {
    39. if(b.getType() == Material.LAPIS_BLOCK)
    40. {
    41. if(!b.isBlockPowered() && !b.isBlockIndirectlyPowered())
    42. {
    43. ConsoleCommandSender ccs = Bukkit.getServer().getConsoleSender();
    44. Bukkit.getServer().dispatchCommand(ccs, "toggledownfall");
    45. }
    46. }
    47. }
    48. }
    49. }
     
  15. Offline

    coolo1

    fireblast709 I'm going to try something, I'll tell you if it works
    [Edit] Whats the exact code that you changed? I want to try without the / because thats unneeded in the console.
    [Edit] Tried it, still does not work...
    [Edit] Found what the problem is after some Googling! the onRedstone event is for redstone wire only, to get the same effect for a block you must use
    Code:
                        public void onBlockPhysics(BlockPhysicsEvent event)
                        {
                     if(event.isCancelled())
                      return;
                     Block block = event.getBlock();
                     boolean oldState = someMagicHere(block);
                              if(block.isBlockPowered())
                     {
                      if(!oldState)
                                {
                                  //Block changed from powered to unpowered
                                  oldState = true;
                                }
                              }
                              else
                              {
                                if(oldState)
                                {
                                  //Block changed from unpowered to powered
                                  oldState = false;
                                }
                              }
                            }
                        }
    The problem is, I am not sure how to implement that...
     
  16. Offline

    md_5

    fireblast709
    Minor gripe, but using a prepopulated array would be better than an array list, especially since the redstone event is high frequency. Rest of the code looks swell :)
     
  17. Offline

    coolo1

    What's causing it to not work then?
     
  18. Offline

    Sheepii

    Do you register your events?
    Put footholds into the code to see where your at, so like System.println("You are at part 1 of RedstoneEvent");
    With this you can see how far you've gotten into the code before it stopped working. If it's not doing anything, there is a possibility a couple things are happening.
    1. You could have an Invalid EventHandler in your plugin, that is causing your plugin to not read events.
    2. You could be not registering your events onEnabled().
    3. The code doesn't work.
    Check all three of these in order and reply with the results. We'll figure it out.
     
  19. Offline

    fireblast709

    coolo1 if you register your events, it should be working. Tested and confirmed by me. Apparently block power and redstone updates aren't that 'sync'. But the code as it is in the box should be working, as mentioned at first in my post
    md_5 ty :3. How would you suggest getting the prepopulated array btw? BlockIterators?
     
  20. Offline

    md_5

    Nevermind, I misread the code and though you were looping twice.
     
  21. Offline

    fireblast709

  22. Offline

    coolo1

    So... What can we do about it not detecting redstone?
     
Thread Status:
Not open for further replies.

Share This Page