How to get target TileEntity from ChangeBlockEvent.Break?

Hello all. How to get target TileEntity from ChangeBlockEvent.Break?

My code:

    @Listener
    public void onChangeGrave(ChangeBlockEvent.Break event) {
        boolean playerCause = event.getCause().first(Player.class).isPresent();
        if (playerCause) {
            Player player = event.getCause().first(Player.class).get();

            event.getTransactions().stream().forEach((trans) -> {
                if (trans.getOriginal().getState().getType().equals(BlockTypes.WALL_SIGN)) {

                    SignManipulator dataofsign = new SignManipulator();
                    Location<World> location = trans.getOriginal().getLocation().get();
                    TileEntity tileEntity = (TileEntity) location.getTileEntity().get();
                    ArrayList<String> signLines = dataofsign.getLines(tileEntity);

                    Text line0 = Texts.of(TextColors.GRAY, signLines.get(0));
                    player.sendMessages(line0);
                }
            });
        }
    }
}

Eror: pastebin
Error because of the line: TileEntity tileEntity = (TileEntity) location.getTileEntity().get();

You don’t need to put code in spoilers BTW

I would say the reason it’s not working is because the tile entity is destroyed before you can query it.
BlockSnapshot is an ImmutableDataHolder so it is possible to query for data that way, example:

trans.getOriginal().get(ImmutableSignData.class);

However it seems that doesn’t work when I tested it but I think that would be the correct way.

I tried. The same error.
My line: ImmutableSignData iSignData = trans.getOriginal().get(ImmutableSignData.class).get();

If you’re asking a lot of questions, the #spongedev IRC Channel may be a really good resource. You can get more instantaneous feedback and stuff.

We don’t bite… much…

I think I found the problem, TileEntity.getContainers() always returns an empty list.

https://github.com/trentech/ProjectWorlds/blob/master/src/com/gmail/trentech/pjw/listeners/SignEventManager.java

Maybe they’ll help. View listener at line 112

I found the reason for this.
Code:

    @Listener
    public void onChangeGrave(ChangeBlockEvent.Break event) {
        boolean playerCause = event.getCause().first(Player.class).isPresent();
        if (playerCause) {
            Player player = event.getCause().first(Player.class).get();

            event.getTransactions().stream().forEach((trans) -> {
                if (trans.getOriginal().getState().getType().equals(BlockTypes.WALL_SIGN)) {
                    Location<World> location = trans.getOriginal().getLocation().get();
                    Text msg = Texts.of(TextColors.GRAY, "You broke: " + location.getBlockType().getName());
                    player.sendMessages(msg);
                }
            });
        }
    }
}

This code return: “You broke: minecraft:air”.

1 Like

Well right, because the location will always give you the current block type, which is after the block transaction.

What isn’t working is that you should be able to get the ImmutableSignData of the Original block, and that doesn’t seem to be the case.

Error on line: ImmutableSignData iSignData = trans.getOriginal().getOrCreate(ImmutableSignData.class).get();

What is the error?

@JBYoshi, This error:

[17:14:33] [Server thread/ERROR] [Sponge/]: Could not pass ChangeBlockEvent$Break$Impl to Plugin{id=grave, name=Grave, version=0.1}
java.util.NoSuchElementException: No value present
	at java.util.Optional.get(Unknown Source) ~[?:1.8.0_66]
	at io.github.azatik.grave.events.EventChangeGrave.lambda$onChangeGrave$3(EventChangeGrave.java:84) ~[EventChangeGrave.class:?]
	at java.util.Iterator.forEachRemaining(Unknown Source) ~[?:1.8.0_66]
	at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Unknown Source) ~[?:1.8.0_66]
	at java.util.stream.ReferencePipeline$Head.forEach(Unknown Source) ~[?:1.8.0_66]
	at io.github.azatik.grave.events.EventChangeGrave.onChangeGrave(EventChangeGrave.java:59) ~[EventChangeGrave.class:?]
	at org.spongepowered.common.event.listener.BreakListener_EventChangeGrave_onChangeGrave9.handle(Unknown Source) ~[?:?]
	at org.spongepowered.common.event.RegisteredListener.handle(RegisteredListener.java:86) ~[RegisteredListener.class:1.8-1577-2.1-DEV-915]
	at org.spongepowered.mod.event.SpongeModEventManager.post(SpongeModEventManager.java:230) [SpongeModEventManager.class:1.8-1577-2.1-DEV-915]
	at org.spongepowered.mod.event.SpongeModEventManager.postBulk(SpongeModEventManager.java:218) [SpongeModEventManager.class:1.8-1577-2.1-DEV-915]
	at org.spongepowered.mod.event.SpongeModEventManager.post(SpongeModEventManager.java:255) [SpongeModEventManager.class:1.8-1577-2.1-DEV-915]
	at org.spongepowered.mod.event.SpongeModEventManager.post(SpongeModEventManager.java:242) [SpongeModEventManager.class:1.8-1577-2.1-DEV-915]
	at org.spongepowered.common.SpongeImpl.postEvent(SpongeImpl.java:111) [SpongeImpl.class:1.8-1577-2.1-DEV-915]
	at net.minecraft.world.World.handlePostTickCaptures(World.java:805) [aqu.class:?]
	at net.minecraft.network.PacketThreadUtil$1.onProcessPacket(SourceFile:87) [ih.class:?]
	at net.minecraft.network.PacketThreadUtil$1.run(SourceFile:13) [ih.class:?]
	at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) [?:1.8.0_66]
	at java.util.concurrent.FutureTask.run(Unknown Source) [?:1.8.0_66]
	at net.minecraftforge.fml.common.FMLCommonHandler.callFuture(FMLCommonHandler.java:714) [FMLCommonHandler.class:?]
	at net.minecraft.server.MinecraftServer.func_71190_q(MinecraftServer.java:656) [MinecraftServer.class:?]
	at net.minecraft.server.dedicated.DedicatedServer.func_71190_q(DedicatedServer.java:364) [po.class:?]
	at net.minecraft.server.MinecraftServer.func_71217_p(MinecraftServer.java:598) [MinecraftServer.class:?]
	at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:478) [MinecraftServer.class:?]
	at java.lang.Thread.run(Unknown Source) [?:1.8.0_66]

Could you run System.out.println(trams.getOriginal()); and send me the output?

You can’t use getOrCreate for Immutable Data. At least you can’t expect it to return a meaningful value.

@JBYoshi,
[STDOUT/]: [io.github.azatik.grave.events.EventChangeGrave:lambda$onChangeGrave$3:89]: SpongeBlockSnapshot{worldUniqueId=76321e7c-dfc0-4f8a-ace6-fdab0adf3086, position=(157, 71, 281), blockState=minecraft:wall_sign[facing=north], extendedState=minecraft:wall_sign[facing=north]}

I’m starting to think this is an API problem, as the immutable sign data is not being passed to the block break event.

I think @gabizou is the best one to answer this though.

@gravityfox is right. Try this code:
ImmutableSignData iSignData = trans.getOriginal().getOrCreate(SignData.class).get().asImmutable();

That won’t work either.

it’s the Optional.get() throwing the exception.

simon816’s code SHOULD be working. It’s not, and that’s the issue.

I changed it to get the mutable SignData, then convert it to an immutable version. The original code just asked for the ImmutableSignData.

@JBYoshi: