diff --git a/README.md b/README.md
index 1282ef2..f4704d5 100644
--- a/README.md
+++ b/README.md
@@ -10,12 +10,14 @@ mod para Minecraft Fabric 1.21.6 que añade algunas cosas QOL, mayormente relaci
3. descargar el .jar
4. moverlo a tu directorio de mods (probablemente `%appdata%/.minecraft/mods`)
-asegúrate de tener una version de Minecraft y Fabric compatibles con el mod
+asegúrate de tener una version de Minecraft y Fabric compatibles con el mod (MC 1.21.6; Fabric 0.128.2)
+es posible que hayan problemas al usarlo junto a otros mods, especialmente otros clientes, pues pueden conflictar
### para frikis de 200 de iq
1. clona el respositorio (`git clone https://github.com/retuci0/camera-tweaks`)
-2. `gradlew build` para Windows o `chmod +x gradlew` + `./gradlew build` para Linux
-3. el resultado estará en `/build/libs` (el que no lleva "sources" en el nombre)
+2. entra al directorio del repositorio (`cd camera-tweaks`)
+3. `gradlew build` para Windows o `chmod +x gradlew` + `./gradlew build` para Linux (Mac es Linux)
+4. el resultado estará en `/build/libs/camtweaks-X.X.jar` (el que no lleva "sources" en el nombre)
## uso
@@ -48,6 +50,7 @@ algunos módulos tienen teclas asignadas por defecto, asígnales `ESC` para desa
+
## contibuciones
diff --git a/cambios.md b/cambios.md
index ca3b273..f7c4dda 100644
--- a/cambios.md
+++ b/cambios.md
@@ -7,6 +7,7 @@
- barra de búsqueda: filtra los ajustes de todos los paneles de ajustes, por nombre y descripción
- barra de deslizamiento
- módulo de jugador falso: invoca una entidad de jugador falsa, por motivos de testeo
+- HUD: mostrar información adicional en pantalla (ej.: hora, fps, coordenadas, ...)
### arreglos / mejoras
@@ -15,9 +16,13 @@
- ahora solo se puede seleccionar un objeto de la interfaz a la vez
- cambiada la posición de los títulos de los marcos
+- ahora los módulos están ordenados por orden alfabético
+
+- ahora nametags también tiene en cuenta la absorción de un jugador al mostrar su vida
+
- el color del prefijo de las notificaciones por chat ahora depende de los ajustes de color
- ya no se muestra el prefijo equivocado en notificaciones por chat al meterse a un mundo por primera vez
## problemas reconocidos
-- ...
\ No newline at end of file
+- muchos, pero repórtalos en la página de problemas si quieres para que queden bien registrados
\ No newline at end of file
diff --git a/gradle.properties b/gradle.properties
index d6efe30..ac7a1ef 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -10,7 +10,7 @@ loader_version=0.17.2
loom_version=1.11-SNAPSHOT
# Mod Properties
-mod_version=1.2
+mod_version=1.3
maven_group=me.retucio
archives_base_name=camtweaks
diff --git a/screenshots/hud.png b/screenshots/hud.png
new file mode 100644
index 0000000..6515bd8
Binary files /dev/null and b/screenshots/hud.png differ
diff --git a/screenshots/ui.png b/screenshots/ui.png
index 1a28d36..4ebc2f4 100644
Binary files a/screenshots/ui.png and b/screenshots/ui.png differ
diff --git a/src/main/java/me/retucio/camtweaks/mixin/PlayerEntityMixin.java b/src/main/java/me/retucio/camtweaks/mixin/PlayerEntityMixin.java
index 93f36b6..bf4df58 100644
--- a/src/main/java/me/retucio/camtweaks/mixin/PlayerEntityMixin.java
+++ b/src/main/java/me/retucio/camtweaks/mixin/PlayerEntityMixin.java
@@ -25,6 +25,7 @@ public abstract class PlayerEntityMixin extends LivingEntity {
if (!nametags.isEnabled() || !nametags.health.isEnabled()) return original;
float health = getHealth();
+ float absorption = getAbsorptionAmount();
Formatting color;
if (health < 5) color = Formatting.RED;
@@ -34,7 +35,18 @@ public abstract class PlayerEntityMixin extends LivingEntity {
// me gustaría también añadir un modo en el que se renderizan los corazones directamente en la nametag, pero no sé cómo hacer para las imágenes :'(
// ahora que lo pienso en la snapshot más reciente han metido iconos que se pueden usar en texto, y uno de ellos es un corazón :D
- return original.copy().append(Text.literal(" [" + color + (nametags.healthMode.is(Nametags.HealthMode.HEARTS)
- ? String.format("%.2f", health / 2) : (int) health) + Formatting.RESET + "]"));
- } // redondear a dos decimales
+ String text = " [" + color +
+ (nametags.healthMode.is(Nametags.HealthMode.HEARTS)
+ ? String.format("%.2f", health / 2) // redondear a dos decimales
+ : (int) health) +
+ (absorption > 0 // tener absorción en cuenta
+ ? Formatting.RESET + " + " + Formatting.GOLD +
+ (nametags.healthMode.is(Nametags.HealthMode.HEARTS)
+ ? String.format("%.2f", absorption / 2)
+ : Integer.toString((int) absorption))
+ : "") +
+ Formatting.RESET + "]";
+
+ return original.copy().append(text);
+ }
}
\ No newline at end of file
diff --git a/src/main/java/me/retucio/camtweaks/module/ModuleManager.java b/src/main/java/me/retucio/camtweaks/module/ModuleManager.java
index df0c19e..5f86a0f 100644
--- a/src/main/java/me/retucio/camtweaks/module/ModuleManager.java
+++ b/src/main/java/me/retucio/camtweaks/module/ModuleManager.java
@@ -6,6 +6,7 @@ import me.retucio.camtweaks.module.modules.*;
import java.lang.reflect.Method;
import java.util.ArrayList;
+import java.util.Comparator;
import java.util.List;
@@ -35,6 +36,7 @@ public class ModuleManager {
modules.add(new Freelook());
modules.add(new Fullbright());
modules.add(new HandView());
+ modules.add(new HUD());
modules.add(new Nametags());
modules.add(new NoRender());
modules.add(new PerspectivePlus());
@@ -42,6 +44,8 @@ public class ModuleManager {
modules.add(new TimeChanger());
modules.add(new Zoom());
+ modules.sort(Comparator.comparing(module -> module.getName().toLowerCase()));
+
// registrar los "listeners" necesarios
for (Module module : getEnabledModules()) {
for (Method method : module.getClass().getDeclaredMethods()) {
diff --git a/src/main/java/me/retucio/camtweaks/module/modules/HUD.java b/src/main/java/me/retucio/camtweaks/module/modules/HUD.java
new file mode 100644
index 0000000..654cf7a
--- /dev/null
+++ b/src/main/java/me/retucio/camtweaks/module/modules/HUD.java
@@ -0,0 +1,56 @@
+package me.retucio.camtweaks.module.modules;
+
+import me.retucio.camtweaks.module.Module;
+import me.retucio.camtweaks.module.settings.BooleanSetting;
+import me.retucio.camtweaks.module.settings.EnumSetting;
+import me.retucio.camtweaks.module.settings.NumberSetting;
+import me.retucio.camtweaks.module.settings.StringSetting;
+
+public class HUD extends Module {
+
+ public NumberSetting red = addSetting(new NumberSetting("rojo", "cantidad de rojo", 255, 0, 255, 1));
+ public NumberSetting green = addSetting(new NumberSetting("verde", "cantidad de verde", 255, 0, 255, 1));
+ public NumberSetting blue = addSetting(new NumberSetting("azul", "cantidad de azul", 255, 0, 255, 1));
+
+ public BooleanSetting rainbow = addSetting(new BooleanSetting("arcoíris", "gay.", false));
+ public NumberSetting rainbowSpeed = addSetting(new NumberSetting("velocidad del arcoíris", "velocidad del arcoíris", 1000, 0, 10000, 2));
+
+ public NumberSetting alpha = addSetting(new NumberSetting("opacidad", "antitransparencia", 255, 0, 255, 1));
+ public BooleanSetting shadow = addSetting(new BooleanSetting("sombra", "texto con sombra", true));
+
+ public BooleanSetting dontOverride = addSetting(new BooleanSetting("no sobreescribir", "evita dibujar por encima de otros elementos de la interfaz", true));
+
+ public EnumSetting timeFormat = addSetting(new EnumSetting<>("formato de la hora", "12h o 24h", TimeFormat.class, TimeFormat.TWENTY_FOUR_HOUR));
+ public NumberSetting timezone = addSetting(new NumberSetting("zona horaria", "zona horaria en UTC+n", 1, -6, 6, 1));
+
+ public BooleanSetting coords = addSetting(new BooleanSetting("coordenadas", "mostrar coordenadas", true));
+ public StringSetting customText = addSetting(new StringSetting("texto custom", "marca de agua (dejar vacío para quitar)", "ESCROTO", 40));
+ public BooleanSetting fps = addSetting(new BooleanSetting("fps", "mostrar frames por segundo", true));
+ public BooleanSetting tps = addSetting(new BooleanSetting("tps", "mostrar tasa de ticks por segundo del server", true));
+ public BooleanSetting time = addSetting(new BooleanSetting("hora", "mostrar hora actual", true));
+
+ public HUD() {
+ super("HUD", "superposición de la pantalla con info. adicional");
+
+ rainbow.onUpdate(v -> {
+ rainbowSpeed.setVisible(v);
+ red.setVisible(!v);
+ green.setVisible(!v);
+ blue.setVisible(!v);
+ });
+
+ time.onUpdate(v -> {
+ timeFormat.setVisible(v);
+ timezone.setVisible(v);
+ });
+ }
+
+ public enum TimeFormat {
+ TWENTY_FOUR_HOUR("24h"),
+ TWELVE_HOUR("12h");
+
+ final String name;
+ TimeFormat(String name) { this.name = name; }
+ @Override public String toString() { return name; }
+ }
+}
diff --git a/src/main/java/me/retucio/camtweaks/ui/HUD.java b/src/main/java/me/retucio/camtweaks/ui/HUD.java
index 4606fca..65fb3d6 100644
--- a/src/main/java/me/retucio/camtweaks/ui/HUD.java
+++ b/src/main/java/me/retucio/camtweaks/ui/HUD.java
@@ -1,8 +1,20 @@
package me.retucio.camtweaks.ui;
+import me.retucio.camtweaks.event.SubscribeEvent;
+import me.retucio.camtweaks.event.events.PacketEvent;
+import me.retucio.camtweaks.module.ModuleManager;
+import me.retucio.camtweaks.module.modules.Freecam;
+import me.retucio.camtweaks.module.modules.HUD.TimeFormat;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawContext;
+import net.minecraft.client.gui.screen.ChatScreen;
import net.minecraft.client.render.RenderTickCounter;
+import net.minecraft.util.math.Vec3d;
+
+import java.awt.Color;
+import java.time.LocalTime;
+import java.time.ZoneOffset;
+import java.time.format.DateTimeFormatter;
// en un principio esto iba a mostrar en pantalla los módulos activados, pero me parece innecesario. se queda aquí por si acaso
// igual lo uso para algo...
@@ -10,5 +22,89 @@ public class HUD {
private static final MinecraftClient mc = MinecraftClient.getInstance();
- public static void render(DrawContext ctx, RenderTickCounter tc) {}
+ private long lastPacketTime = 0;
+ private static float estimatedTPS = 20f;
+
+ public static void render(DrawContext ctx, RenderTickCounter tc) {
+ if (ModuleManager.INSTANCE == null || mc.player == null || mc.cameraEntity == null) return;
+ me.retucio.camtweaks.module.modules.HUD hud = ModuleManager.INSTANCE.getModuleByClass(me.retucio.camtweaks.module.modules.HUD.class);
+
+ int width = mc.getWindow().getScaledWidth();
+ int height = mc.getWindow().getScaledHeight();
+
+ Color color;
+ if (hud.rainbow.isEnabled()) {
+ float speed = 10001 - hud.rainbowSpeed.getFloatValue();
+ float hue = (System.currentTimeMillis() % (int) speed) / speed;
+ Color gamning = Color.getHSBColor(hue, 1, 1);
+ color = new Color(gamning.getRed(), gamning.getGreen(), gamning.getBlue(), hud.alpha.getIntValue());
+ } else {
+ color = new Color(hud.red.getIntValue(), hud.green.getIntValue(), hud.blue.getIntValue(), hud.alpha.getIntValue());
+ }
+ boolean shadow = hud.shadow.isEnabled();
+
+ if (hud.isEnabled()) {
+
+ // coordenadas
+ if (hud.coords.isEnabled()) {
+ Vec3d coords;
+ Freecam freecam = ModuleManager.INSTANCE.getModuleByClass(Freecam.class);
+ if (freecam.isEnabled())
+ coords = new Vec3d(
+ freecam.getX(tc.getDynamicDeltaTicks()),
+ freecam.getY(tc.getDynamicDeltaTicks()),
+ freecam.getZ(tc.getDynamicDeltaTicks())
+ );
+ else
+ coords = mc.player.getPos();
+
+ String text = (int) coords.x + " " + (int) coords.y + " " + (int) coords.z;
+ ctx.drawText(mc.textRenderer, text,
+ width - mc.textRenderer.getWidth(text) - 2,
+ height - mc.textRenderer.fontHeight - 2,
+ color.getRGB(), shadow);
+ }
+
+ // fps y tps
+ if (hud.fps.isEnabled())
+ ctx.drawText(mc.textRenderer, "FPS: " + mc.getCurrentFps(), 2, 2, color.getRGB(), shadow);
+
+ if (hud.tps.isEnabled())
+ ctx.drawText(mc.textRenderer, "TPS: " + estimatedTPS, 2, 4 + mc.textRenderer.fontHeight, color.getRGB(), shadow);
+
+ // marca de agua
+ if (!hud.customText.getValue().isEmpty()) {
+ int y;
+ if (!mc.player.getActiveStatusEffects().isEmpty() && hud.dontOverride.isEnabled()) y = 26;
+ else y = 2;
+ ctx.drawText(mc.textRenderer, hud.customText.getValue(), width - mc.textRenderer.getWidth(hud.customText.getValue()) - 2, y, color.getRGB(), shadow);
+ }
+
+ // hora real
+ if (hud.time.isEnabled()) {
+ int y;
+ if (mc.currentScreen instanceof ChatScreen && hud.dontOverride.isEnabled()) y = height - mc.textRenderer.fontHeight - 14;
+ else y = height - mc.textRenderer.fontHeight - 2;
+
+ ZoneOffset offset = ZoneOffset.ofHours(hud.timezone.getIntValue());
+ LocalTime now = LocalTime.now(offset);
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern(hud.timeFormat.is(TimeFormat.TWENTY_FOUR_HOUR) ? "HH:mm" : "hh:mm a");
+ String time = now.format(formatter);
+
+ ctx.drawText(mc.textRenderer, time, 2, y, color.getRGB(), shadow);
+ }
+ }
+ }
+
+ @SubscribeEvent
+ public void onReceivePacket(PacketEvent.Receive event) {
+ // estimar el tps teniendo en cuenta el tiempo entre paquetes
+ long now = System.currentTimeMillis();
+ if (lastPacketTime > 0) {
+ long diff = now - lastPacketTime; // ms entre paquetes
+ float tps = 1000f / diff;
+ estimatedTPS = Math.min(20.0f, tps);
+ }
+ lastPacketTime = now;
+ }
}
\ No newline at end of file