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,109 @@ 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 ().getPositionMatrix ();
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 ().getPositionMatrix ();
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 abstractClientPlayerEntity ) {
119+ return !abstractClientPlayerEntity .isMainPlayer () && !abstractClientPlayerEntity .isInvisibleTo (MinecraftClient .getInstance ().player );
96120 }
121+
122+ return false ;
97123 }
98124
99- private static void drawHeart (Matrix4f model , VertexConsumer vertexConsumer , float x , int type ){
100- float minU = 16F / 256F + type * 9F / 256F ;
125+ private static void drawHeart (Matrix4f model , VertexConsumer vertexConsumer , float x , float y , float z , HeartType type ){
126+ float minU = type . u / 256F ;
101127 float maxU = minU + 9F / 256F ;
102- float minV = 0 ;
128+ float minV = type . v / 256F ;
103129 float maxV = minV + 9F / 256F ;
104130
105131 float heartSize = 9F ;
106132
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 );
133+ drawVertex (model , vertexConsumer , x , y - heartSize , z , minU , maxV );
134+ drawVertex (model , vertexConsumer , x - heartSize , y - heartSize , z , maxU , maxV );
135+ drawVertex (model , vertexConsumer , x - heartSize , y , z , maxU , minV );
136+ drawVertex (model , vertexConsumer , x , y , z , minU , minV );
111137 }
112138
113139 private static void drawVertex (Matrix4f model , VertexConsumer vertices , float x , float y , float z , float u , float v ) {
0 commit comments