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

instead of listening for the RightClickBlock event, why not override the onItemUse (or something like it, there's a method that gets called when an item is used on a block), method on your kettle item? and handle the logic from there

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

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now


×
×
  • Create New...

Important Information

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