Redstone power data on non-redstone blocks?

Disclaimer: I realize that Sponge is not Bukkit, but that’s my frame of reference for this request as I’m porting over my Bukkit plugin to Sponge. I’m well aware that “because Bukkit had it” isn’t necessarily a reason to bring it to Sponge. Please bear with me.

Bukkit had a BlockRedstoneEvent that was really useful in doing interesting power-related actions on blocks that weren’t necessarily redstone blocks. My specific use case is implementing wireless redstone, which uses Signs to establish channels, transmitters, and receivers. In order to make it work, I need to know when a Sign block receives redstone power, and then can change the receivers into redstone torches to propagate the signal elsewhere.

I was testing to see if the current recommended Sponge Beta (spongeforge-1.8.9-1691-3.1.0-BETA-1046) notified my plugin about redstone events. I enabled the firehose of ChangeBlockEvent and logged all the transactions. I got a ChangeBlockEvent.Modify for the redstone wire powering up after placing a redstone torch next to it, but nothing about the Sign block “connected” to the wire.

So:

  1. Is there a way to do this already that I’m missing? I seem to be having trouble determining which event I should be using if it already exists.
  2. If not, is this something worth adding to the implementation? I think it adds possibilities to server-side plugins, especially on un-modded and/or vanilla servers.

Thanks. (Also, happy to file a GitHub issue if that would be of more use.)

@DsRulesAl: There’s currently not an easy way to do this, but it should eventually be possible.

Currrently, you’ll need to listen to NotifyNeighborBlockEvent, and check if one of the neighbors being notified is a block you’re interested in.

I currently have an issue open for improving how redstone-power related information is accesed. If you care about more than just whether a block is emitting power, then you’ll probably want to cast to NMS for now.

Note that in all cases, you’ll never actually be checking something on your target block. Instead, you’ll be checking whether or not some neighbor block is emitting (strong or weak) power.

Thanks for the reply. I’ll check out the NotifyNeighborBlockEvent; I’m sure I can make it work the way I need it for now. (It also took a little time to figure out how to detect block changes caused by physics. Though Bukkit had an event for that too, Sponge’s event transactions and causes actually made the code simpler overall.) Looking forward to the redstone clean-up. I love working with the API so far.

I got the same issue and using NotifyNeighborblockEvent is not the better solution because it is triggered for other reasons than Redstone change, and it is impossible to filter events based on a positive or negative Redstone power change.

I have a lot of events triggered for a specific block and I can’t say if it was just powered or unpowered, or if its power state has not changed.

Yeah, you can’t do anything really powerful with redstone while using NotifyNeighborBlockEvent. I think the block that is doing the notifying is listed in the causes. I was thinking instead of trying to replicate all the redstone functionality using this event, I would simplify it to just powered wire next to a block I care about. And only test for power levels of 0 and >0. Really not ideal, but it unblocks me from porting for now.

@blood may be able to comment on a better way to do this.

I faced this issue when porting CraftBook over, but I feel that I’ve found a solution that is actually better than the way it was handled in Bukkit.

https://github.com/sk89q/CraftBook/blob/master/src/main/java/com/sk89q/craftbook/sponge/mechanics/powerable/SimplePowerable.java#L15

That function there detects when a neighbor changes, and then checks the redstone state of the block.

In this case it is a netherrack block, glowstone block, etc… But overall this works and allows you to get the current signal.

Interesting. Thanks for sharing that. I’m going to give this a shot and see if it works for what I’m looking to do. Looks like it should handle the simplified mechanism I described earlier. I’ll try to report back when I have a chance to give it a go.

That’s roughly what I did. The issue is that the event is called several times, for example when we simply switch on a lever (too far away to detect it). You may want to execute the function only once.

It looks like it fires for each tick as the power level goes down to 0.

Store the last powered state, and then only do the action if it changes.

Judging by chatter in IRC, as well as a few people interested on this thread, if you were to design API to make this better what would you do for API 6?

Well a redstone sub-event would be nice, but it’s a real pain to implement, because that needs to be called instead of the other one… and they’re called at different spots.

The way I’ve been handling it works pretty well anyway.

But a blockupdate != a redstone powering change though. They are different concepts. So I’m not sure that it would need to be called instead of the other one at all.

That said, blocks should only really be notified/act once the update hits though in order to match quasi-connectivity.

I would definitely welcome an API for the redstone system.

Has something like the suggested event been included in the API yet?