Skip to content

Commit 5e3d00e

Browse files
committed
Updated MobESP
1 parent 2b88079 commit 5e3d00e

1 file changed

Lines changed: 131 additions & 0 deletions

File tree

src/main/java/net/wurstclient/hacks/MobEspHack.java

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@
3838
import net.wurstclient.util.RenderUtils;
3939
import net.wurstclient.util.RenderUtils.ColoredBox;
4040
import net.wurstclient.util.RenderUtils.ColoredPoint;
41+
import com.mojang.math.Axis;
42+
import net.minecraft.client.gui.Font;
43+
import net.minecraft.resources.ResourceKey;
44+
import net.minecraft.world.entity.npc.villager.Villager;
45+
import net.minecraft.world.entity.npc.villager.VillagerProfession;
46+
import net.minecraft.world.phys.Vec3;
4147

4248
@SearchTags({"mob esp", "MobTracers", "mob tracers"})
4349
public final class MobEspHack extends Hack implements UpdateListener,
@@ -102,6 +108,18 @@ public final class MobEspHack extends Hack implements UpdateListener,
102108
"Appends the number of detected mobs to this hack's entry in the HackList.",
103109
false);
104110

111+
// Villager professions label
112+
private final CheckboxSetting showVillagerProfessions =
113+
new CheckboxSetting("Show villager professions",
114+
"Displays the profession of villagers above their heads.", false);
115+
116+
// Range limiter
117+
private final CheckboxSetting rangeLimit = new CheckboxSetting(
118+
"Range limit", "Only show mobs within the configured range.", false);
119+
120+
private final SliderSetting espRange = new SliderSetting("ESP range", 64, 1,
121+
150, 1, SliderSetting.ValueDisplay.INTEGER.withSuffix(" blocks"));
122+
105123
// Above-ground filter
106124
private final CheckboxSetting onlyAboveGround =
107125
new CheckboxSetting("Above ground only",
@@ -143,6 +161,9 @@ public MobEspHack()
143161
addSetting(highlightShulkerProjectiles);
144162
addSetting(highlightWitherProjectiles);
145163
addSetting(showCountInHackList);
164+
addSetting(showVillagerProfessions);
165+
addSetting(rangeLimit);
166+
addSetting(espRange);
146167
}
147168

148169
@Override
@@ -187,6 +208,11 @@ public void onUpdate()
187208
if(onlyAboveGround.isChecked())
188209
stream = stream.filter(e -> e.getY() >= aboveGroundY.getValue());
189210

211+
// optionally limit range
212+
if(rangeLimit.isChecked())
213+
stream = stream
214+
.filter(e -> MC.player.distanceTo(e) <= espRange.getValue());
215+
190216
stream = entityFilters.applyTo(stream);
191217

192218
mobs.addAll(stream.collect(Collectors.toList()));
@@ -399,6 +425,111 @@ public void onRender(PoseStack matrixStack, float partialTicks)
399425
if(glowMode && highlightWitherProjectiles.isChecked()
400426
&& !witherSkulls.isEmpty())
401427
renderWitherProjectileFallback(matrixStack, partialTicks);
428+
429+
// render villager professions
430+
if(showVillagerProfessions.isChecked())
431+
renderVillagerProfessions(matrixStack, partialTicks);
432+
}
433+
434+
private static final double VANILLA_NAMETAG_DIST = 5.0;
435+
436+
private void renderVillagerProfessions(PoseStack matrices,
437+
float partialTicks)
438+
{
439+
Vec3 cam = RenderUtils.getCameraPos();
440+
var camEntity = MC.getCameraEntity();
441+
442+
for(LivingEntity e : mobs)
443+
{
444+
if(!(e instanceof Villager villager))
445+
continue;
446+
447+
// If vanilla is already showing the profession name tag
448+
// up close, skip the MobESP label to avoid duplicates.
449+
if(MC.player.distanceTo(villager) < VANILLA_NAMETAG_DIST)
450+
continue;
451+
452+
String profession = getVillagerProfessionName(villager);
453+
if(profession.isEmpty())
454+
continue;
455+
456+
// position above head
457+
AABB box = EntityUtils.getLerpedBox(e, partialTicks);
458+
double lx = box.getCenter().x;
459+
double ly = box.maxY + 0.6;
460+
double lz = box.getCenter().z;
461+
462+
float[] rgb = getColorRgb();
463+
int labelColor = RenderUtils.toIntColor(rgb, 0.9F);
464+
465+
matrices.pushPose();
466+
matrices.translate(lx - cam.x, ly - cam.y, lz - cam.z);
467+
if(camEntity != null)
468+
{
469+
matrices.mulPose(Axis.YP.rotationDegrees(-camEntity.getYRot()));
470+
matrices.mulPose(Axis.XP.rotationDegrees(camEntity.getXRot()));
471+
}
472+
matrices.mulPose(Axis.YP.rotationDegrees(180.0F));
473+
474+
double dist = MC.player.distanceTo(e);
475+
float scale = 0.025F * (float)Math.max(1.0, dist * 0.1);
476+
matrices.scale(scale, -scale, scale);
477+
478+
float w = MC.font.width(profession) / 2F;
479+
int baseAlpha = (labelColor >>> 24) & 0xFF;
480+
int bgAlpha = (int)Math
481+
.round(MC.options.getBackgroundOpacity(0.25F) * baseAlpha);
482+
int bg = bgAlpha << 24;
483+
int strokeColor =
484+
(Math.max(0, Math.min(255, baseAlpha)) << 24) | 0x000000;
485+
var matrix = matrices.last().pose();
486+
RenderUtils.drawOutlinedTextInBatch(MC.font, profession, -w, 0,
487+
labelColor, strokeColor, matrix, Font.DisplayMode.SEE_THROUGH,
488+
bg, 0xF000F0);
489+
matrices.popPose();
490+
}
491+
}
492+
493+
private String getVillagerProfessionName(Villager villager)
494+
{
495+
ResourceKey<VillagerProfession> key =
496+
villager.getVillagerData().profession().unwrapKey().orElse(null);
497+
498+
if(key == null)
499+
return "";
500+
501+
if(key == VillagerProfession.NONE)
502+
return "Unemployed";
503+
if(key == VillagerProfession.NITWIT)
504+
return "Nitwit";
505+
if(key == VillagerProfession.FARMER)
506+
return "Farmer";
507+
if(key == VillagerProfession.FISHERMAN)
508+
return "Fisherman";
509+
if(key == VillagerProfession.SHEPHERD)
510+
return "Shepherd";
511+
if(key == VillagerProfession.FLETCHER)
512+
return "Fletcher";
513+
if(key == VillagerProfession.LIBRARIAN)
514+
return "Librarian";
515+
if(key == VillagerProfession.CARTOGRAPHER)
516+
return "Cartographer";
517+
if(key == VillagerProfession.CLERIC)
518+
return "Cleric";
519+
if(key == VillagerProfession.ARMORER)
520+
return "Armorer";
521+
if(key == VillagerProfession.WEAPONSMITH)
522+
return "Weaponsmith";
523+
if(key == VillagerProfession.TOOLSMITH)
524+
return "Toolsmith";
525+
if(key == VillagerProfession.BUTCHER)
526+
return "Butcher";
527+
if(key == VillagerProfession.LEATHERWORKER)
528+
return "Leatherworker";
529+
if(key == VillagerProfession.MASON)
530+
return "Mason";
531+
532+
return "";
402533
}
403534

404535
private void renderShulkerProjectileFallback(PoseStack matrixStack,

0 commit comments

Comments
 (0)