11package me.andrew.healthindicators.mixin;
22
33import com.mojang.blaze3d.systems.RenderSystem;
4- import me.andrew.healthindicators.HealthIndicatorsMod;
4+ import me.andrew.healthindicators.Config;
5+ import me.andrew.healthindicators.HeartType;
6+ import net.minecraft.client.MinecraftClient;
57import net.minecraft.client.gui.DrawableHelper;
68import net.minecraft.client.network.AbstractClientPlayerEntity;
79import net.minecraft.client.render.*;
1012import net.minecraft.client.render.entity.PlayerEntityRenderer;
1113import net.minecraft.client.render.entity.model.PlayerEntityModel;
1214import net.minecraft.client.util.math.MatrixStack;
15+ import net.minecraft.entity.Entity;
1316import net.minecraft.util.math.MathHelper;
1417import net.minecraft.util.math.Matrix4f;
1518import org.spongepowered.asm.mixin.Mixin;
@@ -28,86 +31,110 @@ public PlayerEntityRendererMixin(EntityRendererFactory.Context ctx, PlayerEntity
2831 at = @At("RETURN")
2932 )
3033 public void renderHealth(AbstractClientPlayerEntity abstractClientPlayerEntity, float f, float g, MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int light, CallbackInfo ci) {
31- if (HealthIndicatorsMod.toggled && !abstractClientPlayerEntity.isMainPlayer()) {
32- matrixStack.push();
34+ if (!Config.getRenderingEnabled()) return;
3335
34- double d = this.dispatcher.getSquaredDistanceToCamera( abstractClientPlayerEntity);
36+ if (!shouldRenderHeartsForEntity( abstractClientPlayerEntity)) return ;
3537
36- matrixStack.translate(0, abstractClientPlayerEntity.getHeight() + 0.5f, 0);
37- if (this.hasLabel(abstractClientPlayerEntity) && d <= 4096.0) {
38+ matrixStack.push();
39+
40+ double d = this.dispatcher.getSquaredDistanceToCamera(abstractClientPlayerEntity);
41+
42+ matrixStack.translate(0, abstractClientPlayerEntity.getHeight() + 0.5f, 0);
43+ if (this.hasLabel(abstractClientPlayerEntity) && d <= 4096.0) {
44+ matrixStack.translate(0.0D, 9.0F * 1.15F * 0.025F, 0.0D);
45+ if (d < 100.0 && abstractClientPlayerEntity.getScoreboard().getObjectiveForSlot(2) != null) {
3846 matrixStack.translate(0.0D, 9.0F * 1.15F * 0.025F, 0.0D);
39- if (d < 100.0 && abstractClientPlayerEntity.getScoreboard().getObjectiveForSlot(2) != null) {
40- matrixStack.translate(0.0D, 9.0F * 1.15F * 0.025F, 0.0D);
41- }
4247 }
48+ }
4349
44- matrixStack.multiply(this.dispatcher.getRotation());
50+ matrixStack.multiply(this.dispatcher.getRotation());
4551// matrixStack.multiply(Vector3f.POSITIVE_X.getDegreesQuaternion(mc.gameRenderer.getCamera().getPitch()));
4652
47- float pixelSize = 0.025F;
48- matrixStack.scale(pixelSize, pixelSize, pixelSize);
49-
50- Tessellator tessellator = Tessellator.getInstance();
51- BufferBuilder vertexConsumer = tessellator.getBuffer();
52-
53- vertexConsumer.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE);
54- RenderSystem.setShader(GameRenderer::getPositionTexShader);
55- RenderSystem.setShaderTexture(0, DrawableHelper.GUI_ICONS_TEXTURE);
56- RenderSystem.enableDepthTest();
57-
58- Matrix4f model = matrixStack.peek().getModel();
59-
60- int healthRed = MathHelper.ceil(abstractClientPlayerEntity.getHealth());
61- int maxHealth = MathHelper.ceil(abstractClientPlayerEntity.getMaxHealth());
62- int healthYellow = MathHelper.ceil(abstractClientPlayerEntity.getAbsorptionAmount());
63-
64- int heartsRed = MathHelper.ceil(healthRed / 2.0f);
65- boolean lastRedHalf = (healthRed & 1) == 1;
66- int heartsNormal = MathHelper.ceil(maxHealth / 2.0f);
67- int heartsYellow = MathHelper.ceil(healthYellow / 2.0f);
68- boolean lastYellowHalf = (healthYellow & 1) == 1;
69- int heartsTotal = heartsNormal + heartsYellow;
70-
71- int pixelsTotal = heartsTotal * 8 + 1;
72- float maxX = pixelsTotal / 2.0f;
73- for (int heart = 0; heart < heartsTotal; heart++){
74- float x = maxX - heart * 8;
75- drawHeart(model, vertexConsumer, x, 0);
76- // Offset in the gui icons texture in hearts
77- // 0 - empty, 2 - red, 8 - yellow, +1 for half
78- int type;
79- if (heart < heartsRed) {
80- type = 2 * 2;
81- if (heart == heartsRed - 1 && lastRedHalf) type += 1;
82- } else if (heart < heartsNormal) {
83- type = 0;
84- } else {
85- type = 8 * 2;
86- if(heart == heartsTotal - 1 && lastYellowHalf) type += 1;
53+ float pixelSize = 0.025F;
54+ matrixStack.scale(pixelSize, pixelSize, pixelSize);
55+ matrixStack.translate(0, Config.getHeartOffset(), 0);
56+
57+ Tessellator tessellator = Tessellator.getInstance();
58+ BufferBuilder vertexConsumer = tessellator.getBuffer();
59+
60+ vertexConsumer.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE);
61+ RenderSystem.setShader(GameRenderer::getPositionTexShader);
62+ RenderSystem.setShaderTexture(0, DrawableHelper.GUI_ICONS_TEXTURE);
63+ RenderSystem.enableDepthTest();
64+
65+ Matrix4f model = matrixStack.peek().getModel();
66+
67+ int healthRed = MathHelper.ceil(abstractClientPlayerEntity.getHealth());
68+ int maxHealth = MathHelper.ceil(abstractClientPlayerEntity.getMaxHealth());
69+ int healthYellow = MathHelper.ceil(abstractClientPlayerEntity.getAbsorptionAmount());
70+
71+ int heartsRed = MathHelper.ceil(healthRed / 2.0f);
72+ boolean lastRedHalf = (healthRed & 1) == 1;
73+ int heartsNormal = MathHelper.ceil(maxHealth / 2.0f);
74+ int heartsYellow = MathHelper.ceil(healthYellow / 2.0f);
75+ boolean lastYellowHalf = (healthYellow & 1) == 1;
76+ int heartsTotal = heartsNormal + heartsYellow;
77+
78+ int heartsPerRow = Config.getHeartStackingEnabled() ? 10 : heartsTotal;
79+ int rowsTotal = (heartsTotal + heartsPerRow - 1) / heartsPerRow;
80+ int rowOffset = Math.max(10 - (rowsTotal - 2), 3);
81+
82+ int pixelsTotal = Math.min(heartsTotal, heartsPerRow) * 8 + 1;
83+ float maxX = pixelsTotal / 2.0f;
84+ for (int heart = 0; heart < heartsTotal; heart++){
85+ int row = heart / heartsPerRow;
86+ int col = heart % heartsPerRow;
87+
88+ float x = maxX - col * 8;
89+ float y = row * rowOffset;
90+ float z = row * 0.01F;
91+ drawHeart(model, vertexConsumer, x, y, z, HeartType.EMPTY);
92+
93+ HeartType type;
94+ if (heart < heartsRed) {
95+ type = HeartType.RED_FULL;
96+ if (heart == heartsRed - 1 && lastRedHalf) {
97+ type = HeartType.RED_HALF;
8798 }
88- if (type != 0) {
89- drawHeart(model, vertexConsumer, x, type);
99+ } else if (heart < heartsNormal) {
100+ type = HeartType.EMPTY;
101+ } else {
102+ type = HeartType.YELLOW_FULL;
103+ if (heart == heartsTotal - 1 && lastYellowHalf) {
104+ type = HeartType.YELLOW_HALF;
90105 }
91106 }
107+ if (type != HeartType.EMPTY) {
108+ drawHeart(model, vertexConsumer, x, y, z, type);
109+ }
110+ }
111+
112+ tessellator.draw();
92113
93- tessellator.draw();
114+ matrixStack.pop();
115+ }
94116
95- matrixStack.pop();
117+ private static boolean shouldRenderHeartsForEntity(Entity entity) {
118+ if (entity instanceof AbstractClientPlayerEntity) {
119+ AbstractClientPlayerEntity abstractClientPlayerEntity = (AbstractClientPlayerEntity) entity;
120+ return !abstractClientPlayerEntity.isMainPlayer() && !abstractClientPlayerEntity.isInvisibleTo(MinecraftClient.getInstance().player);
96121 }
122+
123+ return false;
97124 }
98125
99- private static void drawHeart(Matrix4f model, VertexConsumer vertexConsumer, float x, int type){
100- float minU = 16F / 256F + type * 9F / 256F;
126+ private static void drawHeart(Matrix4f model, VertexConsumer vertexConsumer, float x, float y, float z, HeartType type){
127+ float minU = type.u / 256F;
101128 float maxU = minU + 9F / 256F;
102- float minV = 0 ;
129+ float minV = type.v / 256F ;
103130 float maxV = minV + 9F / 256F;
104131
105132 float heartSize = 9F;
106133
107- drawVertex(model, vertexConsumer, x, 0F - heartSize, 0F , minU, maxV);
108- drawVertex(model, vertexConsumer, x - heartSize, 0F - heartSize, 0F , maxU, maxV);
109- drawVertex(model, vertexConsumer, x - heartSize, 0F, 0F , maxU, minV);
110- drawVertex(model, vertexConsumer, x, 0F, 0F , minU, minV);
134+ drawVertex(model, vertexConsumer, x, y - heartSize, z , minU, maxV);
135+ drawVertex(model, vertexConsumer, x - heartSize, y - heartSize, z , maxU, maxV);
136+ drawVertex(model, vertexConsumer, x - heartSize, y, z , maxU, minV);
137+ drawVertex(model, vertexConsumer, x, y, z , minU, minV);
111138 }
112139
113140 private static void drawVertex(Matrix4f model, VertexConsumer vertices, float x, float y, float z, float u, float v) {
0 commit comments