Solved Changing the blockstate of redstone to be powered

Discussion in 'Spigot Plugin Development' started by MCrafterzz, Aug 5, 2018.

  1. Hello I'm trying to change the state of redstone wire to be powered. I get the data with block.getBlockData(). The problem is that it can't be cast to AnaloguePowerable as that's what's needed to change the power level. Code:
    Code (Text):

                if (blockData instanceof AnaloguePowerable) {
                    AnaloguePowerable powerable = (AnaloguePowerable) blockData;
                    powerable.setPower(15);
                    block.setBlockData(blockData);
                } else {
                    System.out.println("NOT REDSTONE");
                }
    It always prints "NOT REDSTONE". Removing the check crashes: org.bukkit.craftbukkit.v1_13_R1.block.data.CraftBlockData can't be cast to org.bukkit.block.data.AnaloguePowerable. The thing I really don't understand is that getBlockData returns org.bukkit.block.data.BlockData so I have no idea why it's suddenly org.bukkit.craftbukkit.v1_13_R1.block.data.CraftBlockData
     
  2. This is strange, because RedstoneWire implements AnaloguePowerable, according to the Javadoc. Perhaps you somehow got the wrong block?

    So, BlockData is just the interface which Block#getBlockData promises you to return. Interfaces cannot be instantiated, so it will always return a subclass which implements BlockData, in this case CraftBlockData.
    This actually suggests that you did not get the right block, because if this was redstone wire, getBlockData would return an instance of CraftRedstoneWire, not CraftBlockData.

    Sidenote: You can always print out the actual class of an object via
    Code (Text):
    System.out.println(object.getClass().getName());
     
  3. Changing some positions so it accually targets the redstone wire it now says class org.bukkit.craftbukkit.v1_13_R1.block.impl.CraftRedstoneWire when printing out the class

    Changed to:
    Code (Text):
    if (blockData instanceof CraftRedstoneWire) {
                    CraftRedstoneWire redstoneWire = (CraftRedstoneWire) blockData;
                    redstoneWire.setPower(15);
                    block.setBlockData(blockData);
                }
    Now it no longer crashes but it has no effect
     
  4. There you go, CraftRedstoneWire implements RedstoneWire and AnaloguePowerable. :)
     
  5. Also can you please explain why there are two versions of a lot of stuff like ItemStack. org.bukkit something and org.bukkit.craftbukkit.v1_13_R1. something.
     
  6. It still doesn't change the wire. Does it need some sort of update?
     
  7. Packages in org.bukkit are the public API which we are supposed to use when writing plugins. There is a reasonable expectations that said API will not change across different versions of Spigot, although there are a few exceptions, like with 1.13 and the BlockData.

    Everything in org.bukkit.craftbukkit is the internal implementation of the Spigot server. We may use it, but there is no guarantee that the classes and methods in there will still be around come the next version, and doctoring with that is not generally supported. At some point they added the version number (the v1_13_R1 part above) to the package name so we can make plugins for different versions of Spigot more easily if we want to. Also, I suspect, for prevent us from trying to run outdated code which yields unexpected results. ;)

    So, many classes in org.bukkit are just an interface which is backed by the implementation which resides in org.bukkit.craftbukkit. Just like Block and CraftBlock, or ItemStack and CraftItemStack.

    I'm not sure exactly why the redstone power isn't changing; it depends on where in your code it gets changed. There is a chance that Minecraft itself simply changes it back the very next moment because it realized there is nothing powering this wire.
     
  8. It's a scheduled task:
    Code (Text):
    Bukkit.getScheduler().scheduleSyncRepeatingTask(this, new Runnable() {
                @Override
                public void run() {
                    for (Player player : getServer().getOnlinePlayers()) {
                        for (Entity entity : player.getWorld().getNearbyEntities(player.getLocation(), 50, 150, 50)) {
                            if (entity.getType() == EntityType.ARMOR_STAND) {
                                if (entity.getScoreboardTags().contains("Machine")) {
                                    if (entity.getScoreboardTags().contains("RedstoneClock")) {
                                        RedstoneClockFunction.Update(entity);
                                    }
                                }
                            }
                        }
                    }
                }
            }, 0, 20);
    that updates all the redstone clocks:
    Code (Text):
    public static void Update(Entity entity) {
            Score clockScore = Plugin.scoreboard.getObjective("Clock").getScore(entity.getUniqueId().toString());
            clockScore.setScore(clockScore.getScore() - 1);

            if (clockScore.getScore() == 0) {
                Block block = entity.getWorld().getBlockAt(entity.getLocation().add(0, 2, 0));
                BlockData blockData = block.getBlockData();

                if (blockData instanceof CraftRedstoneWire) {
                    CraftRedstoneWire redstoneWire = (CraftRedstoneWire) blockData;
                    redstoneWire.setPower(15);
                    block.setBlockData(blockData);
                }

                clockScore.setScore(
                        Plugin.scoreboard.getObjective("Time").getScore(entity.getUniqueId().toString()).getScore());
            }
        }
    What I want happen is that every ten seconds a one tick pulse should be sent out by powering the redstone dust above that can for example power a lamp or a piston.
     
  9. I'm not saying this couldn't work somehow, but have you tried turning the block into, say, a redstone block, then turning it back into whatever it was, on the next tick?
     
  10. That will work as I did that for the vanilla function of the machines, the only problem with that is that the block can be broken and therfor become a duplication machine for redstone but maybe I can prevent that