Jump to content

[SOLVED][1.15.2] Replace vanilla block when placed


peter1745

Recommended Posts

Hello! I'm currently working on an aquatic update related mod, and I want to make it so that if a log is placed underwater it will be replaced with my custom "rotten" log.

I've managed to *sort of* prevent the placement of logs underwater by listening for the BlockEvent.EntityPlaceEvent event and cancelling that.

But when I call world.setBlockState with my custom block it doesn't actually place the block. Nothing happens, the vanilla log get's placed for like a second, then it disappears and my custom block doesn't appear.

Link to comment
Share on other sites

58 minutes ago, diesieben07 said:

Post your code.

@Mod.EventBusSubscriber(modid = Constants.MODID, bus = Mod.EventBusSubscriber.Bus.FORGE)
public class ClientEvents
{

	@SubscribeEvent
	public static void onBlockPlaced(BlockEvent.EntityPlaceEvent event)
	{
		IWorld world = event.getWorld();
		BlockPos pos = event.getPos();

		if (OceanicUtils.isBelowWater(world, pos))
		{
			if (event.getPlacedBlock().getBlock() == Blocks.OAK_LOG)
			{
				world.setBlockState(pos, ModBlocks.WET_OAK_LOG.getDefaultState(), 2);
				event.setCanceled(true);
			}
		}
	}

}

 

Link to comment
Share on other sites

Just now, diesieben07 said:

Make sure you only do that on the server. Why is the class called ClientEvents?!

Why are you using 2 for the flags for setBlockState?

The class is called ClientEvents because I was originally thought that those events would be detected on the client, I haven't bothered renaming it yet.

So the entire event should be handled on the server? It's a bit difficult to know since forge doesn't do a great job of explaining which events are triggered on what side.

I'm using 2 since that's the flag used to notify clients that a blockstate has changed? Shouldn't I be using that?

Link to comment
Share on other sites

Hmm... So I've moved the event to the server side by using a proxy and only registering the class in the server proxy, I've also changed the flag to 3 instead of 2. But it still doesn't work.

I'll post the code for both proxy stuff and the actual class below:

package com.oceanicsurvival.common;

import com.oceanicsurvival.core.ModBlocks;
import com.oceanicsurvival.utils.OceanicUtils;
import net.minecraft.block.Blocks;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IWorld;
import net.minecraftforge.event.world.BlockEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;

public class CommonEvents
{

	@SubscribeEvent
	public void onBlockPlaced(BlockEvent.EntityPlaceEvent event)
	{
		IWorld world = event.getWorld();

		if (!world.isRemote())
		{
			BlockPos pos = event.getPos();

			if (OceanicUtils.isBelowWater(world, pos))
			{
				if (event.getPlacedBlock().getBlock() == Blocks.OAK_LOG)
				{
					world.setBlockState(pos, ModBlocks.WET_OAK_LOG.getDefaultState(), 3);
					event.setCanceled(true);
				}
			}
		}
	}

}
package com.oceanicsurvival;

import com.oceanicsurvival.core.ModBlocks;
import com.oceanicsurvival.proxy.ClientProxy;
import com.oceanicsurvival.proxy.CommonProxy;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

@Mod(Constants.MODID)
public class OceanicSurvival
{

	public static final Logger LOGGER = LogManager.getLogger();
	public static final CommonProxy PROXY = DistExecutor.runForDist(() -> ClientProxy::new, () -> CommonProxy::new);

	public static final ItemGroup BLOCKS_GROUP = new ItemGroup("blocks")
	{
		@Override
		public ItemStack createIcon()
		{
			return new ItemStack(ModBlocks.WET_OAK_LOG);
		}
	};

	public OceanicSurvival()
	{
		FMLJavaModLoadingContext.get().getModEventBus().addListener(this::onCommonSetup);
		FMLJavaModLoadingContext.get().getModEventBus().addListener(this::onClientSetup);
	}

	private void onCommonSetup(final FMLCommonSetupEvent event)
	{
		PROXY.onSetupCommon();
	}

	private void onClientSetup(final FMLClientSetupEvent event)
	{
		PROXY.onSetupClient();
	}

}
package com.oceanicsurvival.proxy;

import com.oceanicsurvival.common.CommonEvents;
import net.minecraftforge.common.MinecraftForge;

public class CommonProxy
{

	public void onSetupCommon()
	{
		MinecraftForge.EVENT_BUS.register(new CommonEvents());
	}

	public void onSetupClient() {}

}

 

The ClientProxy simply overrides the CommonProxy (which I know should be called ServerProxy). I've double checked and the event only runs on the server side. I'm clueless

Link to comment
Share on other sites

Just now, diesieben07 said:

That doesn't make sense. Proxies distinguish between distributions, not logical sides. You need to check for World#isRemote.

Alright, I got it to sort of works. The problem is that by the time I call setBlockState the world still thinks that the vanilla log occupies that block which means it will simply ignore the setBlockState call. I'm not sure how to solve this but I'll take a look at it.

Link to comment
Share on other sites

8 minutes ago, diesieben07 said:

Cancelling the event means that the game will restore the world to the state before the placement happens. If you place a block in the same space during the event handler, that will be overwritten, because the game is restoring the world.

You have to probably wait a tick.

Turns out it was much simpler than I thought. I didn't realize that canceling the event reset the world state, so when I stopped canceling the event it worked. I literally just have to call World#setBlockState...

Well, thank you very much for the help! I highly appreciate it, oh and I'm sorry if was a bit slow with understanding what you meant. I haven't touched modding in almost a year so I'm a bit rusty

Link to comment
Share on other sites

  • peter1745 changed the title to [SOLVED][1.15.2] Replace vanilla block when placed

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.