-
Bug
-
Resolution: Unresolved
-
None
-
Minecraft 1.11.2, Minecraft 17w06a, Minecraft 1.12.1, Minecraft 1.12.2, Minecraft 18w22c, Minecraft 1.13.1, Minecraft 1.13.2, Minecraft 19w04b, Minecraft 19w05a, 1.14.4, 1.15.2, 20w21a, 20w22a, 1.16.2, 20w46a, 1.16.5, 21w06a, 21w08b, 21w17a, 1.17, 1.17.1, 1.18.1, 1.19.2, 22w42a, 1.21
-
Confirmed
-
(Unassigned)
The bug
Opening shulker boxes move entities which are inside them. Expected would be that they only move entities which are next to them.
How to reproduce
- Summon an entity which is taller than two blocks
/summon wither_skeleton ~2 ~ ~ {NoAI:1b,Invulnerable:1b}
- Place a shulker box at the upper block
/setblock ~2 ~1 ~ white_shulker_box
- Open the shulker box
→ You will see that the entity was moved upwards
Code analysis
Based on 1.11.2 decompiled using MCP 9.35 rc1
The problem is that the method net.minecraft.tileentity.TileEntityShulkerBox.moveCollidedEntities() searches in a bounding box beginning outside the 1*1*1 cube of the shulker box instead of at the last progress and that it moves entities whose bounding box starts behind this bounding box.
The following shows a proof of concept fix which can possibly be improved performance-wise.
private AxisAlignedBB getTopBoundingBox(EnumFacing p_190588_1_) { // Comment: Replaced this to return a bounding box between progressOld and progress (= area in which entities should be moved) // EnumFacing enumfacing = p_190588_1_.getOpposite(); // return this.getBoundingBox(p_190588_1_).contract((double)enumfacing.getFrontOffsetX(), (double)enumfacing.getFrontOffsetY(), (double)enumfacing.getFrontOffsetZ()); return new AxisAlignedBB( p_190588_1_.getFrontOffsetX() > 0 ? 1 + 0.5F * this.progress: 0 - (p_190588_1_.getFrontOffsetX() < 0 ? 0.5F * this.progressOld : 0), p_190588_1_.getFrontOffsetY() > 0 ? 1 + 0.5F * this.progress: 0 - (p_190588_1_.getFrontOffsetY() < 0 ? 0.5F * this.progressOld : 0), p_190588_1_.getFrontOffsetZ() > 0 ? 1 + 0.5F * this.progress: 0 - (p_190588_1_.getFrontOffsetZ() < 0 ? 0.5F * this.progressOld : 0), p_190588_1_.getFrontOffsetX() < 0 ? 0 - 0.5F * this.progress: 1 + (p_190588_1_.getFrontOffsetX() > 0 ? 0.5F * this.progressOld : 0), p_190588_1_.getFrontOffsetY() < 0 ? 0 - 0.5F * this.progress: 1 + (p_190588_1_.getFrontOffsetX() > 0 ? 0.5F * this.progressOld : 0), p_190588_1_.getFrontOffsetZ() < 0 ? 0 - 0.5F * this.progress: 1 + (p_190588_1_.getFrontOffsetX() > 0 ? 0.5F * this.progressOld : 0) ); } private void moveCollidedEntities() { IBlockState iblockstate = this.world.getBlockState(this.getPos()); if (iblockstate.getBlock() instanceof BlockShulkerBox) { EnumFacing enumfacing = (EnumFacing)iblockstate.getValue(BlockShulkerBox.FACING); AxisAlignedBB axisalignedbb = this.getTopBoundingBox(enumfacing).offset(this.pos); List<Entity> list = this.world.getEntitiesWithinAABBExcludingEntity((Entity)null, axisalignedbb); if (!list.isEmpty()) { for (int i = 0; i < list.size(); ++i) { Entity entity = (Entity)list.get(i); // Comment: Change start // if (entity.getPushReaction() != EnumPushReaction.IGNORE) boolean shouldMoveEntity = false; AxisAlignedBB entityBoundingBox = entity.getEntityBoundingBox(); if (enumfacing.getFrontOffsetX() > 0) { if (entityBoundingBox.minX >= axisalignedbb.minX) { shouldMoveEntity = true; } } else if (enumfacing.getFrontOffsetX() < 0) { if (entityBoundingBox.minX <= axisalignedbb.minX) { shouldMoveEntity = true; } } else if (enumfacing.getFrontOffsetY() > 0) { if (entityBoundingBox.minY >= axisalignedbb.minY) { shouldMoveEntity = true; } } else if (enumfacing.getFrontOffsetY() < 0) { if (entityBoundingBox.minY <= axisalignedbb.minY) { shouldMoveEntity = true; } } else if (enumfacing.getFrontOffsetZ() > 0) { if (entityBoundingBox.minZ >= axisalignedbb.minZ) { shouldMoveEntity = true; } } else if (enumfacing.getFrontOffsetZ() < 0) { if (entityBoundingBox.minZ <= axisalignedbb.minZ) { shouldMoveEntity = true; } } if (entity.getPushReaction() != EnumPushReaction.IGNORE && shouldMoveEntity) // Comment: Change end { // ... } } } } }