setBlockType makes error

Sponge Build: 1.11-6.0.0-BETA-174
Java Version: Java 8 (I use jre1.8.0_112

I need to listen the TickBlockEvent event, next to getTargetBlock(), and if this block is equals some block, to change it by setBlockType(). But this makes red text and I dont know what I need to do to repair it.

Block of code
@Inject
private Logger logger;

private World world;

@Listener
public void onTick(TickBlockEvent evt)
{
	BlockSnapshot block = evt.getTargetBlock();	
	if(block.getState().getType().equals(BlockTypes.GRAVEL))
	{
		logger.info(block.getPosition().toString());
		world.setBlockType(block.getPosition(), BlockTypes.AIR);
	}
Server Logs

[23:39:08] [Server thread/ERROR] [Sponge]: Could not pass TickBlockEvent$Scheduled$Impl to Plugin{id=myfirstplugin, name=myPlugin, version=1.0, source=mods\MyPlugin.jar}
java.lang.NullPointerException
at MyPlugin.Main.onTick(Main.java:36) ~[Main.class:?]
at org.spongepowered.common.event.listener.TickBlockEventListener_Main_onTick3.handle(Unknown Source) ~[?:?]
at org.spongepowered.common.event.RegisteredListener.handle(RegisteredListener.java:95) ~[RegisteredListener.class:1.11-6.0.0-BETA-174]
at org.spongepowered.common.event.SpongeEventManager.post(SpongeEventManager.java:305) [SpongeEventManager.class:1.11-6.0.0-BETA-174]
at org.spongepowered.common.event.SpongeEventManager.post(SpongeEventManager.java:320) [SpongeEventManager.class:1.11-6.0.0-BETA-174]
at org.spongepowered.common.SpongeImpl.postEvent(SpongeImpl.java:144) [SpongeImpl.class:1.11-6.0.0-BETA-174]
at org.spongepowered.common.event.tracking.TrackingUtil.updateTickBlock(TrackingUtil.java:222) [TrackingUtil.class:1.11-6.0.0-BETA-174]
at net.minecraft.world.WorldServer.redirect$onUpdateTick$zjf000(SourceFile:732) [lw.class:?]
at net.minecraft.world.WorldServer.func_72955_a(SourceFile:645) [lw.class:?]
at net.minecraft.world.WorldServer.func_72835_b(SourceFile:215) [lw.class:?]
at net.minecraft.server.MinecraftServer.func_71190_q(SourceFile:178) [MinecraftServer.class:?]
at net.minecraft.server.dedicated.DedicatedServer.func_71190_q(SourceFile:335) [lh.class:?]
at net.minecraft.server.MinecraftServer.func_71217_p(SourceFile:562) [MinecraftServer.class:?]
at net.minecraft.server.MinecraftServer.run(SourceFile:466) [MinecraftServer.class:?]
at java.lang.Thread.run(Unknown Source) [?:1.8.0_112]

Without seeing your full code (and thus, line numbers), I can’t give you a complete answer, but I assume world is null in your code because you don’t actually set it. You probably want the block’s original world anyway, so try changing the line

world.setBlockType(block.getPosition(), BlockTypes.AIR)

to

block.getLocation().ifPresent(loc -> loc.getExtent().setBlockType(block.getPosition(), BlockTypes.AIR));

(note that getLocation returns an Optional, but I suspect this is only empty if the world in question isn’t loaded, which if the block is ticking, it always should be!)

It’s all code of my plugin except imports etc.

I did it but I get the same error.

Error in console

[00:32:20] [Server thread/ERROR] [Sponge]: Could not pass TickBlockEvent$Scheduled$Impl to Plugin{id=myfirstplugin, name=myPlugin, version=1.0, source=mods\MyPlugin.jar}
java.lang.NoSuchMethodError: org.spongepowered.api.world.World.setBlockType(Lcom/flowpowered/math/vector/Vector3i;Lorg/spongepowered/api/block/BlockType;)V
at MyPlugin.Main.lambda$0(Main.java:36) ~[Main.class:?]
at java.util.Optional.ifPresent(Unknown Source) ~[?:1.8.0_112]
at MyPlugin.Main.onTick(Main.java:36) ~[Main.class:?]
at org.spongepowered.common.event.listener.TickBlockEventListener_Main_onTick3.handle(Unknown Source) ~[?:?]
at org.spongepowered.common.event.RegisteredListener.handle(RegisteredListener.java:95) ~[RegisteredListener.class:1.11-6.0.0-BETA-174]
at org.spongepowered.common.event.SpongeEventManager.post(SpongeEventManager.java:305) [SpongeEventManager.class:1.11-6.0.0-BETA-174]
at org.spongepowered.common.event.SpongeEventManager.post(SpongeEventManager.java:320) [SpongeEventManager.class:1.11-6.0.0-BETA-174]
at org.spongepowered.common.SpongeImpl.postEvent(SpongeImpl.java:144) [SpongeImpl.class:1.11-6.0.0-BETA-174]
at org.spongepowered.common.event.tracking.TrackingUtil.updateTickBlock(TrackingUtil.java:222) [TrackingUtil.class:1.11-6.0.0-BETA-174]
at net.minecraft.world.WorldServer.redirect$onUpdateTick$zjf000(SourceFile:732) [lw.class:?]

No, that’s a different error, you got a NullPointerException before, you now get a NoSuchMethodError, which means that you’re (probably) compiling against a different version of the Sponge API, I hadn’t realised that your setBlockType definition was wrong. Make sure you’re compiling against API 6, then have a read of this JavaDocs page to see how to use setBlockType.

If you need a bit more info on Causes (which you will require), see http://docs.spongepowered.org/master/en/plugin/event/causes.html

Yes, I had 4.0.3 API version in my pom.xml, thank you for your prompt. I wrote 5.0.0 instead, and NoSuchMethorError isn’t yet.

But 5.0.0 API need a Cause in setBlockType() as 3rd argument. What I need to write in this place to make it working? I wrote evt.getCause(), but it makes error

Error with evt.getCause()

[01:30:51] [Server thread/ERROR] [Sponge]: Could not pass TickBlockEvent$Scheduled$Impl to Plugin{id=myfirstplugin, name=myPlugin, version=1.0, source=mods\MyPlugin.jar}
java.lang.IllegalArgumentException: PluginContainer must be at the ROOT of a cause!
at com.google.common.base.Preconditions.checkArgument(Preconditions.java:125) ~[minecraft_server.1.11.jar:?]
at net.minecraft.world.WorldServer.setBlock(SourceFile:943) ~[lw.class:?]
at net.minecraft.world.World.setBlock(SourceFile:349) ~[ajq.class:?]
at org.spongepowered.api.world.extent.MutableBlockVolume.setBlockType(MutableBlockVolume.java:97) ~[MutableBlockVolume.class:1.11-6.0.0-BETA-174]
at org.spongepowered.api.world.extent.MutableBlockVolume.setBlockType(MutableBlockVolume.java:80) ~[MutableBlockVolume.class:1.11-6.0.0-BETA-174]
at MyPlugin.Main.lambda$0(Main.java:31) ~[Main.class:?]
at java.util.Optional.ifPresent(Unknown Source) ~[?:1.8.0_112]
at MyPlugin.Main.onTick(Main.java:31) ~[Main.class:?]
at org.spongepowered.common.event.listener.TickBlockEventListener_Main_onTick3.handle(Unknown Source) ~[?:?]
at org.spongepowered.common.event.RegisteredListener.handle(RegisteredListener.java:95) ~[RegisteredListener.class:1.11-6.0.0-BETA-174]
at org.spongepowered.common.event.SpongeEventManager.post(SpongeEventManager.java:305) [SpongeEventManager.class:1.11-6.0.0-BETA-174]
at org.spongepowered.common.event.SpongeEventManager.post(SpongeEventManager.java:320) [SpongeEventManager.class:1.11-6.0.0-BETA-174]
at org.spongepowered.common.SpongeImpl.postEvent(SpongeImpl.java:144) [SpongeImpl.class:1.11-6.0.0-BETA-174]
at org.spongepowered.common.event.tracking.TrackingUtil.updateTickBlock(TrackingUtil.java:222) [TrackingUtil.class:1.11-6.0.0-BETA-174]
at net.minecraft.world.WorldServer.redirect$onUpdateTick$zjf000(SourceFile:732) [lw.class:?]
at net.minecraft.world.WorldServer.func_72955_a(SourceFile:645) [lw.class:?]
at net.minecraft.world.WorldServer.func_72835_b(SourceFile:215) [lw.class:?]
at net.minecraft.server.MinecraftServer.func_71190_q(SourceFile:178) [MinecraftServer.class:?]
at net.minecraft.server.dedicated.DedicatedServer.func_71190_q(SourceFile:335) [lh.class:?]
at net.minecraft.server.MinecraftServer.func_71217_p(SourceFile:562) [MinecraftServer.class:?]
at net.minecraft.server.MinecraftServer.run(SourceFile:466) [MinecraftServer.class:?]
at java.lang.Thread.run(Unknown Source) [?:1.8.0_112]

I tried to hide code in spoiler, but it isn’t work always.
I’m in one step near win, I hope.

Yes, I know, my English is very bad, excuse me.

Don’t worry about the language, I can understand you!

I urge you to read the Docs at your leisure, they are available in a variety of languages, and hopefully will help you in the future - http://docs.spongepowered.org/

As for your current problem: “PluginContainer must be at the ROOT of a cause!” - you’ve perhaps guessed your Cause is wrong. It wants you to create your own cause, which has the class with the @Plugin annotation on it. So, in your case, change evt.getCause() to Cause.of(NamedCause.source(this)). Hopefully then, you should be good to go.

(I use NamedCause.source here as I think of the event’s source as being your plugin - others might disagree with me!)

If I do only this, I get the same error “PluginContainer must be at the ROOT of a cause!”.
I don’t know how to create my own cause, I’m full newbie in minecraft coding.

I read it, but it is worry translated to my language, much of text isn’t translated.

Mind linking your code or a snippet of the code in question? Also if you tell us your language I might be able to help with the missing text on the docs. Best of luck!

1 Like

Change it to: world.getLocation(v).setBlockType(BlockTypes.BEDROCK,
Cause.source(Sponge.getPluginManager().fromInstance(plugin).get()).build());

And it can’t be called any earlier then: GameStartingServerEvent event because thats when the worlds are loaded.

v is a Vector3i variable.
plugin is an instance of the plugin. (Also on a different class) If this is in your main class, use ‘this’ else