mojira.dev
MC-255835

Rideable mobs with max health of 1 don't show health bar

While I was messing around with horses, I summoned one in with 1 hp and I couldn't see the health bar appear and the hunger bar replaced it. This seems to work with all mobs that have a visual health bar when riding them.

To replicate this, summon a horse or any rideable mob with a max hp of 1 and ride them. You can use the following command to summon a tamed horse with 1 max hp.

/summon minecraft:horse ~ ~ ~ {SaddleItem:

{id:saddle,Count:1}

,Tame:1,Health:1,Attributes:[
{Name:"generic.max_health",Base:1f}]}

After you get on it, you won't see the health bar of the horse at all and if your in survival, you'll see the hunger bar in the place where the horse's health would be at. You can check this by spawning another horse with a spawn egg or find a natural generating one and see that when you mount it, you can see its health. This only seems to work if the mob has a max hp of 1 and not any other value like 2, 10, 37, etc.

 

*As I was writing this report, I saw that this behavior is related to how half hearts aren't rendered on rideable mobs at all, but if there is already a bug report out there about half hearts not rendering, this a different bug because I was mentioning how the health bar doesn't appear on any rideable mob like a pig or horse with a max hp of 1.

Linked issues

Attachments

Comments 2

Can confirm in 1.20.3 Release Candidate 1

Code Analysis

I believe the following methods are of interest. (1.20.5-rc2, decompiled with official mappings)

private void renderVehicleHealth(GuiGraphics $$0) {
        LivingEntity $$1 = this.getPlayerVehicleWithHealth();
        if ($$1 != null) {
            int $$2 = this.getVehicleMaxHearts($$1);
            if ($$2 != 0) {
                int $$3 = (int)Math.ceil((double)$$1.getHealth());
                this.minecraft.getProfiler().popPush("mountHealth");
                int $$4 = $$0.guiHeight() - 39;
                int $$5 = $$0.guiWidth() / 2 + 91;
                int $$6 = $$4;
                int $$7 = 0;
                RenderSystem.enableBlend();

                while ($$2 > 0) {
                    int $$8 = Math.min($$2, 10);
                    $$2 -= $$8;

                    for (int $$9 = 0; $$9 < $$8; $$9++) {
                        int $$10 = $$5 - $$9 * 8 - 9;
                        $$0.blitSprite(HEART_VEHICLE_CONTAINER_SPRITE, $$10, $$6, 9, 9);
                        if ($$9 * 2 + 1 + $$7 < $$3) {
                            $$0.blitSprite(HEART_VEHICLE_FULL_SPRITE, $$10, $$6, 9, 9);
                        }

                        if ($$9 * 2 + 1 + $$7 == $$3) {
                            $$0.blitSprite(HEART_VEHICLE_HALF_SPRITE, $$10, $$6, 9, 9);
                        }
                    }

                    $$6 -= 10;
                    $$7 += 20;
                }

                RenderSystem.disableBlend();
            }
        }
    }

private int getVehicleMaxHearts(@Nullable LivingEntity $$0) {
    if ($$0 != null && $$0.showVehicleHealth()) {
        float $$1 = $$0.getMaxHealth();
        int $$2 = (int)($$1 + 0.5F) / 2;
        if ($$2 > 30) {
            $$2 = 30;
        }

        return $$2;
    } else {
        return 0;
    }
}

If a vehicle has a max health of 1, (1 + 0.5) / 2 = 0.75, which gets truncated to 0 when cast to an int. Since a return value of 0 means the vehicle should display its health, the health bar is not shown.

matthewdog6

(Unassigned)

Confirmed

Platform

Low

UI

1.19.2, 22w42a, 22w43a, 22w44a, 22w45a, ..., 1.20.6, 1.21 Pre-Release 1, 1.21 Pre-Release 4, 1.21, 1.21 Release Candidate 1

Retrieved