v1.5
This commit is contained in:
1 parent
8891a57c7c
commit
a6a6f1261e
29 files changed
+750
-195
No files matched your search
@@ -1,6 +1,6 @@
|
||||
# jenny's mod 2 100% real
|
||||
|
||||
mod para Minecraft Fabric 1.21.6 que añade algunas cosas QOL, mayormente relacionadas a la cámara.
|
||||
mod para Minecraft Fabric 1.21.10 que añade algunas cosas QOL, mayormente relacionadas a la cámara.
|
||||
|
||||
## instalación
|
||||
|
||||
@@ -10,8 +10,8 @@ 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 (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
|
||||
asegúrate de tener una version de Minecraft y Fabric compatibles con el mod (MC `1.21.10`; Fabric `0.138.3`)
|
||||
es posible que haya problemas al usarlo junto a otros mods, especialmente junto a otros clientes, pues pueden conflictar entre ellos.
|
||||
|
||||
### para frikis de 200 de iq
|
||||
1. clona el respositorio (`git clone https://github.com/retuci0/camera-tweaks`)
|
||||
@@ -23,9 +23,11 @@ es posible que hayan problemas al usarlo junto a otros mods, especialmente otros
|
||||
|
||||
`shift derecho` por defecto para abrir la interfaz
|
||||
|
||||
`pág. arriba` por defecto para abrir el editor del hud
|
||||
|
||||
`$` como prefijo por defecto para comandos (se autocompletan)
|
||||
|
||||
algunos módulos tienen teclas asignadas por defecto, asígnales `ESC` para desactivar sus teclas
|
||||
algunos módulos tienen teclas asignadas por defecto, asígnales `ESC` para desactivar sus atajos de teclado
|
||||
|
||||
## interfaz
|
||||
|
||||
@@ -51,6 +53,7 @@ algunos módulos tienen teclas asignadas por defecto, asígnales `ESC` para desa
|
||||
<img src="screenshots/crits.png" alt="críticos">
|
||||
<img src="screenshots/fullbright.png" alt="fullbright en modo gamma cambiando el color de los shaders">
|
||||
<img src="screenshots/hud.png" alt="HUD">
|
||||
<img src="screenshots/hudeditor.png" alt="editor de HUD">
|
||||
|
||||
## contibuciones
|
||||
|
||||
@@ -58,4 +61,8 @@ sí por favor
|
||||
|
||||
## licencia
|
||||
|
||||
no sé, haz lo que quieras con esto, es puta basura xd
|
||||
no sé, haz lo que quieras con esto, es puta basura xd
|
||||
|
||||
aunque estaría guay que acreditases
|
||||
|
||||
pero bueno
|
||||
+7
-11
@@ -1,23 +1,19 @@
|
||||
# v1.4
|
||||
# v1.5
|
||||
|
||||
## novedades
|
||||
|
||||
- actualización a la 1.21.10
|
||||
sigo vivo (creo)
|
||||
|
||||
### adiciones
|
||||
|
||||
interfaz en portales: te permite interactuar con interfaces estando dentro de un bloque de portal del nether
|
||||
- editor de hud bastante básico pero por lo general funcional (`pág. arriba` por defecto). viene con muchos bugs, ojalá me caiga un rayo.
|
||||
|
||||
### arreglos / mejoras
|
||||
|
||||
- ahora puedes elegir con qué items aparece el nametag, útil para poder distinguir unos items de otros
|
||||
- ahora F1 también oculta los elementos del HUD, y ya no se muestra en la pantalla de inicio
|
||||
- ahora los items con el nombre cambiado usarán este en sus nametags, y estarán en cursiva
|
||||
- ahora puedes elegir si el contorno de los bloques se renderiza en modo cámara libre
|
||||
- ya no se activarán / desactivarán módulos cuando la tecla F3 esté presionada, para evitar intervenir en combinaciones de teclas con F3
|
||||
- arreglado lo de la ceguera y la oscuridad de NoRender (en un principio)
|
||||
- si una tecla ya está cogida por otra acción, a menos que teclas multimódulos esté activado, se previene configurar esta tecla a un módulo
|
||||
- poco más la verdad
|
||||
- ya no salta un error al hacer una captura con los módulos `capturas de pantalla` y `chat plus` activos
|
||||
- ahora la telemetría (abuso de privacidad al usuario de microshit) está desactivado por huevos. si quieres activarlo te jodes.
|
||||
- ahora ya no puedes abrir interfaces del mod si no estás en un mundo
|
||||
- mejorada la seguridad de algunas operaciones
|
||||
|
||||
## problemas reconocidos
|
||||
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@ loader_version=0.17.3
|
||||
loom_version=1.11-SNAPSHOT
|
||||
|
||||
# Mod Properties
|
||||
mod_version=1.4
|
||||
mod_version=1.5
|
||||
maven_group=me.retucio
|
||||
archives_base_name=camtweaks
|
||||
|
||||
|
||||
@@ -8,6 +8,8 @@ import me.retucio.camtweaks.module.settings.StringSetting;
|
||||
|
||||
public class HUD extends Module {
|
||||
|
||||
public KeySetting editorKey = addSetting(new KeySetting(""))
|
||||
|
||||
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));
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 243 KiB |
@@ -16,7 +16,10 @@ import me.retucio.camtweaks.event.events.camtweaks.LoadModuleManagerEvent;
|
||||
import me.retucio.camtweaks.module.Module;
|
||||
import me.retucio.camtweaks.module.ModuleManager;
|
||||
|
||||
import me.retucio.camtweaks.module.modules.HUD;
|
||||
import me.retucio.camtweaks.ui.ClickGUI;
|
||||
import me.retucio.camtweaks.ui.HudEditorScreen;
|
||||
import me.retucio.camtweaks.ui.HudRenderer;
|
||||
import me.retucio.camtweaks.ui.buttons.BindButton;
|
||||
import me.retucio.camtweaks.ui.buttons.SettingButton;
|
||||
import me.retucio.camtweaks.ui.buttons.TextButton;
|
||||
@@ -64,6 +67,7 @@ public class CameraTweaks implements ClientModInitializer {
|
||||
EVENT_BUS.register(this);
|
||||
EVENT_BUS.register(MiscUtil.class);
|
||||
EVENT_BUS.register(ChatUtil.class);
|
||||
EVENT_BUS.register(HudRenderer.class);
|
||||
|
||||
Lists.init();
|
||||
|
||||
@@ -74,6 +78,7 @@ public class CameraTweaks implements ClientModInitializer {
|
||||
EVENT_BUS.post(new LoadCommandManagerEvent());
|
||||
|
||||
ClickGUI.INSTANCE = new ClickGUI();
|
||||
HudEditorScreen.INSTANCE = new HudEditorScreen();
|
||||
EVENT_BUS.post(new LoadClickGUIEvent());
|
||||
|
||||
ConfigManager.load();
|
||||
@@ -105,12 +110,15 @@ public class CameraTweaks implements ClientModInitializer {
|
||||
boolean anyFocused = isAnySettingButtonFocused() || ClickGUI.INSTANCE.getSearchBar().isFocused();
|
||||
ClickGUI.INSTANCE.setAnyFocused(anyFocused);
|
||||
|
||||
if (action == GLFW.GLFW_PRESS) {
|
||||
if (action != GLFW.GLFW_RELEASE) {
|
||||
if (BindCommand.onKeyPress(key)) return;
|
||||
if (action == GLFW.GLFW_PRESS) {
|
||||
handleModuleToggle(key, anyFocused);
|
||||
handleClickGUIKey(key, anyFocused);
|
||||
handleHudEditorKey(key, anyFocused);
|
||||
}
|
||||
handleSettingButtonsKey(key, action);
|
||||
handleModuleToggle(key, anyFocused);
|
||||
handleClickGUIKey(key, anyFocused);
|
||||
} else if (action == GLFW.GLFW_RELEASE && !anyFocused) {
|
||||
} else if (!anyFocused) {
|
||||
handleModuleRelease(key);
|
||||
}
|
||||
}
|
||||
@@ -151,10 +159,11 @@ public class CameraTweaks implements ClientModInitializer {
|
||||
// maneja la lógica de apertura de la interfaz
|
||||
private void handleClickGUIKey(int key, boolean anyFocused) {
|
||||
if (key != ClientSettingsFrame.guiSettings.getKey() || anyFocused) return;
|
||||
if (!(mc != null && mc.world != null && mc.player != null)) return;
|
||||
|
||||
// al parecer esto hace que con la tecla de la interfaz puedas ir cambiando de splash text en la pantalla del título
|
||||
// pero me ha hecho gracia así que así se queda
|
||||
if (mc.currentScreen != ClickGUI.INSTANCE && !(mc.currentScreen instanceof TitleScreen)) {
|
||||
if (mc.currentScreen != ClickGUI.INSTANCE) {
|
||||
prevScreen = mc.currentScreen;
|
||||
mc.setScreen(ClickGUI.INSTANCE);
|
||||
} else {
|
||||
@@ -163,6 +172,20 @@ public class CameraTweaks implements ClientModInitializer {
|
||||
}
|
||||
}
|
||||
|
||||
// manejar la lógica de apertura del editor de elementos del hud, con la misma lógica que handleClickGUIKey()
|
||||
private void handleHudEditorKey(int key, boolean anyFocused) {
|
||||
if (key != ModuleManager.INSTANCE.getModuleByClass(HUD.class).editorKey.getKey() || anyFocused) return;
|
||||
if (!(mc != null && mc.world != null && mc.player != null)) return;
|
||||
|
||||
if (mc.currentScreen != HudEditorScreen.INSTANCE) {
|
||||
prevScreen = mc.currentScreen;
|
||||
mc.setScreen(HudEditorScreen.INSTANCE);
|
||||
} else {
|
||||
HudEditorScreen.INSTANCE.close();
|
||||
mc.setScreen(prevScreen);
|
||||
}
|
||||
}
|
||||
|
||||
// se ocupa de apagar los módulos que tengan configurado hacerlo tras soltar su tecla
|
||||
private void handleModuleRelease(int key) {
|
||||
if (mc.currentScreen != null && mc.currentScreen != ClickGUI.INSTANCE) return;
|
||||
|
||||
@@ -26,11 +26,16 @@ public class ClientConfig {
|
||||
// nombre del frame -> FrameData (que contiene extended, x & y)
|
||||
public Map<String, FrameData> extendableFrames = new HashMap<>();
|
||||
|
||||
// id del elemento del hud -> posición (x, y)
|
||||
public Map<String, int[]> hudPositions = new HashMap<>();
|
||||
|
||||
// id del elemento del hud -> true: visible / false: no visible
|
||||
public Map<String, Boolean> hudVisibilities = new HashMap<>();
|
||||
|
||||
public ClientConfig() {
|
||||
EVENT_BUS.register(this);
|
||||
}
|
||||
|
||||
|
||||
@SubscribeEvent
|
||||
public void onToggleModule(ToggleModuleEvent event) {
|
||||
ConfigManager.setModuleState(event.getModule());
|
||||
|
||||
@@ -114,7 +114,7 @@ public class ConfigManager {
|
||||
public static void setFramePosition(SettingsFrame frame) {
|
||||
ensureConfig();
|
||||
config.settingsFrames.put(frame.module.getName(), new int[]{frame.x, frame.y});
|
||||
ConfigManager.save();
|
||||
save();
|
||||
}
|
||||
|
||||
public static void setExtendableFrame(String key, ClientConfig.FrameData data) {
|
||||
@@ -123,6 +123,19 @@ public class ConfigManager {
|
||||
save();
|
||||
}
|
||||
|
||||
public static void setHudPosition(String id, int x, int y) {
|
||||
ensureConfig();
|
||||
config.hudPositions.put(id, new int[]{x, y});
|
||||
save();
|
||||
}
|
||||
|
||||
public static void setHudVisibility(String id, Boolean visible) {
|
||||
ensureConfig();
|
||||
config.hudVisibilities.put(id, visible);
|
||||
save();
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
public static void applySetting(Module parent, AbstractSetting setting) {
|
||||
String id = parent.getName() + ":" + setting.getName();
|
||||
|
||||
@@ -5,7 +5,7 @@ import me.retucio.camtweaks.module.ModuleManager;
|
||||
import me.retucio.camtweaks.module.modules.ChatPlus;
|
||||
import me.retucio.camtweaks.module.modules.Freecam;
|
||||
import me.retucio.camtweaks.module.modules.NoRender;
|
||||
import me.retucio.camtweaks.ui.HUD;
|
||||
import me.retucio.camtweaks.ui.HudRenderer;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.client.gui.hud.InGameHud;
|
||||
@@ -66,7 +66,7 @@ public abstract class InGameHudMixin {
|
||||
|
||||
@Inject(method = "render", at = @At("RETURN"))
|
||||
private void renderHUD(DrawContext ctx, RenderTickCounter tc, CallbackInfo ci) {
|
||||
HUD.render(ctx, tc);
|
||||
HudRenderer.render(ctx, tc);
|
||||
}
|
||||
|
||||
@ModifyExpressionValue(method = "renderCrosshair", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/option/Perspective;isFirstPerson()Z"))
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package me.retucio.camtweaks.mixin;
|
||||
|
||||
import com.llamalad7.mixinextras.injector.ModifyReturnValue;
|
||||
import me.retucio.camtweaks.CameraTweaks;
|
||||
import me.retucio.camtweaks.event.events.OpenScreenEvent;
|
||||
import me.retucio.camtweaks.event.events.ShutdownEvent;
|
||||
@@ -10,6 +11,7 @@ import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import static me.retucio.camtweaks.CameraTweaks.EVENT_BUS;
|
||||
|
||||
@@ -37,4 +39,9 @@ public abstract class MinecraftClientMixin {
|
||||
OpenScreenEvent event = EVENT_BUS.post(new OpenScreenEvent(screen));
|
||||
if (event.isCancelled()) ci.cancel();
|
||||
}
|
||||
|
||||
@Inject(method = "isTelemetryEnabledByApi", at = @At("RETURN"), cancellable = true)
|
||||
private void disableMicropenisTelemetryShi(CallbackInfoReturnable<Boolean> cir) {
|
||||
cir.setReturnValue(false);
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,8 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static me.retucio.camtweaks.CameraTweaks.mc;
|
||||
|
||||
@Mixin(ScreenshotRecorder.class)
|
||||
public abstract class ScreenshotRecorderMixin {
|
||||
|
||||
@@ -35,7 +37,8 @@ public abstract class ScreenshotRecorderMixin {
|
||||
|
||||
if (!screenshotPlus.isEnabled()) return;
|
||||
|
||||
screenshotPlus.sendScreenshotMessage();
|
||||
// por los threads o lo que sea
|
||||
mc.execute(screenshotPlus::sendScreenshotMessage);
|
||||
|
||||
switch (screenshotPlus.defaultAction.getValue()) {
|
||||
case COPY -> screenshotPlus.copyScreenshot(nativeImage);
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package me.retucio.camtweaks.mixin;
|
||||
|
||||
import net.minecraft.client.session.telemetry.TelemetryManager;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Coerce;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
@Mixin(TelemetryManager.class)
|
||||
public class TelemetryManagerMixin {
|
||||
|
||||
@Redirect(method = "computeSender", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;isTelemetryEnabledByApi()Z"))
|
||||
private boolean disableTelemetry(@Coerce Object minecraftClient) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package me.retucio.camtweaks.mixin;
|
||||
|
||||
import com.mojang.authlib.yggdrasil.YggdrasilUserApiService;
|
||||
import com.mojang.authlib.yggdrasil.response.UserAttributesResponse;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
// código robado de: https://github.com/kb-1000/no-telemetry
|
||||
|
||||
@Mixin(YggdrasilUserApiService.class)
|
||||
public abstract class YggdrasilUserApiServiceMixin {
|
||||
|
||||
@Redirect(method = "fetchProperties", at = @At(value = "INVOKE", target = "Lcom/mojang/authlib/yggdrasil/response/UserAttributesResponse$Privileges;getTelemetry()Z", remap = false), remap = false, require = 0)
|
||||
private boolean getTelemetry(UserAttributesResponse.Privileges instance) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,21 @@
|
||||
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;
|
||||
import me.retucio.camtweaks.module.settings.*;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
/** lógica del HUD manejada en:
|
||||
* @see me.retucio.camtweaks.ui.HudRenderer
|
||||
* @see me.retucio.camtweaks.ui.widgets.HudElement
|
||||
* @see me.retucio.camtweaks.ui.HudEditorScreen
|
||||
*/
|
||||
|
||||
public class HUD extends Module {
|
||||
|
||||
// editor
|
||||
public KeySetting editorKey = addSetting(new KeySetting("tecla del editor", "tecla asignada al editor de elementos del hud", GLFW.GLFW_KEY_PAGE_UP));
|
||||
|
||||
// colores
|
||||
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));
|
||||
@@ -16,46 +24,22 @@ public class HUD extends Module {
|
||||
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));
|
||||
|
||||
// ajustes
|
||||
public BooleanSetting showOnF3 = addSetting(new BooleanSetting("mostrar en F3", "renderizar HUD en el menú de debug", false));
|
||||
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> 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 EnumSetting<TimeFormat> timeFormat = addSetting(new EnumSetting<>("formato de la hora", "12h o 24h", TimeFormat.class, TimeFormat.TWENTY_FOUR_HOUR));
|
||||
public StringSetting customText = addSetting(new StringSetting("texto custom", "marca de agua (dejar vacío para quitar)", "adolf jitler inshtagram feishbuc twiter", 40));
|
||||
|
||||
// elementos
|
||||
public BooleanSetting coords = addSetting(new BooleanSetting("coordenadas", "mostrar coordenadas", true));
|
||||
public NumberSetting coordsX = new NumberSetting("X de las coordenadas", ".", -1, -1, 1920, 1);
|
||||
public NumberSetting coordsY = new NumberSetting("Y de las coordenadas", ".", -1, -1, 1080, 1);
|
||||
|
||||
public StringSetting customText = addSetting(new StringSetting("texto custom", "marca de agua (dejar vacío para quitar)", "", 40));
|
||||
public NumberSetting customTextX = new NumberSetting("X de la marca de agua", ".", -1, -1, 1920, 1);
|
||||
public NumberSetting customTextY = new NumberSetting("Y de la marca de agua", ".", -1, -1, 1080, 1);
|
||||
|
||||
public BooleanSetting fps = addSetting(new BooleanSetting("fps", "mostrar frames por segundo", true));
|
||||
public NumberSetting fpsX = new NumberSetting("X de los fps", ".", -1, -1, 1920, 1);
|
||||
public NumberSetting fpsY = new NumberSetting("Y de los fps", ".", -1, -1, 1080, 1);
|
||||
|
||||
public BooleanSetting tps = addSetting(new BooleanSetting("tps", "mostrar tasa de ticks por segundo del server", true));
|
||||
public NumberSetting tpsX = new NumberSetting("X del tps", ".", -1, -1, 1920, 1);
|
||||
public NumberSetting tpsY = new NumberSetting("Y del tps", ".", -1, -1, 1080, 1);
|
||||
|
||||
public BooleanSetting time = addSetting(new BooleanSetting("hora", "mostrar hora actual", true));
|
||||
public NumberSetting timeX = new NumberSetting("X de la hora", ".", -1, -1, 1920, 1);
|
||||
public NumberSetting timeY = new NumberSetting("Y de la hora", ".", -1, -1, 1080, 1);
|
||||
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);
|
||||
rainbowSpeed.setVisible(v);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -97,9 +97,11 @@ public class Nametags extends Module {
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public String getOwnerName(LazyEntityReference<LivingEntity> owner) {
|
||||
// si el dueño está en línea
|
||||
LivingEntity ownerEntity = owner.resolve((EntityQueriable<? extends UniquelyIdentifiable>) mc.world, LivingEntity.class);
|
||||
if (ownerEntity instanceof PlayerEntity playerEntity) return playerEntity.getName().getString();
|
||||
// si el dueño está en línea (de manera segura)
|
||||
if (mc.world instanceof EntityQueriable<?> queriableWorld) {
|
||||
LivingEntity ownerEntity = owner.resolve(queriableWorld, LivingEntity.class);
|
||||
if (ownerEntity instanceof PlayerEntity playerEntity) return playerEntity.getName().getString();
|
||||
}
|
||||
|
||||
// mirar si ya está en la caché
|
||||
UUID uuid = owner.getUuid();
|
||||
|
||||
@@ -15,13 +15,14 @@ import me.retucio.camtweaks.ui.frames.ModuleFrame;
|
||||
import me.retucio.camtweaks.ui.frames.SettingsFrame;
|
||||
import me.retucio.camtweaks.ui.widgets.ScrollBarWidget;
|
||||
import me.retucio.camtweaks.ui.widgets.SearchBarWidget;
|
||||
import me.retucio.camtweaks.util.ChatUtil;
|
||||
import me.retucio.camtweaks.util.KeyUtil;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.Click;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -248,8 +249,8 @@ public class ClickGUI extends Screen {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void applyBlur(DrawContext context) {
|
||||
if (guiSettings.blur.isEnabled()) super.applyBlur(context);
|
||||
protected void applyBlur(DrawContext ctx) {
|
||||
if (guiSettings.blur.isEnabled()) super.applyBlur(ctx);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
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.gui.screen.TitleScreen;
|
||||
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...
|
||||
public class HUD {
|
||||
|
||||
private static final MinecraftClient mc = MinecraftClient.getInstance();
|
||||
|
||||
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.getCameraEntity() == null
|
||||
|| mc.currentScreen instanceof TitleScreen
|
||||
|| mc.options.hudHidden)
|
||||
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.getEntityPos();
|
||||
|
||||
String text = (int) coords.x + " " + (int) coords.y + " " + (int) coords.z;
|
||||
ctx.drawText(mc.textRenderer, text,
|
||||
(hud.coordsX.getIntValue() == -1) ? width - mc.textRenderer.getWidth(text) - 2 : hud.coordsX.getIntValue(),
|
||||
(hud.coordsY.getIntValue() == -1) ? height - mc.textRenderer.fontHeight - 2 : hud.coordsY.getIntValue(),
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,215 @@
|
||||
package me.retucio.camtweaks.ui;
|
||||
|
||||
import me.retucio.camtweaks.config.ConfigManager;
|
||||
import me.retucio.camtweaks.ui.frames.ClientSettingsFrame;
|
||||
import me.retucio.camtweaks.ui.widgets.HudElement;
|
||||
import me.retucio.camtweaks.util.Colors;
|
||||
import me.retucio.camtweaks.util.KeyUtil;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.Click;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.input.KeyInput;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class HudEditorScreen extends Screen {
|
||||
|
||||
public static HudEditorScreen INSTANCE;
|
||||
private final MinecraftClient mc = MinecraftClient.getInstance();
|
||||
|
||||
private final List<HudElement> elements = new ArrayList<>();
|
||||
@Nullable private HudElement selected = null;
|
||||
|
||||
private boolean dragging = false;
|
||||
private int dragOffsetX, dragOffsetY;
|
||||
|
||||
public HudEditorScreen() {
|
||||
super(Text.literal("editor del hud"));
|
||||
}
|
||||
|
||||
public void setElements(List<HudElement> elements) {
|
||||
this.elements.clear();
|
||||
this.elements.addAll(elements);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(DrawContext ctx, int mouseX, int mouseY, float delta) {
|
||||
ctx.fill(0, 0, this.width, this.height, Colors.hudEditorScreenBackgroundColor.getRGB());
|
||||
|
||||
// texto con instrucciones
|
||||
ctx.drawCenteredTextWithShadow(mc.textRenderer, "EDITOR DEL HUD", this.width / 2, this.height / 2 - mc.textRenderer.fontHeight, -1);
|
||||
ctx.drawCenteredTextWithShadow(mc.textRenderer,
|
||||
Text.literal("arrastrar para mover · click derecho para alternar visibilidad · esc para guardar y salir · shift + click derecho para restablecer"),
|
||||
this.width / 2, this.height / 2 + mc.textRenderer.fontHeight, Colors.instructionsTextColor.getRGB());
|
||||
|
||||
// dibujar elementos
|
||||
for (HudElement element : elements)
|
||||
element.renderPreview(ctx);
|
||||
|
||||
// tooltips con información sobre el elemento sobre el que está el puntero del ratón
|
||||
if (!dragging) {
|
||||
for (HudElement element : elements) {
|
||||
if (!element.isVisible()) continue;
|
||||
|
||||
if (element.contains(mouseX, mouseY)) {
|
||||
List<Text> tooltip = getTooltipFor(element);
|
||||
if (!tooltip.isEmpty()) ctx.drawTooltip(mc.textRenderer, tooltip, mouseX + 7, mouseY + 20);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
super.render(ctx, mouseX, mouseY, delta);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseClicked(Click click, boolean doubled) {
|
||||
int mouseX = (int) click.x();
|
||||
int mouseY = (int) click.y();
|
||||
|
||||
// iterar de atrás a adelante para respetar el orden z
|
||||
for (int i = elements.size() - 1; i >= 0; i--) {
|
||||
HudElement element = elements.get(i);
|
||||
if (element.contains(mouseX, mouseY)) {
|
||||
selected = element;
|
||||
|
||||
if (click.button() == 0) {
|
||||
dragging = true;
|
||||
|
||||
dragOffsetX = mouseX - element.getX();
|
||||
dragOffsetY = mouseY - element.getY();
|
||||
|
||||
// traer el elemento seleccionado al frente
|
||||
elements.remove(i);
|
||||
elements.add(element);
|
||||
return true;
|
||||
|
||||
} else if (click.button() == 1) {
|
||||
if (mc.isShiftPressed())
|
||||
selected.resetPosition();
|
||||
else
|
||||
selected.setVisible(!selected.isVisible());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return super.mouseClicked(click, doubled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseDragged(Click click, double deltaX, double deltaY) {
|
||||
if (!dragging || selected == null || click.button() != 0)
|
||||
return super.mouseDragged(click, deltaX, deltaY);
|
||||
|
||||
int mouseX = (int) click.x();
|
||||
int mouseY = (int) click.y();
|
||||
|
||||
int newX = mouseX - dragOffsetX;
|
||||
int newY = mouseY - dragOffsetY;
|
||||
|
||||
// clampear para evitar que los elementos se salgan de la pantalla
|
||||
newX = Math.max(1, Math.min(newX, width - selected.getWidth() - 1));
|
||||
newY = Math.max(1, Math.min(newY, height - selected.getHeight() - 1));
|
||||
|
||||
selected.setPosition(newX, newY);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseReleased(Click click) {
|
||||
if (dragging && click.button() == 0) {
|
||||
dragging = false;
|
||||
savePositionsToConfig(); // guardar inmediatamente al config
|
||||
return true;
|
||||
} else if (click.button() == 1 && selected != null) {
|
||||
saveVisibilitiesToConfig();
|
||||
selected = null;
|
||||
return true;
|
||||
}
|
||||
selected = null;
|
||||
return super.mouseReleased(click);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyPressed(KeyInput input) {
|
||||
// esc para guardar y salir
|
||||
if (input.key() == GLFW.GLFW_KEY_ESCAPE) {
|
||||
saveAndClose();
|
||||
return true;
|
||||
}
|
||||
return super.keyPressed(input);
|
||||
}
|
||||
|
||||
private void savePositionsToConfig() {
|
||||
for (HudElement element : elements)
|
||||
ConfigManager.setHudPosition(element.getId(), element.getX(), element.getY());
|
||||
|
||||
ConfigManager.save();
|
||||
}
|
||||
|
||||
private void saveVisibilitiesToConfig() {
|
||||
for (HudElement element : elements)
|
||||
ConfigManager.setHudVisibility(element.getId(), element.isVisible());
|
||||
|
||||
ConfigManager.save();
|
||||
}
|
||||
|
||||
private void saveAndClose() {
|
||||
savePositionsToConfig();
|
||||
selected = null;
|
||||
mc.setScreen(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void applyBlur(DrawContext ctx) {
|
||||
if (ClientSettingsFrame.guiSettings.blur.isEnabled()) super.applyBlur(ctx);
|
||||
}
|
||||
|
||||
public boolean isSelected(HudElement element) {
|
||||
return selected == element;
|
||||
}
|
||||
|
||||
// para los tooltips
|
||||
private List<Text> getTooltipFor(HudElement element) {
|
||||
List<Text> list = new ArrayList<>();
|
||||
|
||||
switch (element.getId()) {
|
||||
case "coords" -> {
|
||||
list.add(Text.literal("coordenadas"));
|
||||
list.add(Text.literal("te muestra tu posición en el mundo en coordenadas XYZ"));
|
||||
}
|
||||
case "fps" -> {
|
||||
list.add(Text.literal("FPS"));
|
||||
list.add(Text.literal("te muestra la tasa de fotogramas por segundo del juego"));
|
||||
}
|
||||
case "tps" -> {
|
||||
list.add(Text.literal("tps"));
|
||||
list.add(Text.literal("te muestra la tasa de ticks por segundo del servidor (0-20)"));
|
||||
}
|
||||
case "customText" -> {
|
||||
list.add(Text.literal("texto custom"));
|
||||
list.add(Text.literal("te permite renderizar texto al gusto"));
|
||||
}
|
||||
case "time" -> {
|
||||
list.add(Text.literal("hora"));
|
||||
list.add(Text.literal("te muestra la hora y los minutos de la zona horaria escogida"));
|
||||
}
|
||||
default -> {
|
||||
list.add(Text.literal(element.getId()));
|
||||
list.add(Text.literal("."));
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,202 @@
|
||||
package me.retucio.camtweaks.ui;
|
||||
|
||||
import me.retucio.camtweaks.CameraTweaks;
|
||||
import me.retucio.camtweaks.config.ConfigManager;
|
||||
import me.retucio.camtweaks.event.SubscribeEvent;
|
||||
import me.retucio.camtweaks.event.events.PacketEvent;
|
||||
import me.retucio.camtweaks.event.events.camtweaks.UpdateSettingEvent;
|
||||
import me.retucio.camtweaks.module.ModuleManager;
|
||||
import me.retucio.camtweaks.module.modules.Freecam;
|
||||
import me.retucio.camtweaks.module.modules.HUD;
|
||||
import me.retucio.camtweaks.ui.widgets.HudElement;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.client.gui.screen.TitleScreen;
|
||||
import net.minecraft.client.render.RenderTickCounter;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
import java.awt.*;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
public class HudRenderer {
|
||||
|
||||
private static final MinecraftClient mc = MinecraftClient.getInstance();
|
||||
|
||||
private static float estimatedTPS = 20f;
|
||||
private long lastPacketTime = 0;
|
||||
|
||||
private static final Map<String, int[]> positions = ConfigManager.getConfig().hudPositions;
|
||||
private static final Map<String, Boolean> visibilities = ConfigManager.getConfig().hudVisibilities;
|
||||
private static final List<HudElement> elements = new ArrayList<>();
|
||||
private static boolean initialized = false;
|
||||
|
||||
private static HudElement customTextElement = null;
|
||||
|
||||
public static void initElements() {
|
||||
if (initialized) return;
|
||||
initialized = true;
|
||||
|
||||
HUD hud = ModuleManager.INSTANCE.getModuleByClass(HUD.class);
|
||||
|
||||
// coordenadas
|
||||
addElement("coords", 2, mc.getWindow().getScaledHeight() - mc.textRenderer.fontHeight, (ctx, mx, my, delta) -> {
|
||||
drawSnappedText(ctx, getElementText("coords", delta, hud), mx, my, getColor(hud).getRGB(), hud.shadow.isEnabled());
|
||||
});
|
||||
|
||||
// FPS
|
||||
addElement("fps", 2, 2, (ctx, mx, my, delta) -> {
|
||||
drawSnappedText(ctx, getElementText("fps", 0, hud), mx, my, getColor(hud).getRGB(), hud.shadow.isEnabled());
|
||||
});
|
||||
|
||||
// TPS
|
||||
addElement("tps", 2, mc.textRenderer.fontHeight + 4, (ctx, mx, my, delta) -> {
|
||||
drawSnappedText(ctx, getElementText("tps", delta, hud), mx, my, getColor(hud).getRGB(), hud.shadow.isEnabled());
|
||||
});
|
||||
|
||||
// texto custom
|
||||
addElement("customText", mc.getWindow().getScaledWidth() / 2 - mc.textRenderer.getWidth(getElementText("customText", 0, ModuleManager.INSTANCE.getModuleByClass(HUD.class))) / 2, 2, (ctx, mx, my, delta) -> {
|
||||
drawSnappedText(ctx, getElementText("customText", delta, hud), mx, my, getColor(hud).getRGB(), hud.shadow.isEnabled());
|
||||
});
|
||||
|
||||
customTextElement = elements.stream()
|
||||
.filter(e -> e.getId().equals("customText"))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
|
||||
// hora
|
||||
addElement("time", mc.getWindow().getScaledWidth() - mc.textRenderer.getWidth("04:20"), mc.getWindow().getScaledHeight() - mc.textRenderer.fontHeight - 2, (ctx, mx, my, delta) -> {
|
||||
drawSnappedText(ctx, getElementText("time", delta, hud), mx, my, getColor(hud).getRGB(), hud.shadow.isEnabled());
|
||||
});
|
||||
|
||||
HudEditorScreen.INSTANCE.setElements(getElements());
|
||||
}
|
||||
|
||||
private static void addElement(String id, int defX, int defY, HudElement.Renderer renderer) {
|
||||
int[] saved = positions.get(id);
|
||||
Boolean visible = visibilities.get(id);
|
||||
int x = saved == null ? defX : saved[0];
|
||||
int y = saved == null ? defY : saved[1];
|
||||
boolean v = visible == null || visible;
|
||||
if (visibilities.isEmpty()) v = true;
|
||||
|
||||
elements.add(new HudElement(id, defX, defY, x, y, v) {
|
||||
@Override public void render(DrawContext ctx, int mx, int my, float delta) {
|
||||
renderer.render(ctx, x, y, delta);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static Color getColor(HUD hud) {
|
||||
if (hud.rainbow.isEnabled()) {
|
||||
float speed = 10001 - hud.rainbowSpeed.getFloatValue();
|
||||
float hue = (System.currentTimeMillis() % (int) speed) / speed;
|
||||
Color rgb = Color.getHSBColor(hue, 1, 1);
|
||||
return new Color(rgb.getRed(), rgb.getGreen(), rgb.getBlue(), hud.alpha.getIntValue());
|
||||
}
|
||||
return new Color(hud.red.getIntValue(), hud.green.getIntValue(), hud.blue.getIntValue(), hud.alpha.getIntValue());
|
||||
}
|
||||
|
||||
public static void drawSnappedText(DrawContext ctx, String text, int x, int y, int color, boolean shadow) {
|
||||
int textWidth = mc.textRenderer.getWidth(text);
|
||||
int screenWidth = mc.getWindow().getScaledWidth();
|
||||
int screenHeight = mc.getWindow().getScaledHeight();
|
||||
|
||||
boolean snapRight = x > screenWidth / 2;
|
||||
int drawX = snapRight ? x + (textWidth + 2) - textWidth : x;
|
||||
|
||||
// clampear y
|
||||
y = Math.max(0, Math.min(y, screenHeight - mc.textRenderer.fontHeight));
|
||||
|
||||
// clampear x
|
||||
drawX = Math.max(0, Math.min(drawX, screenWidth - textWidth));
|
||||
|
||||
ctx.drawText(mc.textRenderer, text, drawX, y, color, shadow);
|
||||
}
|
||||
|
||||
public static void render(DrawContext ctx, RenderTickCounter tc) {
|
||||
if (ModuleManager.INSTANCE == null
|
||||
|| mc.player == null
|
||||
|| mc.getCameraEntity() == null
|
||||
|| mc.currentScreen instanceof TitleScreen
|
||||
|| mc.options.hudHidden)
|
||||
return;
|
||||
|
||||
HUD hud = ModuleManager.INSTANCE.getModuleByClass(HUD.class);
|
||||
if (!hud.isEnabled()) return;
|
||||
if (mc.getDebugHud().shouldShowDebugHud() && !hud.showOnF3.isEnabled()) return;
|
||||
|
||||
initElements();
|
||||
|
||||
if (mc.currentScreen instanceof HudEditorScreen) return;
|
||||
|
||||
float deltaTime = tc.getDynamicDeltaTicks();
|
||||
for (HudElement element : elements)
|
||||
if (element.isVisible()) element.render(ctx, 0, 0, deltaTime);
|
||||
}
|
||||
|
||||
public static List<HudElement> getElements() {
|
||||
return elements;
|
||||
}
|
||||
|
||||
// texto a dibujar por elemento
|
||||
public static String getElementText(String id, float delta, HUD hud) {
|
||||
switch (id) {
|
||||
case "coords" -> {
|
||||
Freecam freecam = ModuleManager.INSTANCE.getModuleByClass(Freecam.class);
|
||||
Vec3d pos = freecam.isEnabled()
|
||||
? new Vec3d(freecam.getX(delta), freecam.getY(delta), freecam.getZ(delta))
|
||||
: mc.player.getEntityPos();
|
||||
|
||||
return (int) pos.x + " " + (int) pos.y + " " + (int) pos.z;
|
||||
}
|
||||
case "fps" -> {
|
||||
return "FPS: " + mc.getCurrentFps();
|
||||
}
|
||||
case "tps" -> {
|
||||
return "TPS: " + estimatedTPS;
|
||||
}
|
||||
case "customText" -> {
|
||||
return ModuleManager.INSTANCE.getModuleByClass(HUD.class).customText.getValue();
|
||||
}
|
||||
case "time" -> {
|
||||
ZoneOffset offset = ZoneOffset.ofHours(hud.timezone.getIntValue());
|
||||
LocalTime now = LocalTime.now(offset);
|
||||
|
||||
boolean is24 = hud.timeFormat.is(HUD.TimeFormat.TWENTY_FOUR_HOUR);
|
||||
DateTimeFormatter format = DateTimeFormatter.ofPattern(is24 ? "HH:mm" : "hh:mm a");
|
||||
return now.format(format);
|
||||
}
|
||||
default -> { return id; }
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onReceivePacket(PacketEvent.Receive event) {
|
||||
long now = System.currentTimeMillis();
|
||||
if (lastPacketTime > 0) {
|
||||
float tps = 1000f / (now - lastPacketTime);
|
||||
estimatedTPS = Math.min(20f, tps);
|
||||
}
|
||||
lastPacketTime = now;
|
||||
}
|
||||
|
||||
/** para cuando se cambie el valor del texto custom */
|
||||
@SubscribeEvent
|
||||
public void onUpdateSetting(UpdateSettingEvent event) {
|
||||
HUD hud = ModuleManager.INSTANCE.getModuleByClass(HUD.class);
|
||||
|
||||
if (event.getSetting() == hud.customText) {
|
||||
if (customTextElement != null) {
|
||||
int newX = mc.getWindow().getScaledWidth() / 2 - mc.textRenderer.getWidth(hud.customText.getValue()) / 2;
|
||||
customTextElement.setX(newX);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,7 +44,7 @@ public class BindButton extends SettingButton {
|
||||
public void mouseClicked(double mouseX, double mouseY, int button) {
|
||||
if (isHovered((int) mouseX, (int) mouseY) && ClickGUI.INSTANCE.trySelect(this)) {
|
||||
if (button == 0) listening = !listening;
|
||||
else if (button == 1 && KeyUtil.isKeyDown(GLFW.GLFW_KEY_LEFT_SHIFT))
|
||||
else if (button == 1 && mc.isShiftPressed())
|
||||
setting.reset();
|
||||
} else {
|
||||
listening = false;
|
||||
|
||||
@@ -14,6 +14,8 @@ import org.lwjgl.glfw.GLFW;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static me.retucio.camtweaks.CameraTweaks.mc;
|
||||
|
||||
// botón para los ajustes tipo EnumSetting (de modo)
|
||||
public class CycleButton<E extends Enum<E>> extends SettingButton {
|
||||
|
||||
@@ -42,7 +44,7 @@ public class CycleButton<E extends Enum<E>> extends SettingButton {
|
||||
if (isHovered((int) mouseX, (int) mouseY)) {
|
||||
Screen currentScreen = parent.mc.currentScreen;
|
||||
if (currentScreen != null) {
|
||||
if (KeyUtil.isKeyDown(GLFW.GLFW_KEY_LEFT_SHIFT)) {
|
||||
if (mc.isShiftPressed()) {
|
||||
List<Text> lines = new ArrayList<>();
|
||||
lines.add(Text.literal("modos disponibles:"));
|
||||
for (Enum<?> val : setting.getValues()) {
|
||||
|
||||
@@ -13,6 +13,8 @@ import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static me.retucio.camtweaks.CameraTweaks.mc;
|
||||
|
||||
public class ListButton<T> extends SettingButton {
|
||||
|
||||
private final ListSetting<T> setting;
|
||||
@@ -65,7 +67,7 @@ public class ListButton<T> extends SettingButton {
|
||||
public void mouseClicked(double mouseX, double mouseY, int button) {
|
||||
if (isHovered(mouseX, mouseY) && ClickGUI.INSTANCE.trySelect(this)) {
|
||||
// click izquierdo / derecho: abrir marco
|
||||
if (button <= 1 && !KeyUtil.isKeyDown(GLFW.GLFW_KEY_LEFT_SHIFT)) {
|
||||
if (button <= 1 && !mc.isShiftPressed()) {
|
||||
if (ClickGUI.INSTANCE.isSettingsFrameOpen(dummy)) {
|
||||
ClickGUI.INSTANCE.closeSettingsFrame(dummy);
|
||||
return;
|
||||
@@ -74,7 +76,7 @@ public class ListButton<T> extends SettingButton {
|
||||
rebuildDummy();
|
||||
ClickGUI.INSTANCE.openListSettingsFrame(dummy, parent.x + 40, parent.y + 40);
|
||||
// shift + clic derecho: restablecer valores
|
||||
} else if (button == 1 && KeyUtil.isKeyDown(GLFW.GLFW_KEY_LEFT_SHIFT)) {
|
||||
} else if (button == 1 && mc.isShiftPressed()) {
|
||||
setting.reset();
|
||||
refreshDummy();
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ import java.awt.*;
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
import static me.retucio.camtweaks.CameraTweaks.EVENT_BUS;
|
||||
import static me.retucio.camtweaks.CameraTweaks.mc;
|
||||
|
||||
// slider (barrita) para los ajustes numéricos
|
||||
public class SliderButton extends SettingButton {
|
||||
@@ -65,7 +66,7 @@ public class SliderButton extends SettingButton {
|
||||
public void mouseClicked(double mouseX, double mouseY, int button) {
|
||||
if (isHovered((int) mouseX, (int) mouseY) && ClickGUI.INSTANCE.trySelect(this)) {
|
||||
if (button == 0) dragging = true; // arrastrar con el clic izquierdo
|
||||
else if (button == 1 && KeyUtil.isKeyDown(GLFW.GLFW_KEY_LEFT_SHIFT)) // restablecer al valor por defecto con shift izquerdo + clic derecho
|
||||
else if (button == 1 && mc.isShiftPressed()) // restablecer al valor por defecto con shift izquerdo + clic derecho
|
||||
setting.reset();
|
||||
}
|
||||
}
|
||||
@@ -78,7 +79,7 @@ public class SliderButton extends SettingButton {
|
||||
|
||||
@SubscribeEvent
|
||||
public void onKey(KeyEvent event) {
|
||||
// de no ser de esto, si se cierra la interfaz sin haber soltado el ratón mientras se arrastraba el valor, al reabrir la interfaz se seguía arrastrando, aún habiendo soltado ya el clic
|
||||
// de no ser de esto, si se cierra la interfaz sin haber soltado el ratón mientras se arrastraba el valor, al reabrir la interfaz se seguía arrastrando, aún habiendo soltado ya el clic
|
||||
if (event.getKey() == GLFW.GLFW_KEY_ESCAPE || event.getKey() == ClientSettingsFrame.guiSettings.getKey()) dragging = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ public class TextButton extends SettingButton {
|
||||
typing = true;
|
||||
buffer.setLength(0);
|
||||
buffer.append(setting.getValue()); // precargar valor anterior
|
||||
} else if (button == 1 && KeyUtil.isKeyDown(GLFW.GLFW_KEY_LEFT_SHIFT)) {
|
||||
} else if (button == 1 && mc.isShiftPressed()) {
|
||||
typing = false;
|
||||
setting.reset();
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@ import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
import static me.retucio.camtweaks.CameraTweaks.mc;
|
||||
|
||||
// botón para los ajustes booleanos (funciona como un interruptor)
|
||||
public class ToggleButton extends SettingButton {
|
||||
|
||||
@@ -39,7 +41,7 @@ public class ToggleButton extends SettingButton {
|
||||
public void mouseClicked(double mouseX, double mouseY, int button) {
|
||||
if (isHovered((int) mouseX, (int) mouseY) && ClickGUI.INSTANCE.trySelect(this)) {
|
||||
if (button == 0) setting.toggle(); // clic izquierdo para alternar
|
||||
else if (button == 1 && KeyUtil.isKeyDown(GLFW.GLFW_KEY_LEFT_SHIFT)) // shift izquierdo + clic derecho para restablecer al valor por defecto
|
||||
else if (button == 1 && mc.isShiftPressed()) // shift izquierdo + clic derecho para restablecer al valor por defecto
|
||||
setting.reset();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,144 @@
|
||||
package me.retucio.camtweaks.ui.widgets;
|
||||
|
||||
import me.retucio.camtweaks.module.ModuleManager;
|
||||
import me.retucio.camtweaks.module.modules.HUD;
|
||||
import me.retucio.camtweaks.ui.HudEditorScreen;
|
||||
import me.retucio.camtweaks.ui.HudRenderer;
|
||||
import me.retucio.camtweaks.util.Colors;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
import java.awt.*;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
|
||||
public class HudElement {
|
||||
|
||||
protected final MinecraftClient mc = MinecraftClient.getInstance();
|
||||
|
||||
private final String id;
|
||||
protected boolean visible;
|
||||
|
||||
protected int x, y;
|
||||
protected int defaultX, defaultY;
|
||||
protected int width = 85, height = 14; // tamaño por defecto
|
||||
|
||||
public HudElement(String id, int defX, int defY, int x, int y, boolean visible) {
|
||||
this.id = id;
|
||||
this.visible = visible;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.defaultX = defX;
|
||||
this.defaultY = defY;
|
||||
}
|
||||
|
||||
// fallback
|
||||
public void render(DrawContext ctx, int mouseX, int mouseY, float tickDelta) {
|
||||
ctx.drawText(mc.textRenderer, Text.literal(getId()), x, y, -1, false);
|
||||
}
|
||||
|
||||
/** renderizar previsualización del elemento para el editor */
|
||||
public void renderPreview(DrawContext ctx) {
|
||||
final HUD hud = ModuleManager.INSTANCE.getModuleByClass(HUD.class);
|
||||
final String previewText = buildPreviewText(hud);
|
||||
|
||||
width = mc.textRenderer.getWidth(previewText);
|
||||
height = mc.textRenderer.fontHeight;
|
||||
|
||||
drawBackground(ctx);
|
||||
|
||||
int color = -1;
|
||||
boolean shadow = false;
|
||||
if (hud != null) {
|
||||
color = HudRenderer.getColor(hud).getRGB();
|
||||
shadow = hud.shadow.isEnabled();
|
||||
}
|
||||
|
||||
HudRenderer.drawSnappedText(ctx, previewText, x, y, color, shadow);
|
||||
}
|
||||
|
||||
/** construir texto para la previsualización */
|
||||
private String buildPreviewText(HUD hud) {
|
||||
float delta = mc.getRenderTickCounter().getDynamicDeltaTicks();
|
||||
|
||||
if ("coords".equals(id)) {
|
||||
if (mc.player == null) return "X Y Z";
|
||||
return HudRenderer.getElementText(id, delta, hud);
|
||||
}
|
||||
|
||||
if ("fps".equals(id)) {
|
||||
return HudRenderer.getElementText(id, delta, hud);
|
||||
}
|
||||
|
||||
if ("tps".equals(id)) {
|
||||
return HudRenderer.getElementText(id, delta, hud);
|
||||
}
|
||||
|
||||
if ("customText".equals(id)) {
|
||||
if (hud != null && hud.customText != null && !hud.customText.getValue().isEmpty())
|
||||
return HudRenderer.getElementText(id, delta, hud);
|
||||
return "texto custom";
|
||||
}
|
||||
|
||||
if ("time".equals(id)) {
|
||||
if (hud != null && hud.timeFormat != null)
|
||||
return HudRenderer.getElementText(id, delta, hud);
|
||||
return "4:20 PM";
|
||||
}
|
||||
|
||||
return id; // fallback: id del elemento
|
||||
}
|
||||
|
||||
/** fondo y contorno */
|
||||
private void drawBackground(DrawContext ctx) {
|
||||
int bg = visible ? Colors.visibleHudElementColor.getRGB() : Colors.disabledHudElementColor.getRGB();
|
||||
int outline = HudEditorScreen.INSTANCE.isSelected(this) ? Colors.selectedHudElementOutlineColor.getRGB() : Colors.unselectedHudElementOutlineColor.getRGB();
|
||||
|
||||
// fondo
|
||||
ctx.fill(x - 1, y - 1, x + width + 1, y + height + 1, bg);
|
||||
|
||||
// contorno
|
||||
ctx.fill(x - 1, y - 1, x + width + 1, y, outline);
|
||||
ctx.fill(x - 1, y + height, x + width + 1, y + height + 1, outline);
|
||||
ctx.fill(x - 1, y, x, y + height, outline);
|
||||
ctx.fill(x + width, y, x + width + 1, y + height, outline);
|
||||
}
|
||||
|
||||
public boolean contains(int mouseX, int mouseY) {
|
||||
return mouseX >= x && mouseX <= x + width
|
||||
&& mouseY >= y && mouseY <= y + height;
|
||||
}
|
||||
|
||||
// getters y setters
|
||||
public String getId() { return id; }
|
||||
|
||||
public int getX() { return x; }
|
||||
public int getY() { return y; }
|
||||
|
||||
public void setX(int x) { this.x = x; }
|
||||
public void setY(int y) { this.y = y; }
|
||||
|
||||
public int getWidth() { return width; }
|
||||
public int getHeight() { return height; }
|
||||
|
||||
public boolean isVisible() { return visible; }
|
||||
public void setVisible(boolean visible) { this.visible = visible; }
|
||||
|
||||
public void setPosition(int newX, int newY) {
|
||||
this.x = newX;
|
||||
this.y = newY;
|
||||
}
|
||||
|
||||
public void resetPosition() {
|
||||
this.x = defaultX;
|
||||
this.y = defaultY;
|
||||
}
|
||||
|
||||
public interface Renderer {
|
||||
void render(DrawContext ctx, int x, int y, float delta);
|
||||
}
|
||||
}
|
||||
@@ -19,8 +19,14 @@ public class Colors {
|
||||
public static Color mainColor;
|
||||
public static Color frameBGColor = new Color(40, 40, 40, 75);
|
||||
public static Color buttonColor = new Color(75, 75, 75, 100);
|
||||
public static Color hudEditorScreenBackgroundColor = new Color(0, 0, 0, 120);
|
||||
public static Color instructionsTextColor = new Color(190, 190, 190, 255);
|
||||
public static Color enabledToggleButtonColor;
|
||||
public static Color disabledToggleButtonColor;
|
||||
public static Color visibleHudElementColor;
|
||||
public static Color disabledHudElementColor;
|
||||
public static Color selectedHudElementOutlineColor;
|
||||
public static Color unselectedHudElementOutlineColor;
|
||||
|
||||
static {
|
||||
updateAllColors(new Color(red, green, blue, alpha));
|
||||
@@ -31,6 +37,23 @@ public class Colors {
|
||||
enabledToggleButtonColor = mixWithMainColor(new Color(10, 150, 10), 0.8f);
|
||||
disabledToggleButtonColor = mixWithMainColor(new Color(150, 10, 10), 0.8f);
|
||||
|
||||
selectedHudElementOutlineColor = color;
|
||||
unselectedHudElementOutlineColor = color.darker().darker();
|
||||
|
||||
visibleHudElementColor = new Color(
|
||||
enabledToggleButtonColor.getRed(),
|
||||
enabledToggleButtonColor.getGreen(),
|
||||
enabledToggleButtonColor.getBlue(),
|
||||
enabledToggleButtonColor.getAlpha() / 2
|
||||
);
|
||||
|
||||
disabledHudElementColor = new Color(
|
||||
disabledToggleButtonColor.getRed(),
|
||||
disabledToggleButtonColor.getGreen(),
|
||||
disabledToggleButtonColor.getBlue(),
|
||||
disabledToggleButtonColor.getAlpha() / 2
|
||||
);
|
||||
|
||||
ChatUtil.updatePrefix(ChatUtil.getJustPrefix());
|
||||
}
|
||||
|
||||
|
||||
@@ -44,10 +44,12 @@ public class KeyUtil {
|
||||
case GLFW.GLFW_KEY_DOWN -> "abajo";
|
||||
case GLFW.GLFW_KEY_LEFT -> "izquierda";
|
||||
case GLFW.GLFW_KEY_RIGHT -> "derecha";
|
||||
default -> { // F1–F25
|
||||
case GLFW.GLFW_KEY_PAGE_UP -> "pág. arriba";
|
||||
case GLFW.GLFW_KEY_PAGE_DOWN -> "pág. abajo";
|
||||
default -> {
|
||||
if (key >= GLFW.GLFW_KEY_F1 && key <= GLFW.GLFW_KEY_F25)
|
||||
yield "F" + (key - GLFW.GLFW_KEY_F1 + 1);
|
||||
yield "tecla " + key;
|
||||
yield "F" + (key - GLFW.GLFW_KEY_F1 + 1); // F1–F25
|
||||
yield "tecla " + key; // fallback
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
"PlayerEntityMixin",
|
||||
"StringHelperMixin",
|
||||
"Vec3dMixin",
|
||||
"YggdrasilUserApiServiceMixin",
|
||||
"accessor.StatusEffectInstanceAccessor"
|
||||
],
|
||||
"injectors": {
|
||||
@@ -53,6 +54,7 @@
|
||||
"ScreenshotRecorderMixin",
|
||||
"SkyRendererMixin",
|
||||
"StuckArrowsFeatureRendererMixin",
|
||||
"TelemetryManagerMixin",
|
||||
"TextRendererDrawerMixin",
|
||||
"TextRendererMixin",
|
||||
"WeatherRenderingMixin",
|
||||
|
||||
Reference in new issue
Block a user