Farmer's Delight

Farmer's Delight

77M Downloads

More intuitive interactions with the cutting board

Lolcroc opened this issue ยท 3 comments

commented

After several hours of playtime I have found interactions with the cutting board somewhat clunky right now (clicks do not do what you'd expect). This suggestion is meant to improve the interaction in the following way.

Placing items

Currently, a board that already contains an item will have it try to cut on right-click, even if the player isn't wearing a knife or when the item isn't cuttable. Trying to cut should only be done if the player is holding a knife and if the item is cuttable, otherwise the item is replaced by whatever the player is holding in his main hand. An exception to the latter is when the item may be added to whatever stack the player is holding. In that case the item is added to the player's hand and the board is cleared. Also if the main hand is empty and the player can't cut, the click retrieves the item and clears the board.

Cutting items

With a cuttable item in offhand and knife in main hand, this interaction works how you'd expect. The first right-click places the cuttable item down, the second right-click then cuts it with the knife. This behaviour should also be present for a knife in offhand and cuttable item in main hand; currently the cuttable item's right-click behaviour (e.g. eating) overrides this expected behavior.

Removing items

Copy this behavior from item frames. At any point, items may be removed with left-click.

commented

Hi! Sorry for taking so long to reply, and thank you a lot for the feedback! โค๏ธ

I'll share my two cents below:

Currently, a board that already contains an item will have it try to cut on right-click, even if the player isn't wearing a knife or when the item isn't cuttable. Trying to cut should only be done if the player is holding a knife and if the item is cuttable, otherwise the item is replaced by whatever the player is holding in his main hand

Though this could work, the problem here is that it's not just the knife which can be used as a tool. In cutting recipes, any item can be a tool if so specified by a recipe. Identifying if the item is a tool or not isn't trivial, due to how recipe checking works.

Also, the Cutting Board's "status message hints" rely on items not being swapped around. I added them to let a player know, without needing JEI, that either their ingredient or their tool is invalid, and they should try something else. By allowing an item swap in invalid cases, this hint would never show up. :(

With a cuttable item in offhand and knife in main hand, this interaction works how you'd expect. The first right-click places the cuttable item down, the second right-click then cuts it with the knife. This behaviour should also be present for a knife in offhand and cuttable item in main hand; currently the cuttable item's right-click behaviour (e.g. eating) overrides this expected behavior.

True, it would be better if both orientations worked. At the time of implementation, I ran into problems when allowing both-sided place/cut interactions, because the order in which the off-hand and the main-hand affect a block is unilateral; I had to workaround to even get the off-hand to go first. It also suffers from the problem of not being able to identify which items are "tools".

In this case, I've been thinking a bunch about whether this off-hand-prioritizing mechanic could be exchanged by just letting the Cutting Board hold a full stack of items instead. This way, stackables could be placed once, while players hold the use button to cut them one by one. It would only hinder non-stackable ingredients (such as Leather Armor), but those could be good cases for hopper automation instead. I need to play around with this mechanic sometime.

Copy this behavior from item frames. At any point, items may be removed with left-click.

Hmm... The Item Frame is an entity, so it's probably easier to do so on it; not sure if blocks have an easy way to remove on left-click. I can check later, and see if it doesn't end up causing too many accidental item removals. ๐Ÿ‘

commented

Thank you for the comprehensive reply. It's funny how many of these choices are technical limitations.

Status hints
I agree the message hints are vital for players without JEI. I also believe players do not have to rely on other mod's information in order to play something properly. That is not to say one cannot go without the other.

It may be fine (and perhaps desirable) to show the status message once if a player tried an invalid action, and otherwise do the swapping/retrieving behaviour if the player tries the same thing again. I still think this is better than having to clear a hotbar slot to remove items I don't intend on cutting/chopping/digging, because my hotbar is always full. Now that I think about it, left-click to remove will solve this problem without messing with the existing mechanics.

Place/cut interactions
I've dug through CuttingBoardBlock and CuttingBoardBlockEntity code and the interaction with Minecraft vanilla (especially Minecraft::startUseItem). Currently right-click behaviour is deferred to the off-hand if that is non-empty, but this forces Minecraft to first check the main-hand ItemStack's right-click behaviour (like eating) and then check the offhand. Trying to place items from the main hand requires the block to be aware of which hand contains the tool, and which hand doesn't, as you've stated.

I do believe this is possible. The RecipeWrapper used for checking recipes in CuttingBoardBlockEntity::getMatchingRecipe wraps a single-item ItemStackHandler. A wrapper around a single ItemStack may be used to directly check for matching recipes from the player's hand. However I'm not sure about the performance impact of this check if players start spam-clicking the cutting board (perhaps some caching required).

Left-click to retrieve
Overriding BlockBehaviour::attack will do the trick. Here is a possible implementation

@Override
public void attack(BlockState state, Level worldIn, BlockPos pos, Player player) {
    if (!worldIn.isClientSide) {
        BlockEntity tileEntity = worldIn.getBlockEntity(pos);
        if (tileEntity instanceof CuttingBoardBlockEntity cuttingBoardEntity) {
            ItemStack stack = cuttingBoardEntity.removeItem();
            
            if (!player.isCreative() && !stack.isEmpty()) {
                Containers.dropItemStack(worldIn, pos.getX(), pos.getY(), pos.getZ(), stack);
                worldIn.playSound(null, pos.getX(), pos.getY(), pos.getZ(), SoundEvents.ITEM_FRAME_REMOVE_ITEM, SoundSource.BLOCKS, 1.0F, 1.0F);
            }
        }
    }
}

Conclusions
All that being said, it's pretty clear that changing this behaviour will be very technical and time-consuming. It might be better to spend time on other, more interesting or critical issues, and come back to it later. Thank you for checking it out anyway.

commented

I'm converting this to a discussion so it's not lost amidst the issues, as it's a design discussion. ๐Ÿ‘