mojira.dev
MC-216985

Some entities don't bounce on a slime block when falling down into it

The bug

Tnt, Falling blocks, and Xp orbs (only those that I know of currently, might be more) don't bounce on slime blocks when falling into them. This is due to the order or events in the entities tick phase where the onGround tag perpetuates downward motion instead of upwards.

How to reproduce

  1. Place four slime blocks in a 2x2 pattern on the floor.

  2. Go in the middle of the 4 slime blocks and fly up 5 blocks

  3. Use the following command above the slime blocks

/summon minecraft:tnt ~ ~ ~ {fuse:100,Motion:[0.0,-9.0,0.0]}

→ ❌ It will not bounce

Code analysis

Using Fabric mapping 1.16.5

Here, we will look at the tnt entity for this example. We will start in the tick phase where it handles its motion and velocity as well as other important stuff not related to this ticket.  We will say that this entity is moving down in this example (negative velocity y). We are first going to go into the move method as that is called first:

public void tick() {
    REMOVED code as it was not needed
    this.move(MovementType.SELF, this.getVelocity());
    REMOVED code as it was not needed
    if (this.onGround) {
        this.setVelocity(this.getVelocity().multiply(0.7, -0.5, 0.7));
    }
    REMOVED code as it was not needed
}

In the move method of the Entity class:

public void move(MovementType type, Vec3d movement) {

    REMOVE code above as it was not needed

    BlockPos lv2 = this.getLandingPos();
    BlockState lv3 = this.world.getBlockState(lv2);

    REMOVED code here as it was not needed

    this.fall(lv.y, this.onGround, lv3, lv2);
    Vec3d lv4 = this.getVelocity();
    Block lv5 = lv3.getBlock();
    if (movement.y != lv.y) {
        lv5.onEntityLand(this.world, this);
    }

    REMOVED code here as it was not needed
}

In the move method, the entity will try to go to it's final location using the velocity supplied in the parameters. If the y position hits a block, movement.y != lv.y, will be set to true and call onEntityLand, supplying a block, which in this case, that is a slime block.

Now looking in the onEnitiyLand code

@Override
public void onEntityLand(BlockView world, Entity entity) {
    if (entity.bypassesLandingEffects()) {
        super.onEntityLand(world, entity);
    } else {
        this.bounce(entity);
    }
}

As the tnt can't bypassesLandingEffects, it will call this.bounce(entity).

Now looking at the bounce:

private void bounce(Entity entity) { 
   Vec3d lv = entity.getVelocity();
   if (lv.y < 0.0) {
     double d = entity instanceof LivingEntity ? 1.0 : 0.8;
     entity.setVelocity(lv.x, -lv.y * d, lv.z); 
   } 
}

As the tnt is being shot down, it has negative y velocity. Thus, the entities velocity will be set to a positive as it has its sign changed by -lv.y

As the move method is now done, we are back in the tick method

public void tick() { REMOVED code as it was not needed  
 this.move(MovementType.SELF, this.getVelocity());
 REMOVED code as it was not needed 
 if (this.onGround) { 
     this.setVelocity(this.getVelocity().multiply(0.7, -0.5, 0.7)); 
 }
 REMOVED code as it was not needed
}

We came out of the move method with a positive velocity. Now, as it hit a block going down, the onGround check was set to true. As the onGround check was set to true, the y velocity will be multiplied by -0.5, thus making it negative. When the tick is called again, the slime blocks will just keep smacking into the slime block, thus never bouncing up.

Below is an MCP print statement to show the same thing above.

[Player268: Summoned new Primed TNT]
-9.04 before move in tick
-9.04 pre move
-9.04 Pre onLanded
-9.04 enter bounce
7.231999999999999 return from bounce
7.231999999999999 Post onlanded
7.231999999999999 Pre ground and stepping
7.231999999999999 post ground and stepping
7.231999999999999 post move
7.231999999999999 after move in tick
7.087359999999999 before ground in tick
-3.5436799999999997 after ground in tick

Solution

Like MC-207866

If an entity has collided with a slime block in the "bounce", set the OnGround tag to false. This may have unforeseen consequences, but I can't think of any as of now.

Linked issues

Attachments

Comments 10

Can confirm in 21w13a.

Can confirm in 1.17. Relates to MC-227382.

Can confirm in 1.17.1.

Can confirm in 1.18.1 and 22w06a.

Can confirm in 1.19.3 and 23w07a

Kyle Weber

(Unassigned)

Confirmed

Entities

1.16.5, 21w08b, 21w11a, 21w13a, 21w15a, ..., 1.19.4 Pre-release 1, 1.19.4, 23w14a, 1.20.1, 1.20.4

Retrieved