PaperMC / Paper

The most widely used, high performance Minecraft server that aims to fix gameplay and mechanics inconsistencies
https://papermc.io/
Other
10.04k stars 2.34k forks source link

The Item frame outside the worldborder drops abnormally #9805

Closed MineSunshineone closed 11 months ago

MineSunshineone commented 1 year ago

Expected behavior

same as vanilla the item frame does not drop

Observed/Actual behavior

spigot same as vanilla

all of the paper fork has the problem.

when you let worldboder behand the item frame, it will drop without reason. 93C50C369CF458D846436F10A04F0988

Steps/models to reproduce

1.put a item frame 2.move world border behand item frame 3.wait

Plugin and Datapack List

datapack list [21:23:29 INFO]: There are 6 data pack(s) enabled: [vanilla (built-in)], [trade_rebalance (feature)], [file/Structory_1.20_v1.3.3.zip (world)], [file/Terralith_1.20_v2.4.6.zip (world)], [file/XKendermanFix.zip (world)], [file/bukkit (world)]

plugins [21:24:01 INFO]: Server Plugins (2): [21:24:01 INFO]: Bukkit Plugins: [21:24:01 INFO]: - Chunky, FreedomChat

Paper version

version [21:24:18 INFO]: Checking version, please wait... [21:24:21 INFO]: This server is running Paper version git-Paper-217 (MC: 1.20.2) (Implementing API version 1.20.2-R0.1-SNAPSHOT) (Git: cfe311d) You are running the latest version

Other

No response

Hydrostic commented 1 year ago

Some ideas in net.minecraft.world.entity.decoration.ItemFrame#survives

 @Override
    public boolean survives() {
        if (this.fixed) {
            return true;
        } else if (!this.level().noCollision((Entity) this)) {
            return false;
        } else {
            BlockState iblockdata = this.level().getBlockState(this.pos.relative(this.direction.getOpposite()));

            return !iblockdata.isSolid() && (!this.direction.getAxis().isHorizontal() || !DiodeBlock.isDiode(iblockdata)) ? false : this.level().getEntities((Entity) this, this.getBoundingBox(), ItemFrame.HANGING_ENTITY).isEmpty();
        }
    }

the itemframe will detect whether itself collides with other items by calling noCollision, but in net.minecraft.world.level.Level#noCollision(Entity, AABB), which has been modified by paper, hasn't consider the situation that itemframe is outside the world border and directly call the func getCollisionsForBlocksOrWorldBorder, which return false when entity is outside the world border

// Paper start - Prevent armor stands from doing entity lookups
    @Override
    public boolean noCollision(@Nullable Entity entity, AABB box) {
        if (entity instanceof net.minecraft.world.entity.decoration.ArmorStand && !entity.level().paperConfig().entities.armorStands.doCollisionEntityLookups) return false;
        // Paper start - optimise collisions
        int flags = io.papermc.paper.util.CollisionUtil.COLLISION_FLAG_CHECK_ONLY;
        if (entity != null) {
            flags |= io.papermc.paper.util.CollisionUtil.COLLISION_FLAG_CHECK_BORDER;
        }
        if (io.papermc.paper.util.CollisionUtil.getCollisionsForBlocksOrWorldBorder(this, entity, box, null, null, flags, null)) {
            return false;
        }

        return !io.papermc.paper.util.CollisionUtil.getEntityHardCollisions(this, entity, box, null, flags, null);
        // Paper end - optimise collisions
    }
    // Paper end
Lulu13022002 commented 11 months ago

This has been mitigated by https://github.com/PaperMC/Paper/commit/0b952981e6e96157d2cea8322c04c0f69965f2bf. The border edge now exists on Paper however there's still some issues especially with the collide of the edge. The item frame should not drop if placed at the border block (horizontally) with a border of size 10 and then shrinking to 9. And the player is rollback when the half size of the border is not an integer. This is essentially because there's no voxelshape intersection like in vanilla. And in this case the voxelshape of the world border is rounded depending on the side.