How to set a block powered?

Discussion in 'Plugin Development' started by ZachBora, Jan 4, 2012.

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

    ZachBora

    Hello,

    I'm working on a plugin called CloneMe which creates clones that do exactly the same action as you do. I've hit a problem regarding powered blocks.

    The setup is :
    Wire - Block - Lever on the block

    When I build this, my clone builds the same thing. If I flip the switch, his switch also gets flipped. But the block power doesn't change.

    This setup works and does change the power for my clone too :
    wire - lever on the ground

    Any idea how to update the powered state of the block?

    Edit: I tried to assign like this but isBlockPowered isn't a variable.
    myblock.getLocation().add(0, 0, 1).getBlock().isBlockPowered() = true;

    Note that I cannot simply call a new playerinteract event as my plugin might catch it (since this is a change done onPlayerInteract). Unless you know how to prevent events from looping.

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

    theguynextdoor

    It wouldnt be just
    myblock.getLocation().add(0, 0, 1).getBlock().isBlockPowered() = true;

    it would be
    myblock.getLocation().add(0, 0, 1).getBlock().isBlockPowered() == true;

    note the ==
    Plus, if its a boolean like
    if( myblock.getLocation().add(0, 0, 1).getBlock().isBlockPowered() ){
    that if statement will only work if the boolean is true.
     
  3. Offline

    ZachBora

    I know, but it just tells me that the block is powered. I want it to update with the lever.

    Right now I'm thinking of creating a new event that inherits PlayerInteractEvent and add a boolean somewhere so it doesn't loop.
     
  4. Offline

    bergerkiller

    @ZachBora try forcing a physics update on the lever.
    Could work.
     
  5. Offline

    ZachBora

    Tried to update state on the lever and on the block the lever is attached to and didn't change anything.
    The process works if the redstone isn't powered. But once it's powered, the lever doesn't do anything anymore.

    I'm trying right now with a modified event.

    I've made a new event with the same information as PlayerInteractEvent and check if it's an instance of it.
    But it doesn't do anything when I call it. So I'm guessing calling the event doesn't actually does the event... I'd need to do an action and call the event?

    ClonePlayerInteractEvent:
    Code:
    public class ClonePlayerInteractEvent extends PlayerInteractEvent {
        private static final long serialVersionUID = 3868388333255631567L;
    
        public ClonePlayerInteractEvent(Player who, Action action, ItemStack item,
                Block clickedBlock, BlockFace clickedFace) {
            super(who, action, item, clickedBlock, clickedFace);
        }
    }
    onPlayerInteract:
    Code:
    public void onPlayerInteract(PlayerInteractEvent event) {
            if (event.isCancelled()) return;
    
            if(!(event instanceof ClonePlayerInteractEvent))
            {
                Player p = event.getPlayer();
    
                Set<Clone> clones = plugin.getClones(p.getName());
                if(clones != null && clones.size() != 0)
                {
                    for(Clone clone : clones)
                    {
                        Block newblock = clone.setBlockAtNewLocation(event.getClickedBlock(), false, true, true);
    
                        ClonePlayerInteractEvent newevent = new ClonePlayerInteractEvent(p, event.getAction(), p.getItemInHand(), newblock, event.getBlockFace());
    
                        plugin.getServer().getPluginManager().callEvent(newevent);
                    }
                }
            }
        }
    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 22, 2016
  6. Offline

    bergerkiller

    @ZachBora yup, when you call an event all that it does is send the event to all other plugins, it doesn't actually execute anything. It's only useful if you want to do something but do want to notify the plugins about this.

    Actually, I have the same issue in TrainCarts and Redstone Mania: redstone wire that is attached to the block the lever sits on does not respond to the lever changing state. So this is of my interest too...

    I'll look at the native coding and find out what needs to be called...
     
  7. Offline

    ZachBora

    I'm looking at the interact event of level here : https://github.com/Bukkit/CraftBukkit/blob/master/src/main/java/net/minecraft/server/BlockLever.java

    I suspect these lines does the changes :
    world.setData(i, j, k, i1 + j1);
    world.b(i, j, k, i, j, k);

    Then it applies physics to blocks around it.

    I just tried doing the same thing in my event as if it was done by a //set in worldedit and it produces the same problematic behavior.

    I have this in a line:
    - lever on top of cobble
    - redstone wire
    - cobble with redstone wire
    - redstone torch on the side of cobble
    - redstone wire
    - door

    I do this on the lever:
    //set 69:5
    //set 69:13
    (both commands multiple time)

    This is all depending on the orientation, the redstone will either do nothing, or the door will clap twice (open and close at the same time).

    So maybe there's a bug in bukkit or minecraft somewhere.

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

    Technius

    I *think* you have to set the data of the lever, 0 is off, 1 is on?
     
  9. Offline

    ZachBora

    I'm doing that right now in the code. Byte 0x8 is set for on and off.

    I've got
    newblock.setData(data, true);

    Where data includes orientation (1-4 if on a wall) (5-6 on floor) and bit 0x8 for on and off.

    Since I can't find any help, I am supposing it's because people don't understand my problem. So I created a video of the problem here :


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

    Shamebot

    So why can't you just call net.minecraft.server.BlockLever.interact(...) ?
     
  11. Offline

    ZachBora

    And how would you do that? Pretty much every object I have available is of type CraftSomething. Even my Block.getWorld() is a CraftWorld and not a net.minecraft.server.World

    A CraftBlock (which is what I have in my event) cannot be converted to a BlockLever (java.lang.ClassCastException: org.bukkit.craftbukkit.block.CraftBlock cannot be cast to net.minecraft.server.BlockLever) so I cannot simply do :

    ((net.minecraft.server.BlockLever) newblock).interact((World) e.getClickedBlock().getWorld(), newblock.getX(), newblock.getY(), newblock.getZ(), (EntityHuman)e.getPlayer());

    And I'll get the same problem casting a CraftPlayer to EntityHuman.
     
  12. Offline

    Shamebot

    Code:
    net.minecraft.server.Block.LEVER.interact(((CraftWorld)world).getHandle(),x,y,((CraftPlayer)player).getHandle());
     
    ZachBora likes this.
  13. Offline

    Technius

    I believe you have to use getHandle() on "Craft" classes to get their NMS equivalents, if they have any.
     
  14. Offline

    Shamebot

    As shown above.
     
  15. Offline

    ZachBora

    No compile errors, I'll give that a try.

    Edit: That works perfectly! thanks Shamebot! I never understood how to get the original elements, didn't know about this ".getHandle()"

    @Shamebot now is there a way I could get this to work with every interactable blocks without doing a switch?
    net.minecraft.server.Block.LEVER.interact(((CraftWorld)e.getClickedBlock().getWorld()).getHandle(),newblock.getX(), newblock.getY(), newblock.getZ(),((CraftPlayer)e.getPlayer()).getHandle());

    I got it working thanks to @fullwall and @Shamebot

    net.minecraft.server.Block.byId[newblock.getTypeId()].interact(((CraftWorld)e.getClickedBlock().getWorld()).getHandle(),newblock.getX(), newblock.getY(), newblock.getZ(),((CraftPlayer)e.getPlayer()).getHandle());

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

    Tim Visee

    So Is there also a way to set a block powered like a redstone lantern since it isn't possible to place a powered redstone lantern, so is there a way to power that block without a switch, torch or anything? I hope you understand what I mean.
    EDIT: I really like that video about those 'bots' who are cloning you btw!
     
  17. Offline

    ZachBora

    I haven't started modifying this plugin for 1.2.3 so I couldn't answer you.
     
  18. Offline

    Tim Visee

    k, no problem. Thanks for answering
     
Thread Status:
Not open for further replies.

Share This Page