Jump to content

[1.16] Making a vanilla block replaceable


A Soulspark

Recommended Posts

2021-04-28_22.48.20.png

My tea mod adds kettles, and now these should be placeable on top of campfires. Obviously campfires can't do that on their own, so I created a new block that looks like a campfire with one on top.

My problem is with "placing" the block. I'm currently doing it by detecting the RightClickBlock event when you right click a campfire, then changing the block, but this seems to be unnecessarily difficult, as I have to account for all the block placement rules again. Is there a simpler way to do this?

I saw there is an replaceBlock() method I could override, except I can't, I'd have to override from vanilla T-T
Here's my code. I gave up on this path once I realized you could place it even when the kettle was "inside" you (eg. you were standing on the campfire)

Spoiler



@SubscribeEvent
public static void onBlockRightClick(PlayerInteractEvent.RightClickBlock event) {
  //...
  if (event.getFace() == Direction.UP && handStack.getItem().isIn(TeaKettleTags.FILLED_KETTLES) && state.getBlock() == Blocks.CAMPFIRE) {
    // can't place if there are items on the campfire. 
    TileEntity tileEntity = world.getTileEntity(pos);
     if (tileEntity instanceof CampfireTileEntity) {
       NonNullList<ItemStack> items = ((CampfireTileEntity) tileEntity).getInventory();
       for (ItemStack stack : items) if (!stack.isEmpty()) return;
     }

     // place a campfire w/ kettle block at the location, copying the FACING state from the previous state and HOT from the item stack used
     if (!player.abilities.isCreativeMode) player.setHeldItem(event.getHand(), ItemStack.EMPTY);
     if (!world.isRemote) world.setBlockState(pos, ModBlocks.CAMPFIRE_WATER_KETTLE.get().getDefaultState().with(KettleBlock.FACING, state.get(CampfireBlock.FACING)).with(CampfireKettleBlock.HOT, handStack.getItem().isIn(TeaKettleTags.HOT_KETTLES)));

    // hardcoded values. eww
     world.playSound(player, player.getPosX(), player.getPosY(), player.getPosZ(), SoundType.METAL.getPlaceSound(), SoundCategory.NEUTRAL, 1.0F, 1.0F);

     event.setCanceled(true);
     event.setCancellationResult(ActionResultType.func_233537_a_(world.isRemote));
   }
  //...
}

 

 

Edited by A Soulspark
Link to comment
Share on other sites

31 minutes ago, A Soulspark said:

huh, that's clever, wonder why I went with such a difficult path for the detection xd

I still need to figure out the placement logic. do I really have to copy all the code that vanilla uses for normal block placement?

I'm not sure what you mean by copying the vanilla code. I believe you can just call World#setBlockState (in mcp mappings)

Link to comment
Share on other sites

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.