mojira.dev
MC-102223

Paintings in structure blocks not loading in same place

The bug

When you place a painting in a Structure and save it using the Save Structure Block, and then Load the structure, the painting will sometimes load one block off.

  • All paintings with even height are loaded off in +Y axis

  • A painting with even width is off if

    • it looks towards +Z when loaded, then it's loaded off in +X

    • it looks towards -X when loaded, then it's loaded off in +Z

Affects rotating/mirroring

Cause

The problem seems to be that the Pos tag of hanging entities refers to the center of the entity, however when it is created the passed position is the position of its corner. This could probably be solved by using the TileX, TileY and TileZ values for hanging entities.

Linked issues

Attachments

Comments 19

Aniline Selenic

Possibly related to this, Item Frames have a similar issue.

When the structure is rotated when loading, the item frame (with item in it) will be floating in front of the wall.

This happens at the 90 and 270 degree rotations.

I added additional screenshots showing the floating item frames.

Aniline Selenic

Testing with Mirrors:

Using the Z-axis mirror (< >), you get the same results for paintings and items frames that you get without mirrors. Painting misplaced at 0 rotation and 270 rotation. Item Frames misplaced at 90 and 270 rotations.

Using the X-axis mirror (^ v), the paintings are all correctly placed at every rotation. However, the Item Frames are misplaced at the 90 and 270 rotations again.

[Mod] redstonehelper

Possibly fixed in 1.10-pre1, but difficult to verify with MC-102894.

[Mod] redstonehelper

Not fixed in 1.10-pre2.

The problem seems to be that the Pos tag of hanging entities refers to the center of the entity, however when it is created the passed position is the position of its corner. This could probably be solved by using the TileX, TileY and TileZ values for hanging entities.

9 more comments

can confirm in 1.19.4

Confirm in 1.20.1

[media]
minecraftjibam2

Confirmed in 1.20.4

[media]

Potential Solution?
In StructureTemplate#placeEntities before Mob#finalizeSpawn, it might be possible to run some kind of structure placement validation check which corrects the positioning of the entity (and any future entities that may have a similar issue?) prior to finalization.

By converting the painting variant's width and height to block sizes (Variant#getWidth() / 16), if the height is even, offset the painting Y block pos down by 1. If the width is even, and the painting direction is west or south, offset by Direction#getClockwise().getNormal(), then set the painting pos to that position.

The mixin code I wrote to test this solution (in 1.20.2) looks like this: (MojMap)

@Mixin(StructureTemplate.class)
public class StructureTemplateMixin {
    // Injects into StructureTemplate#placeEntities, inside the lambda of createEntityIgnoreException
    @Inject(method = "method_17917", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;moveTo(DDDFF)V", shift = At.Shift.AFTER))
    private static void fixPaintingPlacement(Rotation rotation, Mirror mirror, Vec3 vec3, boolean bl, ServerLevelAccessor level, CompoundTag tag, Entity entity, CallbackInfo ci) {
        if (!(entity instanceof Painting painting)) {
            return;
        }

        var pos = new BlockPos.MutableBlockPos();
        pos.set(painting.getPos());
        var variant = painting.getVariant().value();

        var width = variant.getWidth() / 16;
        var height = variant.getHeight() / 16;
        var direction = painting.getDirection();

        // paintings with an even height seem to always be moved upwards...
        if (height % 2 == 0) {
            pos.move(0, -1, 0);
        }

        // paintings with an even width seem to be moved in the clockwise direction of their facing direction,
        // if they're west or south.
        if (width % 2 == 0 && (direction == Direction.WEST || direction == Direction.SOUTH)) {
            var moveTo = direction.getClockWise().getNormal();
            pos.move(moveTo);
        }

        painting.setPos(pos.getCenter());
    }
}

 

 

Still in 1.20.6

[MOD] Greymagic27
[media]

From reproducing this issue in 1.21.5-rc2

Aniline Selenic

(Unassigned)

Confirmed

Platform

Normal

Structures

painting, structure_block

Minecraft 16w20a, Minecraft 1.10 Pre-Release 2, Minecraft 1.10.2, Minecraft 16w32a, Minecraft 16w32b, ..., 24w11a, 1.20.6, 1.21 Pre-Release 4, 25w04a, 1.21.5 Release Candidate 2

Retrieved