Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HealthTags improvements #801

Open
wants to merge 24 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
92a7c79
HealthTags for mobs
ThisTestUser Mar 17, 2023
36c1044
Update RenderUtils.java
ThisTestUser Mar 17, 2023
1082575
Merge branch 'master' into mobhealthtags
Alexander01998 Mar 21, 2023
d5cd0eb
Display max health for players option
ThisTestUser May 28, 2023
686526d
Unlimited range for mob health tags
ThisTestUser May 28, 2023
f0ba058
Fix range overflowing
ThisTestUser May 28, 2023
edd26ae
Use double for height offset
ThisTestUser Jun 5, 2023
ae5ee29
Clean up
ThisTestUser Jun 5, 2023
cd0ca73
Cleanup
ThisTestUser Jun 7, 2023
cda75f9
Merge branch 'master' into mobhealthtags
ThisTestUser Oct 22, 2023
87955b1
Merge branch 'master' into pr/ThisTestUser/801
Alexander01998 Dec 22, 2023
c1d374b
Clean up
Alexander01998 Dec 22, 2023
5a9db98
Let NameTags handle the unlimited range option
Alexander01998 Dec 22, 2023
5307b2a
Refactor max health setting and display logic
Alexander01998 Dec 23, 2023
2c3cc80
Fix inconsistent number formatting
Alexander01998 Dec 23, 2023
684692f
Replace rounding checkbox with precision slider
Alexander01998 Dec 23, 2023
8c90791
Add validation for minimum value in RoundingPrecisionSetting
Alexander01998 Dec 23, 2023
92703c5
Remove unused hasMobHealthTags() method for now
Alexander01998 Dec 23, 2023
5cb8d27
Partially refactor renderTag() method
Alexander01998 Dec 26, 2023
ed1cb1f
Year update
ThisTestUser Jan 2, 2024
31022d1
Merge branch 'master' into mobhealthtags
ThisTestUser Mar 4, 2024
f9c5533
Merge branch 'master' into mobhealthtags
Alexander01998 Apr 4, 2024
305f0b6
Merge branch 'master' into mobhealthtags
ThisTestUser Oct 1, 2024
93149e4
Fix issues with mobhealthtags
ThisTestUser Oct 22, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 91 additions & 7 deletions src/main/java/net/wurstclient/hacks/HealthTagsHack.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,48 +7,132 @@
*/
package net.wurstclient.hacks;

import java.text.DecimalFormat;

import net.minecraft.client.render.Tessellator;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.mob.MobEntity;
import net.minecraft.text.MutableText;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import net.wurstclient.Category;
import net.wurstclient.SearchTags;
import net.wurstclient.events.RenderListener;
import net.wurstclient.hack.Hack;
import net.wurstclient.settings.CheckboxSetting;
import net.wurstclient.util.RenderUtils;

@SearchTags({"health tags"})
public final class HealthTagsHack extends Hack
public final class HealthTagsHack extends Hack implements RenderListener
{
private static final DecimalFormat DF = new DecimalFormat("0.##");

private final CheckboxSetting mobs = new CheckboxSetting("Mobs",
"Displays health tags above mobs also.", false);

private final CheckboxSetting unlimitedRange = new CheckboxSetting(
"Unlimited range", "Displays mob health tags at any distance.", false);

private final CheckboxSetting max =
new CheckboxSetting("Display max health for players", false);

private final CheckboxSetting round =
new CheckboxSetting("Round health", true);

public HealthTagsHack()
{
super("HealthTags");
setCategory(Category.RENDER);
addSetting(mobs);
addSetting(unlimitedRange);
addSetting(max);
addSetting(round);
}

@Override
public void onEnable()
{
EVENTS.add(RenderListener.class, this);
}

@Override
public void onDisable()
{
EVENTS.remove(RenderListener.class, this);
}

@Override
public void onRender(MatrixStack matrixStack, float partialTicks)
{
if(!mobs.isChecked())
return;

VertexConsumerProvider.Immediate immediate = VertexConsumerProvider
.immediate(Tessellator.getInstance().getBuffer());

for(Entity e : MC.world.getEntities())
if(e instanceof MobEntity entity)
{
String health = round.isChecked()
? Integer.toString((int)entity.getHealth())
: DF.format(entity.getHealth());

String maxHealth = round.isChecked()
? Integer.toString((int)entity.getMaxHealth())
: DF.format(entity.getMaxHealth());

Text text = Text.literal(health + "/" + maxHealth).formatted(
getColor(entity.getHealth(), entity.getMaxHealth()));

RenderUtils.renderTag(matrixStack, text, entity, immediate,
0xffffff, !entity.hasCustomName() ? 0.5 : 1,
unlimitedRange.isChecked() ? 1000 : 75, partialTicks);
}

immediate.draw();
}

public Text addHealth(LivingEntity entity, Text nametag)
{
if(!isEnabled())
return nametag;

int health = (int)entity.getHealth();
String health =
round.isChecked() ? Integer.toString((int)entity.getHealth())
: DF.format(entity.getHealth());

String maxHealth =
round.isChecked() ? Integer.toString((int)entity.getMaxHealth())
: DF.format(entity.getMaxHealth());

MutableText formattedHealth = Text.literal(" ")
.append(Integer.toString(health)).formatted(getColor(health));
.append(max.isChecked() ? health + "/" + maxHealth : health)
.formatted(getColor(entity.getHealth(), entity.getMaxHealth()));

return ((MutableText)nametag).append(formattedHealth);
}

private Formatting getColor(int health)
private Formatting getColor(float health, float maxHealth)
{
if(health <= 5)
if(health <= maxHealth * 0.25)
return Formatting.DARK_RED;

if(health <= 10)
if(health <= maxHealth * 0.5)
return Formatting.GOLD;

if(health <= 15)
if(health <= maxHealth * 0.75)
return Formatting.YELLOW;

return Formatting.GREEN;
}

public boolean hasMobHealthTags()
{
return isEnabled() && mobs.isChecked();
}

// See EntityRendererMixin.onRenderLabelIfPresent()
}
61 changes: 54 additions & 7 deletions src/main/java/net/wurstclient/util/RenderUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,25 @@
import com.mojang.blaze3d.systems.RenderSystem;

import net.minecraft.block.Blocks;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.font.TextRenderer.TextLayerType;
import net.minecraft.client.gl.VertexBuffer;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.render.BufferBuilder;
import net.minecraft.client.render.*;
import net.minecraft.client.render.BufferBuilder.BuiltBuffer;
import net.minecraft.client.render.Camera;
import net.minecraft.client.render.DiffuseLighting;
import net.minecraft.client.render.GameRenderer;
import net.minecraft.client.render.Tessellator;
import net.minecraft.client.render.VertexFormat;
import net.minecraft.client.render.VertexFormats;
import net.minecraft.client.render.entity.EntityRenderDispatcher;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.Entity;
import net.minecraft.item.ItemStack;
import net.minecraft.text.Text;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.chunk.Chunk;
import net.wurstclient.WurstClient;
import net.wurstclient.hacks.NameTagsHack;
Alexander01998 marked this conversation as resolved.
Show resolved Hide resolved

public enum RenderUtils
{
Expand Down Expand Up @@ -893,4 +893,51 @@ public static void drawItem(DrawContext context, ItemStack stack, int x,

RenderSystem.setShaderColor(1, 1, 1, 1);
}

public static void renderTag(MatrixStack matrixStack, Text text,
Entity entity, VertexConsumerProvider provider, int color,
double height, int limit, float partialTicks)
{
NameTagsHack nameTagsHack = WurstClient.INSTANCE.getHax().nameTagsHack;
MinecraftClient MC = MinecraftClient.getInstance();
EntityRenderDispatcher dispatcher = MC.getEntityRenderDispatcher();
double dist = dispatcher.getSquaredDistanceToCamera(entity);
if(dist > limit * limit)
return;
matrixStack.push();

RenderUtils.applyCameraRotationOnly();
Vec3d camPos = RenderUtils.getCameraPos();
matrixStack.translate(
-camPos.x + entity.prevX
+ (entity.getX() - entity.prevX) * partialTicks,
-camPos.y + entity.prevY
+ (entity.getY() - entity.prevY) * partialTicks
+ entity.getHeight() + height,
-camPos.z + entity.prevZ
+ (entity.getZ() - entity.prevZ) * partialTicks);

matrixStack.multiply(dispatcher.getRotation());

float scale = 0.025F;
if(nameTagsHack.isEnabled())
{
double distance = MC.player.distanceTo(entity);

if(distance > 10)
scale *= distance / 10;
}

matrixStack.scale(-scale, -scale, scale);

Matrix4f matrix = matrixStack.peek().getPositionMatrix();
float bgOpacity = MC.options.getTextBackgroundOpacity(0.25f);
int bgColor = (int)(bgOpacity * 255.0f) << 24;
int labelX = -MC.textRenderer.getWidth(text) / 2;
MC.textRenderer.draw(text, labelX, 0, color, false, matrix, provider,
TextLayerType.NORMAL, bgColor, 15728880);
MC.textRenderer.draw(text, labelX, 0, -1, false, matrix, provider,
TextLayerType.SEE_THROUGH, 0, 15728880);
matrixStack.pop();
}
}