mojira.dev

AjaxGb

Assigned

No issues.

Reported

View all
MC-176038 Lodestone compasses in containers do not become unlinked when lodestone is broken Duplicate MC-176029 Right clicking a lodestone with a stack of compasses converts the whole stack Fixed MC-175514 Villager Gossips still use old UUID NBT format (TargetMost and TargetLeast) Fixed MC-173476 Piercing arrows pass through level+1 entities, vanish without damage when hitting level+2 Confirmed MC-152737 Summoned falling_block entities will incorrectly delete client-side blocks Duplicate MC-146881 Sleeping villagers have a much smaller render radius than normal Confirmed MC-138426 Not all CustomModelData values can be checked by predicate, due to floating point imprecision Won't Fix MC-138299 /loot mine and /loot kill ignore container contents, armor items, and other non-loot-table drops Confirmed MC-137427 Advancements treat the player as the "direct_entity" source of primed TNT damage Confirmed MC-126809 minecraft:exploration_map loot table function only works on block containers Fixed

Comments

Can confirm in 24w06a.

@@unknown Eight-year-old comment, but it seems to me that the "correct" solution would be to do attribute application in two passes. First, go over all the slots as you described, but only process item removals. Then go over all the slots a second time and process all the item additions.

Did some digging on this. Turns out Striders set their NoGravity flag to true when they're in lava and to false when they aren't; that's how they float. Certain things can make the flag get stuck on true. A consistent and easy one is just saving and quitting while the Strider is standing in lava. After you reopen the world, the Strider is stuck floating at their current height forever. The flag being stuck like this also prevents them from walking up blocks, which they can normally do.

This also relates to MC-176203, as the NoGravity flag prevents levitation. Striders probably shouldn't be using that flag; it's mostly intended for command use only.

@violine1101 I actually don't think that's a duplicate. That bug is about how, when the lodestone is broken, the compass is still a Lodestone Compass, just a Lodestone Compass that points to nothing. This bug is about how, when the lodestone is broken, compasses in containers won't notice at all, and will continue to point to the lodestone's old location until they are placed back into the player's inventory.

Confirmed for both 1.15.2 and 20w07a.

 I was unable to reproduce in 1.15.2. Seems to be resolved.

Confirmed for 1.14.4 and 19w41a.

I suspect that this is happening because villagers have a much smaller hitbox while sleeping.

Confirmed for 19w04b.

Confirmed for 18w32a, with the upper limit of distance= in place of r=. Setting only the lower limit has no effect, so

distance=1000000..

will not trigger the bug, but any of

distance=1000000
distance=..1000000

will.

@Cody
It's a block tag. It can be set with datapacks.

Confirmed for 1.12.2 and 1.13-pre5.

Confirmed for 18w16a.

Confirmed for 1.12-pre5.

So does that mean that there's now a maximum chain length? If so, what is it?

@unknown Thanks for the correction.

I did a code analysis with a suggested solution on the related bug MC-73916. The problem and solution are the same for this bug; please link in the description.

https://bugs.mojang.com/browse/MC-73916?focusedCommentId=345453&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-345453

Time for some code analysis! This is based on MCP for 1.10.2. Please link this in the description.

So the reason for both this and MC-54932 is the same. As @unknown said, this does not affect Player-only selectors in most cases; if the players make up 1/16 or more of the loaded entities, the bug will occur.

The bottleneck is the method getEntitiesWithinAABB, which is used for both radius- and region-based selection of entities (and players in the 1/16 case mentioned above). It loops through all chunks within the bounding box and, if they are loaded, adds any of their entities that fall within the bounding box.

public <T extends Entity> List<T> getEntitiesWithinAABB(Class <? extends T > clazz, AxisAlignedBB aabb, @Nullable Predicate <? super T > filter)
{
    int i = MathHelper.floor_double((aabb.minX - MAX_ENTITY_RADIUS) / 16.0D);
    int j = MathHelper.ceiling_double_int((aabb.maxX + MAX_ENTITY_RADIUS) / 16.0D);
    int k = MathHelper.floor_double((aabb.minZ - MAX_ENTITY_RADIUS) / 16.0D);
    int l = MathHelper.ceiling_double_int((aabb.maxZ + MAX_ENTITY_RADIUS) / 16.0D);
    List<T> list = Lists.<T>newArrayList();

    for (int i1 = i; i1 < j; ++i1)
    {
        for (int j1 = k; j1 < l; ++j1)
        {
            if (this.isChunkLoaded(i1, j1, true))
            {
                this.getChunkFromChunkCoords(i1, j1).getEntitiesOfTypeWithinAAAB(clazz, aabb, list, filter);
            }
        }
    }

    return list;
}

To solve the bug, the method must be able to quickly determine whether it will be more efficient to loop through all possible chunks in the area (and then check if they are loaded) or through all loaded chunks (and then check if they are in the area), and then to loop through the loaded chunks if that is the decision. Therefore I suggest adding two methods to IChunkProvider: getNumLoadedChunks() and iterLoadedChunks(), both of which should be trivial to implement.

The new method:

public <T extends Entity> List<T> getEntitiesWithinAABB(Class <? extends T > clazz, AxisAlignedBB aabb, @Nullable Predicate <? super T > filter)
{
    int i = MathHelper.floor_double((aabb.minX - MAX_ENTITY_RADIUS) / 16.0D);
    int j = MathHelper.ceiling_double_int((aabb.maxX + MAX_ENTITY_RADIUS) / 16.0D);
    int k = MathHelper.floor_double((aabb.minZ - MAX_ENTITY_RADIUS) / 16.0D);
    int l = MathHelper.ceiling_double_int((aabb.maxZ + MAX_ENTITY_RADIUS) / 16.0D);
    List<T> list = Lists.<T>newArrayList();
    
    int chunksInAABB = (j - i) * (l - k);
    
    if (chunksInAABB > this.chunkProvider.getNumLoadedChunks())
    {
        for (Chunk chunk : this.chunkProvider.iterLoadedChunks())
        {
            if (chunk.xPosition >= i && chunk.xPosition < j && chunk.zPosition >= k && chunk.zPosition < l)
            {
                chunk.getEntitiesOfTypeWithinAAAB(clazz, aabb, list, filter);
            }
        }
    }
    else
    {
        for (int i1 = i; i1 < j; ++i1)
        {
            for (int j1 = k; j1 < l; ++j1)
            {
                if (this.isChunkLoaded(i1, j1, true))
                {
                    this.getChunkFromChunkCoords(i1, j1).getEntitiesOfTypeWithinAAAB(clazz, aabb, list, filter);
                }
            }
        }
    }

    return list;
}

This way the function will have exactly the same input and output, but will never check more chunks than are actually loaded.

Load more comments