From f15dff997ba84690a1e2766a7ad0d5caedcdf1d2 Mon Sep 17 00:00:00 2001 From: crazycat256 <63475640+crazycat256@users.noreply.github.com> Date: Wed, 24 Jan 2024 17:31:00 +0100 Subject: [PATCH 1/4] Fix GenericSetting reset button GenericSetting's reset button was not right-aligned --- .../meteorclient/gui/DefaultSettingsWidgetFactory.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/meteordevelopment/meteorclient/gui/DefaultSettingsWidgetFactory.java b/src/main/java/meteordevelopment/meteorclient/gui/DefaultSettingsWidgetFactory.java index 6b2d2152fc..ec4a12b483 100644 --- a/src/main/java/meteordevelopment/meteorclient/gui/DefaultSettingsWidgetFactory.java +++ b/src/main/java/meteordevelopment/meteorclient/gui/DefaultSettingsWidgetFactory.java @@ -216,7 +216,7 @@ private void providedStringW(WTable table, ProvidedStringSetting setting) { } private void genericW(WTable table, GenericSetting setting) { - WButton edit = table.add(theme.button(GuiRenderer.EDIT)).widget(); + WButton edit = table.add(theme.button(GuiRenderer.EDIT)).expandCellX().widget(); edit.action = () -> mc.setScreen(setting.get().createScreen(theme)); reset(table, setting, null); From 6cc20577e9b112e5d71dacf3e043af56acd2fea8 Mon Sep 17 00:00:00 2001 From: crazycat256 <63475640+crazycat256@users.noreply.github.com> Date: Thu, 25 Jan 2024 16:07:23 +0100 Subject: [PATCH 2/4] Added EntityTypeDataSetting --- .../gui/DefaultSettingsWidgetFactory.java | 8 ++ .../settings/EntityTypeDataSettingScreen.java | 100 ++++++++++++++++++ .../settings/EntityTypeDataSetting.java | 85 +++++++++++++++ .../settings/IEntityTypeData.java | 17 +++ 4 files changed, 210 insertions(+) create mode 100644 src/main/java/meteordevelopment/meteorclient/gui/screens/settings/EntityTypeDataSettingScreen.java create mode 100644 src/main/java/meteordevelopment/meteorclient/settings/EntityTypeDataSetting.java create mode 100644 src/main/java/meteordevelopment/meteorclient/settings/IEntityTypeData.java diff --git a/src/main/java/meteordevelopment/meteorclient/gui/DefaultSettingsWidgetFactory.java b/src/main/java/meteordevelopment/meteorclient/gui/DefaultSettingsWidgetFactory.java index ec4a12b483..0c076e8a14 100644 --- a/src/main/java/meteordevelopment/meteorclient/gui/DefaultSettingsWidgetFactory.java +++ b/src/main/java/meteordevelopment/meteorclient/gui/DefaultSettingsWidgetFactory.java @@ -64,6 +64,7 @@ public DefaultSettingsWidgetFactory(GuiTheme theme) { factories.put(StorageBlockListSetting.class, (table, setting) -> storageBlockListW(table, (StorageBlockListSetting) setting)); factories.put(ScreenHandlerListSetting.class, (table, setting) -> screenHandlerListW(table, (ScreenHandlerListSetting) setting)); factories.put(BlockDataSetting.class, (table, setting) -> blockDataW(table, (BlockDataSetting) setting)); + factories.put(EntityTypeDataSetting.class, (table, setting) -> entityTypeDataW(table, (EntityTypeDataSetting) setting)); factories.put(PotionSetting.class, (table, setting) -> potionW(table, (PotionSetting) setting)); factories.put(StringListSetting.class, (table, setting) -> stringListW(table, (StringListSetting) setting)); factories.put(BlockPosSetting.class, (table, setting) -> blockPosW(table, (BlockPosSetting) setting)); @@ -341,6 +342,13 @@ private void blockDataW(WTable table, BlockDataSetting setting) { reset(table, setting, null); } + private void entityTypeDataW(WTable table, EntityTypeDataSetting setting) { + WButton button = table.add(theme.button(GuiRenderer.EDIT)).expandCellX().widget(); + button.action = () -> mc.setScreen(new EntityTypeDataSettingScreen(theme, setting)); + + reset(table, setting, null); + } + private void potionW(WTable table, PotionSetting setting) { WHorizontalList list = table.add(theme.horizontalList()).expandX().widget(); WItemWithLabel item = list.add(theme.itemWithLabel(setting.get().potion, setting.get().potion.getName().getString())).widget(); diff --git a/src/main/java/meteordevelopment/meteorclient/gui/screens/settings/EntityTypeDataSettingScreen.java b/src/main/java/meteordevelopment/meteorclient/gui/screens/settings/EntityTypeDataSettingScreen.java new file mode 100644 index 0000000000..789824f25f --- /dev/null +++ b/src/main/java/meteordevelopment/meteorclient/gui/screens/settings/EntityTypeDataSettingScreen.java @@ -0,0 +1,100 @@ +/* + * This file is part of the Meteor Client distribution (https://github.com/MeteorDevelopment/meteor-client). + * Copyright (c) Meteor Development. + */ + +package meteordevelopment.meteorclient.gui.screens.settings; + +import meteordevelopment.meteorclient.gui.GuiTheme; +import meteordevelopment.meteorclient.gui.WindowScreen; +import meteordevelopment.meteorclient.gui.renderer.GuiRenderer; +import meteordevelopment.meteorclient.gui.widgets.containers.WTable; +import meteordevelopment.meteorclient.gui.widgets.input.WTextBox; +import meteordevelopment.meteorclient.gui.widgets.pressable.WButton; +import meteordevelopment.meteorclient.settings.EntityTypeDataSetting; +import meteordevelopment.meteorclient.settings.IEntityTypeData; +import meteordevelopment.meteorclient.utils.misc.IChangeable; +import meteordevelopment.meteorclient.utils.misc.ICopyable; +import meteordevelopment.meteorclient.utils.misc.ISerializable; +import meteordevelopment.meteorclient.utils.misc.Names; +import net.minecraft.entity.EntityType; +import net.minecraft.registry.Registries; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.List; + +import static meteordevelopment.meteorclient.MeteorClient.mc; + +public class EntityTypeDataSettingScreen extends WindowScreen { + private final List ENTITY_TYPES = new ArrayList<>(100); + + private final EntityTypeDataSetting setting; + + private WTable table; + private String filterText = ""; + + public EntityTypeDataSettingScreen(GuiTheme theme, EntityTypeDataSetting setting) { + super(theme, "Configure Entity Types"); + + this.setting = setting; + } + + @Override + public void initWidgets() { + WTextBox filter = add(theme.textBox("")).minWidth(400).expandX().widget(); + filter.setFocused(true); + filter.action = () -> { + filterText = filter.get().trim(); + + table.clear(); + initTable(); + }; + + table = add(theme.table()).expandX().widget(); + + initTable(); + } + + public & ISerializable & IChangeable & IEntityTypeData> void initTable() { + for (EntityType entityType : Registries.ENTITY_TYPE) { + T entityTypeData = (T) setting.get().get(entityType); + + if (entityTypeData != null) ENTITY_TYPES.add(0, entityType); + else ENTITY_TYPES.add(entityType); + } + + for (EntityType entityType : ENTITY_TYPES) { + String name = Names.get(entityType); + if (!StringUtils.containsIgnoreCase(name, filterText)) continue; + + T entityTypeData = (T) setting.get().get(entityType); + + table.add(theme.label(name)).expandCellX(); + table.add(theme.label(entityTypeData != null && entityTypeData.isChanged() ? "*": " ")); + + WButton edit = table.add(theme.button(GuiRenderer.EDIT)).widget(); + edit.action = () -> { + T data = entityTypeData; + if (data == null) data = (T) setting.defaultData.get().copy(); + + mc.setScreen(data.createScreen(theme, entityType, (EntityTypeDataSetting) setting)); + }; + + WButton reset = table.add(theme.button(GuiRenderer.RESET)).widget(); + reset.action = () -> { + setting.get().remove(entityType); + setting.onChanged(); + + if (entityTypeData != null && entityTypeData.isChanged()) { + table.clear(); + initTable(); + } + }; + + table.row(); + } + + ENTITY_TYPES.clear(); + } +} diff --git a/src/main/java/meteordevelopment/meteorclient/settings/EntityTypeDataSetting.java b/src/main/java/meteordevelopment/meteorclient/settings/EntityTypeDataSetting.java new file mode 100644 index 0000000000..328dccfb5a --- /dev/null +++ b/src/main/java/meteordevelopment/meteorclient/settings/EntityTypeDataSetting.java @@ -0,0 +1,85 @@ +/* + * This file is part of the Meteor Client distribution (https://github.com/MeteorDevelopment/meteor-client). + * Copyright (c) Meteor Development. + */ + +package meteordevelopment.meteorclient.settings; + +import meteordevelopment.meteorclient.utils.misc.IChangeable; +import meteordevelopment.meteorclient.utils.misc.ICopyable; +import meteordevelopment.meteorclient.utils.misc.IGetter; +import meteordevelopment.meteorclient.utils.misc.ISerializable; +import net.minecraft.entity.EntityType; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.registry.Registries; +import net.minecraft.util.Identifier; + +import java.util.HashMap; +import java.util.Map; +import java.util.function.Consumer; + +public class EntityTypeDataSetting & ISerializable & IChangeable & IEntityTypeData> extends Setting> { + public final IGetter defaultData; + + public EntityTypeDataSetting(String name, String description, Map defaultValue, Consumer> onChanged, Consumer>> onModuleActivated, IGetter defaultData, IVisible visible) { + super(name, description, defaultValue, onChanged, onModuleActivated, visible); + + this.defaultData = defaultData; + } + + @Override + public void resetImpl() { + value = new HashMap<>(defaultValue); + } + + @Override + protected Map parseImpl(String str) { + return new HashMap<>(0); + } + + @Override + protected boolean isValueValid(Map value) { + return true; + } + + @Override + protected NbtCompound save(NbtCompound tag) { + NbtCompound valueTag = new NbtCompound(); + for (EntityType entityType : get().keySet()) { + valueTag.put(Registries.ENTITY_TYPE.getId(entityType).toString(), get().get(entityType).toTag()); + } + tag.put("value", valueTag); + + return tag; + } + + @Override + protected Map load(NbtCompound tag) { + get().clear(); + + NbtCompound valueTag = tag.getCompound("value"); + for (String key : valueTag.getKeys()) { + get().put(Registries.ENTITY_TYPE.get(new Identifier(key)), defaultData.get().copy().fromTag(valueTag.getCompound(key))); + } + + return get(); + } + + public static class Builder & ISerializable & IChangeable & IEntityTypeData> extends SettingBuilder, Map, EntityTypeDataSetting> { + private IGetter defaultData; + + public Builder() { + super(new HashMap<>(0)); + } + + public Builder defaultData(IGetter defaultData) { + this.defaultData = defaultData; + return this; + } + + @Override + public EntityTypeDataSetting build() { + return new EntityTypeDataSetting<>(name, description, defaultValue, onChanged, onModuleActivated, defaultData, visible); + } + } +} diff --git a/src/main/java/meteordevelopment/meteorclient/settings/IEntityTypeData.java b/src/main/java/meteordevelopment/meteorclient/settings/IEntityTypeData.java new file mode 100644 index 0000000000..25184782c9 --- /dev/null +++ b/src/main/java/meteordevelopment/meteorclient/settings/IEntityTypeData.java @@ -0,0 +1,17 @@ +/* + * This file is part of the Meteor Client distribution (https://github.com/MeteorDevelopment/meteor-client). + * Copyright (c) Meteor Development. + */ + +package meteordevelopment.meteorclient.settings; + +import meteordevelopment.meteorclient.gui.GuiTheme; +import meteordevelopment.meteorclient.gui.WidgetScreen; +import meteordevelopment.meteorclient.utils.misc.IChangeable; +import meteordevelopment.meteorclient.utils.misc.ICopyable; +import meteordevelopment.meteorclient.utils.misc.ISerializable; +import net.minecraft.entity.EntityType; + +public interface IEntityTypeData & ISerializable & IChangeable & IEntityTypeData> { + WidgetScreen createScreen(GuiTheme theme, EntityType entityType, EntityTypeDataSetting setting); +} From bdedd7cfcaeb1a8ea8d265ef3eb346a4a7458333 Mon Sep 17 00:00:00 2001 From: crazycat256 <63475640+crazycat256@users.noreply.github.com> Date: Thu, 25 Jan 2024 16:08:26 +0100 Subject: [PATCH 3/4] Improved nametags settings --- .../mixin/EntityRendererMixin.java | 2 +- .../meteorclient/systems/modules/Modules.java | 1 + .../render/{ => nametags}/Nametags.java | 82 +++++++++---- .../nametags/NametagsEntityTypeData.java | 98 +++++++++++++++ .../NametagsEntityTypeDataScreen.java | 116 ++++++++++++++++++ 5 files changed, 276 insertions(+), 23 deletions(-) rename src/main/java/meteordevelopment/meteorclient/systems/modules/render/{ => nametags}/Nametags.java (89%) create mode 100644 src/main/java/meteordevelopment/meteorclient/systems/modules/render/nametags/NametagsEntityTypeData.java create mode 100644 src/main/java/meteordevelopment/meteorclient/systems/modules/render/nametags/NametagsEntityTypeDataScreen.java diff --git a/src/main/java/meteordevelopment/meteorclient/mixin/EntityRendererMixin.java b/src/main/java/meteordevelopment/meteorclient/mixin/EntityRendererMixin.java index d7d227aedc..7404347e27 100644 --- a/src/main/java/meteordevelopment/meteorclient/mixin/EntityRendererMixin.java +++ b/src/main/java/meteordevelopment/meteorclient/mixin/EntityRendererMixin.java @@ -9,7 +9,7 @@ import meteordevelopment.meteorclient.mixininterface.IEntityRenderer; import meteordevelopment.meteorclient.systems.modules.Modules; import meteordevelopment.meteorclient.systems.modules.render.Fullbright; -import meteordevelopment.meteorclient.systems.modules.render.Nametags; +import meteordevelopment.meteorclient.systems.modules.render.nametags.Nametags; import meteordevelopment.meteorclient.systems.modules.render.NoRender; import meteordevelopment.meteorclient.utils.entity.EntityUtils; import meteordevelopment.meteorclient.utils.render.postprocess.PostProcessShaders; diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/Modules.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/Modules.java index c9b07c574d..ea80d082a3 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/Modules.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/Modules.java @@ -31,6 +31,7 @@ import meteordevelopment.meteorclient.systems.modules.render.*; import meteordevelopment.meteorclient.systems.modules.render.blockesp.BlockESP; import meteordevelopment.meteorclient.systems.modules.render.marker.Marker; +import meteordevelopment.meteorclient.systems.modules.render.nametags.Nametags; import meteordevelopment.meteorclient.systems.modules.world.Timer; import meteordevelopment.meteorclient.systems.modules.world.*; import meteordevelopment.meteorclient.utils.Utils; diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Nametags.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/nametags/Nametags.java similarity index 89% rename from src/main/java/meteordevelopment/meteorclient/systems/modules/render/Nametags.java rename to src/main/java/meteordevelopment/meteorclient/systems/modules/render/nametags/Nametags.java index 79d51bc625..f82f6c0018 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Nametags.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/nametags/Nametags.java @@ -3,10 +3,11 @@ * Copyright (c) Meteor Development. */ -package meteordevelopment.meteorclient.systems.modules.render; +package meteordevelopment.meteorclient.systems.modules.render.nametags; import meteordevelopment.meteorclient.events.render.Render2DEvent; import meteordevelopment.meteorclient.events.world.TickEvent; +import meteordevelopment.meteorclient.mixininterface.IVec3d; import meteordevelopment.meteorclient.renderer.Renderer2D; import meteordevelopment.meteorclient.renderer.text.TextRenderer; import meteordevelopment.meteorclient.settings.*; @@ -16,6 +17,7 @@ import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.systems.modules.Modules; import meteordevelopment.meteorclient.systems.modules.misc.NameProtect; +import meteordevelopment.meteorclient.systems.modules.render.Freecam; import meteordevelopment.meteorclient.utils.Utils; import meteordevelopment.meteorclient.utils.entity.EntityUtils; import meteordevelopment.meteorclient.utils.player.PlayerUtils; @@ -31,9 +33,11 @@ import net.minecraft.entity.decoration.ItemFrameEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; +import net.minecraft.util.hit.HitResult; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; import net.minecraft.world.GameMode; +import net.minecraft.world.RaycastContext; import org.joml.Vector3d; import java.util.*; @@ -53,11 +57,25 @@ public class Nametags extends Module { .build() ); - private final Setting scale = sgGeneral.add(new DoubleSetting.Builder() - .name("scale") - .description("The scale of the nametag.") - .defaultValue(1.1) - .min(0.1) + private final Setting defaultEntitySettings = sgGeneral.add(new GenericSetting.Builder() + .name("default-entity-settings") + .description("The default settings for each entity type.") + .defaultValue( + new NametagsEntityTypeData( + 1.1, + true, + false, + 20, + 50 + ) + ) + .build() + ); + + private final Setting> entitySettings = sgGeneral.add(new EntityTypeDataSetting.Builder() + .name("entity-settings") + .description("The settings for each entity type.") + .defaultData(defaultEntitySettings) .build() ); @@ -84,21 +102,11 @@ public class Nametags extends Module { private final Setting culling = sgGeneral.add(new BoolSetting.Builder() .name("culling") - .description("Only render a certain number of nametags at a certain distance.") + .description("Only render a certain number of nametags.") .defaultValue(false) .build() ); - private final Setting maxCullRange = sgGeneral.add(new DoubleSetting.Builder() - .name("culling-range") - .description("Only render nametags within this distance of your player.") - .defaultValue(20) - .min(0) - .sliderMax(200) - .visible(culling::get) - .build() - ); - private final Setting maxCullCount = sgGeneral.add(new IntSetting.Builder() .name("culling-count") .description("Only render this many nametags.") @@ -279,6 +287,7 @@ public class Nametags extends Module { private final double[] itemWidths = new double[6]; private final List entityList = new ArrayList<>(); + private final Map, Integer> entityCountMap = new HashMap<>(); public Nametags() { super(Categories.Render, "nametags", "Displays customizable nametags above players."); @@ -298,9 +307,33 @@ private static String ticksToTime(int ticks) { } } + private boolean isBehindWall(Entity entity) { + Vec3d vec1 = new Vec3d(0, 0, 0); + Vec3d vec2 = new Vec3d(0, 0, 0); + + Vec3d cameraPos = mc.gameRenderer.getCamera().getPos(); + + ((IVec3d) vec1).set(cameraPos.x, cameraPos.y, cameraPos.z); + ((IVec3d) vec2).set(entity.getX(), entity.getY() + entity.getStandingEyeHeight(), entity.getZ()); + + return mc.world.raycast(new RaycastContext(vec1, vec2, RaycastContext.ShapeType.VISUAL, RaycastContext.FluidHandling.NONE, mc.player)).getType() == HitResult.Type.MISS; + } + + private Integer entityCountIncrement(Class entityClass) { + int count = entityCountMap.getOrDefault(entityClass, 0); + entityCountMap.put(entityClass, count + 1); + return count + 1; + } + + NametagsEntityTypeData getEntityTypeData(EntityType entityType) { + NametagsEntityTypeData entityTypeData = entitySettings.get().get(entityType); + return entityTypeData == null ? defaultEntitySettings.get() : entityTypeData; + } + @EventHandler private void onTick(TickEvent.Post event) { entityList.clear(); + entityCountMap.clear(); boolean freecamNotActive = !Modules.get().isActive(Freecam.class); boolean notThirdPerson = mc.options.getPerspective().isFirstPerson(); @@ -310,15 +343,20 @@ private void onTick(TickEvent.Post event) { EntityType type = entity.getType(); if (!entities.get().contains(type)) continue; + NametagsEntityTypeData entityData = getEntityTypeData(type); + if (!entityData.throughWalls && !isBehindWall(entity)) continue; + if (entityData.culling) { + if (entityData.maxCullCount <= entityCountIncrement(type.getClass())) continue; + if (!PlayerUtils.isWithinCamera(entity, entityData.maxCullRange)) continue; + } + if (type == EntityType.PLAYER) { if ((ignoreSelf.get() || (freecamNotActive && notThirdPerson)) && entity == mc.player) continue; if (EntityUtils.getGameMode((PlayerEntity) entity) == null && ignoreBots.get()) continue; if (Friends.get().isFriend((PlayerEntity) entity) && ignoreFriends.get()) continue; } - if (!culling.get() || PlayerUtils.isWithinCamera(entity, maxCullRange.get())) { - entityList.add(entity); - } + entityList.add(entity); } entityList.sort(Comparator.comparing(e -> e.squaredDistanceTo(cameraPos))); @@ -337,7 +375,7 @@ private void onRender2D(Render2DEvent event) { EntityType type = entity.getType(); - if (NametagUtils.to2D(pos, scale.get())) { + if (NametagUtils.to2D(pos, getEntityTypeData(type).scale)) { if (type == EntityType.PLAYER) renderNametagPlayer(event, (PlayerEntity) entity, shadow); else if (type == EntityType.ITEM) renderNametagItem(((ItemEntity) entity).getStack(), shadow); else if (type == EntityType.ITEM_FRAME) @@ -391,7 +429,7 @@ private void renderNametagPlayer(Render2DEvent event, PlayerEntity player, boole String name; Color nameColor = PlayerUtils.getPlayerColor(player, this.nameColor.get()); - if (player == mc.player) name = Modules.get().get(NameProtect.class).getName(player.getName().getString()); + if (player == mc.player) name = Modules.get().get(NameProtect.class).getName(player.getGameProfile().getName()); else name = player.getName().getString(); // Health diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/nametags/NametagsEntityTypeData.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/nametags/NametagsEntityTypeData.java new file mode 100644 index 0000000000..a36db0696c --- /dev/null +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/nametags/NametagsEntityTypeData.java @@ -0,0 +1,98 @@ +/* + * This file is part of the Meteor Client distribution (https://github.com/MeteorDevelopment/meteor-client). + * Copyright (c) Meteor Development. + */ + +package meteordevelopment.meteorclient.systems.modules.render.nametags; + +import meteordevelopment.meteorclient.gui.GuiTheme; +import meteordevelopment.meteorclient.gui.WidgetScreen; +import meteordevelopment.meteorclient.gui.utils.IScreenFactory; +import meteordevelopment.meteorclient.settings.EntityTypeDataSetting; +import meteordevelopment.meteorclient.settings.IEntityTypeData; +import meteordevelopment.meteorclient.utils.misc.IChangeable; +import meteordevelopment.meteorclient.utils.misc.ICopyable; +import meteordevelopment.meteorclient.utils.misc.ISerializable; +import net.minecraft.entity.EntityType; +import net.minecraft.nbt.NbtCompound; + +public class NametagsEntityTypeData implements ICopyable, ISerializable, IChangeable, IEntityTypeData, IScreenFactory { + public double scale; + public boolean throughWalls; + public boolean culling; + public double maxCullRange; + public double maxCullCount; + + private boolean changed; + + public NametagsEntityTypeData(double scale, boolean throughWalls, boolean culling, double maxCullRange, double maxCullCount) { + this.scale = scale; + this.throughWalls = throughWalls; + this.culling = culling; + this.maxCullRange = maxCullRange; + this.maxCullCount = maxCullCount; + } + + @Override + public WidgetScreen createScreen(GuiTheme theme, EntityType entityType, EntityTypeDataSetting setting) { + return new NametagsEntityTypeDataScreen(theme, this, entityType, setting); + } + + @Override + public WidgetScreen createScreen(GuiTheme theme) { + return new NametagsEntityTypeDataScreen(theme, this, null, null); + } + + @Override + public boolean isChanged() { + return changed; + } + + public void changed() { + changed = true; + } + + @Override + public NametagsEntityTypeData set(NametagsEntityTypeData value) { + scale = value.scale; + throughWalls = value.throughWalls; + culling = value.culling; + maxCullRange = value.maxCullRange; + maxCullCount = value.maxCullCount; + + changed = value.changed; + + return this; + } + + @Override + public NametagsEntityTypeData copy() { + return new NametagsEntityTypeData(scale, throughWalls, culling, maxCullRange, maxCullCount); + } + + @Override + public NbtCompound toTag() { + NbtCompound tag = new NbtCompound(); + tag.putDouble("scale", scale); + tag.putBoolean("onlyVisible", throughWalls); + tag.putBoolean("culling", culling); + tag.putDouble("maxCullRange", maxCullRange); + tag.putDouble("maxCullCount", maxCullCount); + + tag.putBoolean("changed", changed); + return tag; + } + + @Override + public NametagsEntityTypeData fromTag(NbtCompound tag) { + scale = tag.getDouble("scale"); + throughWalls = tag.getBoolean("onlyVisible"); + culling = tag.getBoolean("culling"); + maxCullRange = tag.getDouble("maxCullRange"); + maxCullCount = tag.getDouble("maxCullCount"); + + changed = tag.getBoolean("changed"); + return this; + } + +} diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/nametags/NametagsEntityTypeDataScreen.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/nametags/NametagsEntityTypeDataScreen.java new file mode 100644 index 0000000000..85d7b801eb --- /dev/null +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/nametags/NametagsEntityTypeDataScreen.java @@ -0,0 +1,116 @@ +/* + * This file is part of the Meteor Client distribution (https://github.com/MeteorDevelopment/meteor-client). + * Copyright (c) Meteor Development. + */ + +package meteordevelopment.meteorclient.systems.modules.render.nametags; + +import meteordevelopment.meteorclient.gui.GuiTheme; +import meteordevelopment.meteorclient.gui.WindowScreen; +import meteordevelopment.meteorclient.gui.widgets.containers.WContainer; +import meteordevelopment.meteorclient.settings.*; +import net.minecraft.entity.EntityType; + +public class NametagsEntityTypeDataScreen extends WindowScreen { + private final NametagsEntityTypeData entityTypeData; + private final EntityType entityType; + private final EntityTypeDataSetting setting; + private Settings settings; + private WContainer settingsContainer; + + public NametagsEntityTypeDataScreen(GuiTheme guiTheme, NametagsEntityTypeData entityData, EntityType entityType, EntityTypeDataSetting setting) { + super(guiTheme, "Entity Data"); + + this.entityTypeData = entityData; + this.entityType = entityType; + this.setting = setting; + } + + @Override + public void initWidgets() { + settings = new Settings(); + SettingGroup sgGeneral = settings.getDefaultGroup(); + + sgGeneral.add(new DoubleSetting.Builder() + .name("scale") + .description("The scale of the nametag.") + .defaultValue(1.1) + .onModuleActivated(settingDoubleSetting -> settingDoubleSetting.set(entityTypeData.scale)) + .onChanged(settingDouble -> { + entityTypeData.scale = settingDouble; + changed(entityTypeData, entityType, setting); + }) + .min(0.1) + .build() + ); + + sgGeneral.add(new BoolSetting.Builder() + .name("through-walls") + .description("Renders nametags through walls.") + .defaultValue(false) + .onModuleActivated(settingBooleanSetting -> settingBooleanSetting.set(entityTypeData.throughWalls)) + .onChanged(settingBoolean -> { + entityTypeData.throughWalls = settingBoolean; + changed(entityTypeData, entityType, setting); + }) + .build() + ); + + final Setting culling = sgGeneral.add(new BoolSetting.Builder() + .name("culling") + .description("Only render a certain number of nametags at a certain distance.") + .defaultValue(false) + .onModuleActivated(settingBooleanSetting -> settingBooleanSetting.set(entityTypeData.culling)) + .onChanged(settingBoolean -> { + entityTypeData.culling = settingBoolean; + changed(entityTypeData, entityType, setting); + }) + .build() + ); + + sgGeneral.add(new DoubleSetting.Builder() + .name("culling-range") + .description("Only render nametags within this distance of your player.") + .defaultValue(20) + .min(0) + .sliderMax(200) + .visible(culling::get) + .onModuleActivated(settingDoubleSetting -> entityTypeData.maxCullRange = settingDoubleSetting.get()) + .onChanged(settingDouble -> { + entityTypeData.maxCullRange = settingDouble; + changed(entityTypeData, entityType, setting); + }) + .build() + ); + + sgGeneral.add(new IntSetting.Builder() + .name("culling-count") + .description("Only render this many nametags.") + .defaultValue(50) + .min(1) + .sliderRange(1, 100) + .visible(culling::get) + .onModuleActivated(settingIntegerSetting -> entityTypeData.maxCullCount = settingIntegerSetting.get()) + .onChanged(settingInteger -> { + entityTypeData.maxCullCount = settingInteger; + changed(entityTypeData, entityType, setting); + }) + .build() + ); + + settings.onActivated(); + settingsContainer = (WContainer) add(theme.settings(settings)).expandX().widget(); + } + + private void changed(NametagsEntityTypeData entityTypeData, EntityType entityType, EntityTypeDataSetting setting) { + if (!entityTypeData.isChanged() && entityType != null && setting != null) { + setting.get().put(entityType, entityTypeData); + setting.onChanged(); + } + if (settingsContainer != null) { + settings.tick(settingsContainer, theme); + } + + entityTypeData.changed(); + } +} From f27476196a5cbe74eb9b671694de7f431b2dcf36 Mon Sep 17 00:00:00 2001 From: crazycat256 <63475640+crazycat256@users.noreply.github.com> Date: Thu, 25 Jan 2024 19:19:07 +0100 Subject: [PATCH 4/4] Fix entity eye height --- .../meteorclient/systems/modules/render/nametags/Nametags.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/nametags/Nametags.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/nametags/Nametags.java index f82f6c0018..301ac2f4b3 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/nametags/Nametags.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/nametags/Nametags.java @@ -314,7 +314,7 @@ private boolean isBehindWall(Entity entity) { Vec3d cameraPos = mc.gameRenderer.getCamera().getPos(); ((IVec3d) vec1).set(cameraPos.x, cameraPos.y, cameraPos.z); - ((IVec3d) vec2).set(entity.getX(), entity.getY() + entity.getStandingEyeHeight(), entity.getZ()); + ((IVec3d) vec2).set(entity.getX(), entity.getEyeY(), entity.getZ()); return mc.world.raycast(new RaycastContext(vec1, vec2, RaycastContext.ShapeType.VISUAL, RaycastContext.FluidHandling.NONE, mc.player)).getType() == HitResult.Type.MISS; }