The Bug:
Amethyst crystals aren't placed in other valid spaces when targeting invalid areas of placement.
Steps to Reproduce:
Build the setup as shown in the provided attachment.
Obtain any amethyst crystal and attempt to place it down whilst targeting any side faces of the leaf block.
Take note as to whether or not amethyst crystals are placed in other valid spaces when targeting invalid areas of placement.
Observed Behavior:
Amethyst crystals aren't placed in other valid spaces when targeting invalid areas of placement.
Expected Behavior:
Amethyst crystals would be placed in other valid spaces when targeting invalid areas of placement.
Code Analysis:
The following is based on a decompiled version of Minecraft 26.3 Snapshot 4 using Mojang mappings.
An amethyst crystal has to be attached to a full, flat face on the block behind it, which leaves do not provide. When you place one, the game picks which way it points from the face you aimed at, and if canSurvive finds that a crystal pointing that way cannot stay attached, the placement is thrown away.
net.minecraft.world.level.block.AmethystClusterBlock.java
@Override
public @Nullable BlockState getStateForPlacement(final BlockPlaceContext context) {
LevelAccessor level = context.getLevel();
BlockPos pos = context.getClickedPos();
return this.defaultBlockState().setValue(WATERLOGGED, level.getFluidState(pos).is(Fluids.WATER)).setValue(FACING, context.getClickedFace());
}net.minecraft.world.level.block.LadderBlock.java
@Override
public @Nullable BlockState getStateForPlacement(final BlockPlaceContext context) {
...
BlockState state = this.defaultBlockState();
LevelReader level = context.getLevel();
BlockPos pos = context.getClickedPos();
FluidState replacedFluidState = context.getLevel().getFluidState(context.getClickedPos());
for (Direction direction : context.getNearestLookingDirections()) {
if (direction.getAxis().isHorizontal()) {
state = state.setValue(FACING, direction.getOpposite());
if (state.canSurvive(level, pos)) {
return state.setValue(WATERLOGGED, replacedFluidState.is(Fluids.WATER));
}
}
}
return null;
}If we look at the above classes, we can see that an amethyst crystal only ever tries the one face you aimed at, so the game gives up right away even when another direction in that same space would have held it. A ladder instead works through the directions you are looking in and settles on the first one that can stay attached. Its sideways check is only there because ladders cannot point up or down, which an amethyst crystal can.
Large, medium and small amethyst buds are affected in the same way, as they share the same class.
Fixed Code:
net.minecraft.world.level.block.AmethystClusterBlock.java
@Override
public @Nullable BlockState getStateForPlacement(final BlockPlaceContext context) {
LevelReader level = context.getLevel();
BlockPos pos = context.getClickedPos();
BlockState state = this.defaultBlockState()
.setValue(WATERLOGGED, level.getFluidState(pos).is(Fluids.WATER))
.setValue(FACING, context.getClickedFace());
if (state.canSurvive(level, pos)) {
return state;
}
for (Direction direction : context.getNearestLookingDirections()) {
state = state.setValue(FACING, direction.getOpposite());
if (state.canSurvive(level, pos)) {
return state;
}
}
return null;
}The above keeps the face you aimed at as the first choice, and falls back to the other directions you are looking in when a crystal pointing that way cannot stay attached. The crystal is then held not by the leaf itself, but by another surface bordering the same space.
Copying the ladder loop on its own would have been enough most of the time, as getNearestLookingDirections usually lists the face you aimed at first. It does not do that when the block you clicked is one that gets replaced, such as tall grass, a snow layer or water, and starting from the loop there could quietly turn a placement that works today to face a different way. Testing the aimed at face first means the change can only add placements that used to fail, never alter one that already succeeds.
This change was applied to a modified client and tested against the steps above, and the crystal is now placed.
Linked issues
Attachments
Comments 5
Relates to MC-136405
Can confirm this in 21w40a. The expected behavior would be that amethyst crystals would default to valid placements when targeting blocks it cannot be placed on.
Can confirm.