Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e358b142c6 | ||
|
|
e7d872d75e | ||
|
|
589279342d | ||
|
|
054702999b |
No files matched your search
@@ -39,4 +39,6 @@ replay_*.log
|
||||
*.hprof
|
||||
*.jfr
|
||||
|
||||
todo.txt
|
||||
todo.txt
|
||||
test.java
|
||||
cambios.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
|
||||
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)
|
||||
1. clona el respositorio (`git clone https://github.com/retuci0/camera-tweaks`)
|
||||
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
|
||||
|
||||
@@ -23,6 +25,8 @@ asegúrate de tener una version de Minecraft y Fabric compatibles con el mod
|
||||
|
||||
`$` como prefijo por defecto para comandos (se autocompletan)
|
||||
|
||||
algunos módulos tienen teclas asignadas por defecto, asígnales `ESC` para desactivar sus teclas
|
||||
|
||||
## interfaz
|
||||
|
||||
- clic izquierdo para activar / desactivar módulos
|
||||
@@ -37,14 +41,16 @@ asegúrate de tener una version de Minecraft y Fabric compatibles con el mod
|
||||
- shift mientras pasas el puntero por encima de un ajuste de modos para ver los modos disponibles
|
||||
- clic derecho para ciclar hacia atrás en ajustes de modo
|
||||
- usa la rueda del ratón para mover la interfaz verticalmente
|
||||
- shift + rueda del ratón para mover todos los marcos a un rango visible en la pantalla
|
||||
|
||||
## capturas
|
||||
|
||||
<img src="screenshots/2025-08-19_23.20.15.png" alt="captura 1 (foto vieja)">
|
||||
<img src="screenshots/2025-08-22_00.18.51.png" alt="captura 2 (interfaz)">
|
||||
<img src="screenshots/2025-08-22_00.19.11.png" alt="captura 3 (interfaz)">
|
||||
<img src="screenshots/2025-08-22_00.22.41.png" alt="captura 5 (comandos)">
|
||||
<img src="screenshots/2025-08-27_18.44.41.png" alt="captura 6 (nametags & apilar bossbars)">
|
||||
<img src="screenshots/ui.png" alt="interfaz">
|
||||
<img src="screenshots/nametags.png" alt="nametags mostrando daño de un tridente">
|
||||
<img src="screenshots/chatplus.png" alt="chatplus y capturas en uso">
|
||||
<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">
|
||||
|
||||
## contibuciones
|
||||
|
||||
|
||||
@@ -29,6 +29,10 @@ dependencies {
|
||||
|
||||
}
|
||||
|
||||
loom {
|
||||
accessWidenerPath = file("src/main/resources/camtweaks.accesswidener")
|
||||
}
|
||||
|
||||
processResources {
|
||||
inputs.property "version", project.version
|
||||
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
# v1.3
|
||||
|
||||
## novedades
|
||||
|
||||
### adiciones
|
||||
|
||||
- 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
|
||||
|
||||
- mejoras a la interfaz
|
||||
- ahora el color de los widgets depende del color principal
|
||||
- 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
|
||||
|
||||
- muchos, pero repórtalos en la página de problemas si quieres para que queden bien registrados
|
||||
@@ -1,4 +1,5 @@
|
||||
meteor client dev team
|
||||
oyvey client (1.21 port by mioclient)
|
||||
lennyboi (youtube)
|
||||
packbar by cattyn on github
|
||||
packbar by cattyn on github
|
||||
shotify mod
|
||||
@@ -10,7 +10,7 @@ loader_version=0.17.2
|
||||
loom_version=1.11-SNAPSHOT
|
||||
|
||||
# Mod Properties
|
||||
mod_version=1.1
|
||||
mod_version=1.3
|
||||
maven_group=me.retucio
|
||||
archives_base_name=camtweaks
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 1.6 MiB |
|
Before Width: | Height: | Size: 973 KiB |
|
Before Width: | Height: | Size: 1005 KiB |
|
Before Width: | Height: | Size: 942 KiB |
|
Before Width: | Height: | Size: 560 KiB |
|
Before Width: | Height: | Size: 484 KiB |
|
After Width: | Height: | Size: 864 KiB |
|
After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 566 KiB |
|
After Width: | Height: | Size: 469 KiB |
|
After Width: | Height: | Size: 506 KiB |
|
After Width: | Height: | Size: 691 KiB |
@@ -10,6 +10,9 @@ import me.retucio.camtweaks.event.EventBus;
|
||||
import me.retucio.camtweaks.event.SubscribeEvent;
|
||||
import me.retucio.camtweaks.event.events.ShutdownEvent;
|
||||
|
||||
import me.retucio.camtweaks.event.events.camtweaks.LoadClickGUIEvent;
|
||||
import me.retucio.camtweaks.event.events.camtweaks.LoadCommandManagerEvent;
|
||||
import me.retucio.camtweaks.event.events.camtweaks.LoadModuleManagerEvent;
|
||||
import me.retucio.camtweaks.module.Module;
|
||||
import me.retucio.camtweaks.module.ModuleManager;
|
||||
|
||||
@@ -17,10 +20,12 @@ import me.retucio.camtweaks.ui.ClickGUI;
|
||||
import me.retucio.camtweaks.ui.buttons.BindButton;
|
||||
import me.retucio.camtweaks.ui.buttons.SettingButton;
|
||||
import me.retucio.camtweaks.ui.buttons.TextButton;
|
||||
import me.retucio.camtweaks.ui.frames.ClickGUISettingsFrame;
|
||||
import me.retucio.camtweaks.ui.frames.ClientSettingsFrame;
|
||||
import me.retucio.camtweaks.ui.frames.SettingsFrame;
|
||||
|
||||
import me.retucio.camtweaks.util.ChatUtil;
|
||||
import me.retucio.camtweaks.util.KeyUtil;
|
||||
import me.retucio.camtweaks.util.Lists;
|
||||
import me.retucio.camtweaks.util.MiscUtil;
|
||||
|
||||
|
||||
@@ -29,6 +34,7 @@ import net.fabricmc.api.ClientModInitializer;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
|
||||
import net.minecraft.client.gui.screen.TitleScreen;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
@@ -46,20 +52,31 @@ public class CameraTweaks implements ClientModInitializer {
|
||||
public static MinecraftClient mc;
|
||||
|
||||
private Screen prevScreen;
|
||||
private boolean settingsApplied = false;
|
||||
public boolean settingsApplied = false;
|
||||
|
||||
@Override
|
||||
public void onInitializeClient() {
|
||||
// por algún motivo aunque lo añada a los args de la JVM sigue siendo true a menos que haga esto??? puta vida
|
||||
System.setProperty("java.awt.headless", "false");
|
||||
|
||||
mc = MinecraftClient.getInstance();
|
||||
|
||||
ModuleManager.INSTANCE = new ModuleManager(EVENT_BUS);
|
||||
CommandManager.INSTANCE = new CommandManager();
|
||||
ClickGUI.INSTANCE = new ClickGUI();
|
||||
|
||||
ConfigManager.load();
|
||||
|
||||
EVENT_BUS.register(this);
|
||||
EVENT_BUS.register(MiscUtil.class);
|
||||
EVENT_BUS.register(ChatUtil.class);
|
||||
|
||||
Lists.init();
|
||||
|
||||
ModuleManager.INSTANCE = new ModuleManager(EVENT_BUS);
|
||||
EVENT_BUS.post(new LoadModuleManagerEvent());
|
||||
|
||||
CommandManager.INSTANCE = new CommandManager();
|
||||
EVENT_BUS.post(new LoadCommandManagerEvent());
|
||||
|
||||
ClickGUI.INSTANCE = new ClickGUI();
|
||||
EVENT_BUS.post(new LoadClickGUIEvent());
|
||||
|
||||
ConfigManager.load();
|
||||
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
|
||||
ConfigManager.save();
|
||||
@@ -84,7 +101,7 @@ public class CameraTweaks implements ClientModInitializer {
|
||||
public void onKeyPress(int key, int action) {
|
||||
ModuleManager.INSTANCE.getEnabledModules().forEach(module -> module.onKey(key, action));
|
||||
|
||||
boolean anyFocused = isAnySettingButtonFocused();
|
||||
boolean anyFocused = isAnySettingButtonFocused() || ClickGUI.INSTANCE.getSearchBar().isFocused();
|
||||
ClickGUI.INSTANCE.setAnyFocused(anyFocused);
|
||||
|
||||
if (action == GLFW.GLFW_PRESS) {
|
||||
@@ -132,12 +149,15 @@ public class CameraTweaks implements ClientModInitializer {
|
||||
|
||||
// maneja la lógica de apertura de la interfaz
|
||||
private void handleClickGUIKey(int key, boolean anyFocused) {
|
||||
if (key != ClickGUISettingsFrame.guiSettings.getKey() || anyFocused) return;
|
||||
if (key != ClientSettingsFrame.guiSettings.getKey() || anyFocused) return;
|
||||
|
||||
if (mc.currentScreen != ClickGUI.INSTANCE) {
|
||||
// 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)) {
|
||||
prevScreen = mc.currentScreen;
|
||||
mc.setScreen(ClickGUI.INSTANCE);
|
||||
} else {
|
||||
ClickGUI.INSTANCE.close();
|
||||
mc.setScreen(prevScreen);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import net.minecraft.command.CommandSource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Comparator;
|
||||
import java.util.Objects;
|
||||
|
||||
// registro de comandos
|
||||
public class CommandManager {
|
||||
@@ -28,9 +29,12 @@ public class CommandManager {
|
||||
|
||||
public static void registerCommands() {
|
||||
addCommand(new BindCommand());
|
||||
addCommand(new CopyScreenshotCommand());
|
||||
// addCommand(new EnderChestCommand()); no funciona D:
|
||||
addCommand(new PeekCommand());
|
||||
addCommand(new PrefixCommand());
|
||||
addCommand(new PurgeCommand());
|
||||
addCommand(new SaveScreenshotCommand());
|
||||
addCommand(new SendCommand());
|
||||
addCommand(new ToggleCommand());
|
||||
|
||||
@@ -44,17 +48,17 @@ public class CommandManager {
|
||||
}
|
||||
|
||||
public static void dispatch(String message) throws CommandSyntaxException {
|
||||
dispatcher.execute(message, mc.getNetworkHandler().getCommandSource());
|
||||
dispatcher.execute(message, Objects.requireNonNull(mc.getNetworkHandler()).getCommandSource());
|
||||
}
|
||||
|
||||
public static Command getCommandByName(String name) {
|
||||
for (Command command : commands) {
|
||||
if (command.getName().equals(name))
|
||||
return command;
|
||||
if (command.getName().equals(name)) return command;
|
||||
|
||||
for (String alias : command.getAliases())
|
||||
if (alias.equals(name))
|
||||
return command;
|
||||
if (alias.equals(name)) return command;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package me.retucio.camtweaks.command.commands;
|
||||
|
||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||
import me.retucio.camtweaks.command.Command;
|
||||
import me.retucio.camtweaks.module.ModuleManager;
|
||||
import me.retucio.camtweaks.module.modules.ScreenshotPlus;
|
||||
import net.minecraft.command.CommandSource;
|
||||
|
||||
// se usa principalmente para el módulo ScreenshotPlus, pero también se puede usar sin él supongo
|
||||
public class CopyScreenshotCommand extends Command {
|
||||
|
||||
public CopyScreenshotCommand() {
|
||||
super("copiarcaptura", "copia la captura más reciente al portapapeles");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void build(LiteralArgumentBuilder<CommandSource> builder) {
|
||||
builder.executes(ctx -> {
|
||||
ScreenshotPlus screenshotPlus = ModuleManager.INSTANCE.getModuleByClass(ScreenshotPlus.class);
|
||||
|
||||
if (screenshotPlus.getScreenshot() != null) mc.execute(screenshotPlus::copyScreenshot);
|
||||
|
||||
return SUCCESS;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@ package me.retucio.camtweaks.command.commands;
|
||||
import com.mojang.brigadier.arguments.StringArgumentType;
|
||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||
import me.retucio.camtweaks.command.Command;
|
||||
import me.retucio.camtweaks.ui.frames.ClickGUISettingsFrame;
|
||||
import me.retucio.camtweaks.ui.frames.ClientSettingsFrame;
|
||||
import me.retucio.camtweaks.util.ChatUtil;
|
||||
import net.minecraft.command.CommandSource;
|
||||
import net.minecraft.text.Text;
|
||||
@@ -21,7 +21,7 @@ public class PrefixCommand extends Command {
|
||||
builder
|
||||
.then(argument("prefijo", StringArgumentType.word()).executes(ctx -> {
|
||||
String prefix = ctx.getArgument("prefijo", String.class);
|
||||
ClickGUISettingsFrame.guiSettings.commandPrefix.setValue(prefix);
|
||||
ClientSettingsFrame.guiSettings.commandPrefix.setValue(prefix);
|
||||
ChatUtil.info(Text.literal("prefijo cambiado a " + Formatting.AQUA + prefix));
|
||||
return SUCCESS;
|
||||
}));
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package me.retucio.camtweaks.command.commands;
|
||||
|
||||
import com.mojang.brigadier.arguments.IntegerArgumentType;
|
||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||
import me.retucio.camtweaks.command.Command;
|
||||
import me.retucio.camtweaks.util.interfaces.IChatHud;
|
||||
import net.minecraft.client.gui.hud.ChatHud;
|
||||
import net.minecraft.client.gui.hud.ChatHudLine;
|
||||
import net.minecraft.command.CommandSource;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PurgeCommand extends Command {
|
||||
|
||||
public PurgeCommand() {
|
||||
super("purgar", "elimina mensajes del chat", "purge");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void build(LiteralArgumentBuilder<CommandSource> builder) {
|
||||
builder.then(argument("cantidad", IntegerArgumentType.integer(1))
|
||||
.executes(context -> {
|
||||
int amount = IntegerArgumentType.getInteger(context, "cantidad");
|
||||
purgeMessages(amount);
|
||||
return 1;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
private void purgeMessages(int amount) {
|
||||
ChatHud chatHud = mc.inGameHud.getChatHud();
|
||||
|
||||
synchronized (chatHud) {
|
||||
List<ChatHudLine.Visible> visibleMessages = ((IChatHud) chatHud).smegma$getVisibleMessages();
|
||||
int toRemove = Math.min(amount, visibleMessages.size());
|
||||
for (int i = 0; i < toRemove; i++)
|
||||
visibleMessages.removeFirst();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package me.retucio.camtweaks.command.commands;
|
||||
|
||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||
import me.retucio.camtweaks.command.Command;
|
||||
import me.retucio.camtweaks.module.ModuleManager;
|
||||
import me.retucio.camtweaks.module.modules.ScreenshotPlus;
|
||||
import me.retucio.camtweaks.util.ChatUtil;
|
||||
import net.minecraft.command.CommandSource;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
// se usa principalmente para el módulo ScreenshotPlus, pero también se puede usar sin él supongo
|
||||
public class SaveScreenshotCommand extends Command {
|
||||
|
||||
public SaveScreenshotCommand() {
|
||||
super("guardarcaptura", "guarda localmente la captura más reciente");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void build(LiteralArgumentBuilder<CommandSource> builder) {
|
||||
builder.executes(ctx -> {
|
||||
ScreenshotPlus screenshotPlus = ModuleManager.INSTANCE.getModuleByClass(ScreenshotPlus.class);
|
||||
|
||||
mc.execute(() -> {
|
||||
if (screenshotPlus.getScreenshot() != null) {
|
||||
try {
|
||||
screenshotPlus.saveScreenshot();
|
||||
} catch (IOException e) {
|
||||
ChatUtil.error("no se pudo guardar la captura");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return SUCCESS;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,6 @@ import me.retucio.camtweaks.event.SubscribeEvent;
|
||||
import me.retucio.camtweaks.event.events.camtweaks.*;
|
||||
import me.retucio.camtweaks.module.settings.*;
|
||||
import me.retucio.camtweaks.ui.ClickGUI;
|
||||
import me.retucio.camtweaks.ui.frames.ClickGUISettingsFrame;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@@ -37,9 +36,10 @@ public class ClientConfig {
|
||||
ConfigManager.setModuleState(event.getModule());
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@SubscribeEvent
|
||||
public void onUpdateSetting(UpdateSettingEvent event) {
|
||||
if (mc == null) return;
|
||||
if (mc == null || !event.shouldSave()) return;
|
||||
|
||||
// guardar ajustes con su respectivo tipo de valor, en formato "nombreMódulo:nombreAjuste"
|
||||
Object value = null;
|
||||
@@ -49,6 +49,7 @@ public class ClientConfig {
|
||||
case KeySetting k: value = k.getKey(); break;
|
||||
case NumberSetting n: value = n.getValue(); break;
|
||||
case StringSetting s: value = s.getValue(); break;
|
||||
case ListSetting l: value = l.getValues(); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,13 +7,15 @@ import me.retucio.camtweaks.module.Module;
|
||||
import me.retucio.camtweaks.module.ModuleManager;
|
||||
import me.retucio.camtweaks.module.settings.*;
|
||||
import me.retucio.camtweaks.ui.ClickGUI;
|
||||
import me.retucio.camtweaks.ui.frames.ClickGUISettingsFrame;
|
||||
import me.retucio.camtweaks.ui.frames.ClientSettingsFrame;
|
||||
import me.retucio.camtweaks.ui.frames.SettingsFrame;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
// se ocupa de guardar, cargar y aplicar ajustes
|
||||
// pues no me ha dado dolores de cabeza el coso este con los NPE de los cojones...
|
||||
@@ -69,8 +71,8 @@ public class ConfigManager {
|
||||
}
|
||||
});
|
||||
|
||||
ClickGUISettingsFrame.guiSettings.setEnabled(true);
|
||||
ClickGUISettingsFrame.guiSettings.getSettings().forEach(setting -> applySetting(ClickGUISettingsFrame.guiSettings, setting));
|
||||
ClientSettingsFrame.guiSettings.setEnabled(true);
|
||||
ClientSettingsFrame.guiSettings.getSettings().forEach(setting -> applySetting(ClientSettingsFrame.guiSettings, setting));
|
||||
|
||||
CameraTweaks.LOGGER.info("módulos encendidos cargados");
|
||||
CameraTweaks.LOGGER.info("ajustes de módulos cargados");
|
||||
@@ -90,6 +92,7 @@ public class ConfigManager {
|
||||
}
|
||||
|
||||
CameraTweaks.LOGGER.info("posiciones de frames cargadas");
|
||||
ClickGUI.INSTANCE.refreshListButtons();
|
||||
}
|
||||
|
||||
public static ClientConfig getConfig() {
|
||||
@@ -102,7 +105,7 @@ public class ConfigManager {
|
||||
save();
|
||||
}
|
||||
|
||||
public static void setSetting(Setting setting, Object value) {
|
||||
public static void setSetting(AbstractSetting setting, Object value) {
|
||||
ensureConfig();
|
||||
config.settings.put(setting.getModule().getName() + ":" + setting.getName(), value);
|
||||
save();
|
||||
@@ -120,7 +123,8 @@ public class ConfigManager {
|
||||
save();
|
||||
}
|
||||
|
||||
public static void applySetting(Module parent, Setting setting) {
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
public static void applySetting(Module parent, AbstractSetting setting) {
|
||||
String id = parent.getName() + ":" + setting.getName();
|
||||
if (config.settings.containsKey(id)) {
|
||||
Object value = config.settings.get(id);
|
||||
@@ -131,7 +135,17 @@ public class ConfigManager {
|
||||
case NumberSetting n -> n.setValue((double) value);
|
||||
case StringSetting s -> s.setValue((String) value);
|
||||
case KeySetting k -> k.setKey(value instanceof Double val ? val.intValue() : (int) value);
|
||||
default -> {}
|
||||
case ListSetting l -> {
|
||||
if (value instanceof Map<?, ?> map) {
|
||||
Map<Object, Boolean> converted = new HashMap<>();
|
||||
for (Object option : l.getOptions()) {
|
||||
Object key = String.valueOf(option);
|
||||
Object bv = map.get(key);
|
||||
converted.put(option, bv instanceof Boolean b && b);
|
||||
}
|
||||
l.setValues(converted);
|
||||
}
|
||||
} default -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
package me.retucio.camtweaks.event.events.camtweaks;
|
||||
|
||||
import me.retucio.camtweaks.event.Event;
|
||||
|
||||
public class LoadClickGUIEvent extends Event {}
|
||||
@@ -0,0 +1,5 @@
|
||||
package me.retucio.camtweaks.event.events.camtweaks;
|
||||
|
||||
import me.retucio.camtweaks.event.Event;
|
||||
|
||||
public class LoadCommandManagerEvent extends Event {}
|
||||
@@ -0,0 +1,5 @@
|
||||
package me.retucio.camtweaks.event.events.camtweaks;
|
||||
|
||||
import me.retucio.camtweaks.event.Event;
|
||||
|
||||
public class LoadModuleManagerEvent extends Event {}
|
||||
@@ -1,18 +1,28 @@
|
||||
package me.retucio.camtweaks.event.events.camtweaks;
|
||||
|
||||
import me.retucio.camtweaks.event.Event;
|
||||
import me.retucio.camtweaks.module.settings.Setting;
|
||||
import me.retucio.camtweaks.module.settings.AbstractSetting;
|
||||
|
||||
// se genera cada que se cambia el valor de un ajuste
|
||||
public class UpdateSettingEvent extends Event {
|
||||
|
||||
private final Setting setting;
|
||||
private final AbstractSetting setting;
|
||||
private boolean shouldSave;
|
||||
|
||||
public UpdateSettingEvent(Setting setting) {
|
||||
public UpdateSettingEvent(AbstractSetting setting, boolean shouldSave) {
|
||||
this.setting = setting;
|
||||
this.shouldSave = shouldSave;
|
||||
}
|
||||
|
||||
public Setting getSetting() {
|
||||
public AbstractSetting getSetting() {
|
||||
return setting;
|
||||
}
|
||||
|
||||
public boolean shouldSave() {
|
||||
return shouldSave;
|
||||
}
|
||||
|
||||
public void shouldSave(boolean value) {
|
||||
this.shouldSave = value;
|
||||
}
|
||||
}
|
||||
@@ -103,6 +103,11 @@ public abstract class ChatHudMixin implements IChatHud {
|
||||
return line;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ChatHudLine.Visible> smegma$getVisibleMessages() {
|
||||
return visibleMessages;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// modificar contenido del mensaje
|
||||
|
||||
@@ -3,13 +3,19 @@ package me.retucio.camtweaks.mixin;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import me.retucio.camtweaks.command.CommandManager;
|
||||
import me.retucio.camtweaks.event.events.SendMessageEvent;
|
||||
import me.retucio.camtweaks.module.ModuleManager;
|
||||
import me.retucio.camtweaks.module.modules.NoRender;
|
||||
import me.retucio.camtweaks.util.ChatUtil;
|
||||
import net.minecraft.client.network.ClientPlayNetworkHandler;
|
||||
import net.minecraft.client.render.GameRenderer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import static me.retucio.camtweaks.CameraTweaks.*;
|
||||
@@ -46,4 +52,10 @@ public abstract class ClientPlayNetworkHandlerMixin {
|
||||
mc.inGameHud.getChatHud().addToMessageHistory(message);
|
||||
ci.cancel();
|
||||
}
|
||||
|
||||
@Redirect(method = "onEntityStatus", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/GameRenderer;showFloatingItem(Lnet/minecraft/item/ItemStack;)V"))
|
||||
private void noRenderTotemPop(GameRenderer instance, ItemStack floatingItem) {
|
||||
NoRender noRender = ModuleManager.INSTANCE.getModuleByClass(NoRender.class);
|
||||
if (!noRender.isEnabled() || noRender.totemPop.isEnabled()) mc.gameRenderer.showFloatingItem(Items.TOTEM_OF_UNDYING.getDefaultStack());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package me.retucio.camtweaks.mixin;
|
||||
|
||||
import me.retucio.camtweaks.module.ModuleManager;
|
||||
import me.retucio.camtweaks.module.modules.Freecam;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.network.ClientPlayNetworkHandler;
|
||||
import net.minecraft.client.network.ClientPlayerEntity;
|
||||
import net.minecraft.client.network.ClientPlayerInteractionManager;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.hit.BlockHitResult;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
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;
|
||||
|
||||
@Mixin(ClientPlayerInteractionManager.class)
|
||||
public abstract class ClientPlayerInteractionManagerMixin {
|
||||
|
||||
@Unique
|
||||
Freecam freecam;
|
||||
|
||||
@Inject(method = "<init>", at = @At("TAIL"))
|
||||
private void getModules(MinecraftClient client, ClientPlayNetworkHandler networkHandler, CallbackInfo ci) {
|
||||
freecam = ModuleManager.INSTANCE.getModuleByClass(Freecam.class);
|
||||
}
|
||||
|
||||
// los paquetes ya se cancelan en la clase de Freecam, pero visualmente el bloque sigue apareciendo roto
|
||||
@Inject(method = "breakBlock", at = @At("HEAD"), cancellable = true)
|
||||
private void cancelBlockBreaking(BlockPos pos, CallbackInfoReturnable<Boolean> cir) {
|
||||
if (freecam.isEnabled() && freecam.cancelActionPackets.isEnabled()) cir.setReturnValue(false);
|
||||
}
|
||||
|
||||
@Inject(method = "interactBlock", at = @At("HEAD"), cancellable = true)
|
||||
private void cancelBlockPlacement(ClientPlayerEntity player, Hand hand, BlockHitResult hitResult, CallbackInfoReturnable<ActionResult> cir) {
|
||||
if (freecam.isEnabled() && freecam.cancelActionPackets.isEnabled()) cir.setReturnValue(ActionResult.FAIL);
|
||||
}
|
||||
|
||||
@Inject(method = "interactEntity", at = @At("HEAD"), cancellable = true)
|
||||
private void cancelEntityInteractions(PlayerEntity player, Entity entity, Hand hand, CallbackInfoReturnable<ActionResult> cir) {
|
||||
if (freecam.isEnabled() && freecam.cancelActionPackets.isEnabled()) cir.setReturnValue(ActionResult.FAIL);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package me.retucio.camtweaks.mixin;
|
||||
|
||||
import com.llamalad7.mixinextras.injector.ModifyReturnValue;
|
||||
import me.retucio.camtweaks.module.ModuleManager;
|
||||
import me.retucio.camtweaks.module.modules.CritsPlus;
|
||||
import net.minecraft.client.particle.DamageParticle;
|
||||
import net.minecraft.client.particle.ParticleTextureSheet;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyVariable;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
@Mixin(DamageParticle.class)
|
||||
public abstract class DamageParticleMixin {
|
||||
|
||||
@ModifyReturnValue(method = "getType", at = @At("RETURN"))
|
||||
private ParticleTextureSheet makeCritsTranslucent(ParticleTextureSheet original) {
|
||||
if (ModuleManager.INSTANCE.getModuleByClass(CritsPlus.class).isEnabled()) return ParticleTextureSheet.PARTICLE_SHEET_TRANSLUCENT;
|
||||
return original;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Mixin(DamageParticle.Factory.class)
|
||||
abstract class DamageParticleFactoryMixin {
|
||||
|
||||
@ModifyVariable(method = "createParticle(Lnet/minecraft/particle/SimpleParticleType;Lnet/minecraft/client/world/ClientWorld;DDDDDD)Lnet/minecraft/client/particle/Particle;", at = @At(value = "STORE"))
|
||||
private DamageParticle modifyCritColor(DamageParticle original) {
|
||||
CritsPlus crits = ModuleManager.INSTANCE.getModuleByClass(CritsPlus.class);
|
||||
if (!crits.isEnabled()) return original;
|
||||
|
||||
if (crits.rainbow.isEnabled()) {
|
||||
float speed = 10001 - crits.rainbowSpeed.getFloatValue();
|
||||
float hue = (System.currentTimeMillis() % (int) speed) / speed;
|
||||
Color gamning = Color.getHSBColor(hue, 1, 1);
|
||||
original.setColor(
|
||||
gamning.getRed() / 255f,
|
||||
gamning.getGreen() / 255f,
|
||||
gamning.getBlue() / 255f);
|
||||
} else {
|
||||
original.setColor(
|
||||
crits.red.getFloatValue() / 255f,
|
||||
crits.green.getFloatValue() / 255f,
|
||||
crits.blue.getFloatValue() / 255f);
|
||||
}
|
||||
|
||||
original.alpha = crits.alpha.getFloatValue() / 255f;
|
||||
original.scale *= crits.scale.getFloatValue();
|
||||
original.velocityMultiplier *= crits.velocityMultipler.getFloatValue();
|
||||
original.gravityStrength *= crits.gravity.getFloatValue();
|
||||
original.setMaxAge(crits.maxAge.getIntValue());
|
||||
original.collidesWithWorld = crits.collide.isEnabled();
|
||||
|
||||
return original;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package me.retucio.camtweaks.mixin;
|
||||
|
||||
import me.retucio.camtweaks.module.ModuleManager;
|
||||
import me.retucio.camtweaks.module.modules.NoRender;
|
||||
import net.minecraft.particle.EntityEffectParticleEffect;
|
||||
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.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(EntityEffectParticleEffect.class)
|
||||
public abstract class EntityEffectParticleEffectMixin {
|
||||
|
||||
@Inject(method = "getAlpha", at = @At("HEAD"), cancellable = true)
|
||||
private void noRenderPotionParticles(CallbackInfoReturnable<Float> cir) {
|
||||
NoRender noRender = ModuleManager.INSTANCE.getModuleByClass(NoRender.class);
|
||||
if (noRender.isEnabled()) cir.setReturnValue(256 - noRender.potionParticleAlpha.getFloatValue());
|
||||
}
|
||||
}
|
||||
@@ -2,19 +2,15 @@ package me.retucio.camtweaks.mixin;
|
||||
|
||||
import com.llamalad7.mixinextras.injector.ModifyReturnValue;
|
||||
import me.retucio.camtweaks.module.ModuleManager;
|
||||
import me.retucio.camtweaks.module.modules.AntiInvis;
|
||||
import me.retucio.camtweaks.module.modules.Freecam;
|
||||
import me.retucio.camtweaks.module.modules.Freelook;
|
||||
import me.retucio.camtweaks.module.modules.Nametags;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.render.entity.AgeableMobEntityRenderer;
|
||||
import me.retucio.camtweaks.util.ChatUtil;
|
||||
import net.minecraft.entity.*;
|
||||
import net.minecraft.entity.mob.Monster;
|
||||
import net.minecraft.entity.passive.PassiveEntity;
|
||||
import net.minecraft.entity.passive.TameableEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.projectile.PersistentProjectileEntity;
|
||||
import net.minecraft.entity.projectile.ProjectileEntity;
|
||||
import net.minecraft.entity.vehicle.VehicleEntity;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Formatting;
|
||||
import net.minecraft.world.World;
|
||||
@@ -25,17 +21,18 @@ import org.spongepowered.asm.mixin.Unique;
|
||||
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.mc;
|
||||
|
||||
@Mixin(Entity.class)
|
||||
public abstract class EntityMixin {
|
||||
|
||||
@Shadow public int age;
|
||||
@Shadow
|
||||
public abstract Text getName();
|
||||
|
||||
@Shadow public abstract Text getName();
|
||||
|
||||
@Shadow @Nullable public abstract Text getCustomName();
|
||||
@Shadow
|
||||
public abstract EntityType<?> getType();
|
||||
|
||||
@Unique
|
||||
Freecam freecam;
|
||||
@@ -82,15 +79,8 @@ public abstract class EntityMixin {
|
||||
@ModifyReturnValue(method = "isCustomNameVisible", at = @At("RETURN"))
|
||||
private boolean renderEntityNametags(boolean original) {
|
||||
if (!nametags.isEnabled()) return original;
|
||||
return switch ((Object) this) {
|
||||
case PlayerEntity player -> nametags.namePlayers.isEnabled();
|
||||
case ItemEntity item -> nametags.nameItems.isEnabled();
|
||||
case ProjectileEntity projectile -> nametags.nameProjectiles.isEnabled();
|
||||
case Monster hostile -> nametags.nameHostileMobs.isEnabled() || original; // monster en vez de HostileEntity para también incluir slimes
|
||||
case PassiveEntity passive -> nametags.namePassiveMobs.isEnabled() || original;
|
||||
case VehicleEntity vehicle -> nametags.nameVehicles.isEnabled();
|
||||
default -> nametags.nameMiscMobs.isEnabled() || original;
|
||||
};
|
||||
if ((Object) this instanceof PersistentProjectileEntity p && p.isOnGround()) return false;
|
||||
return nametags.entities.isEnabled((this.getType()));
|
||||
}
|
||||
|
||||
@ModifyReturnValue(method = "getName", at = @At("RETURN"))
|
||||
@@ -98,9 +88,10 @@ public abstract class EntityMixin {
|
||||
if (!nametags.isEnabled() || !nametags.showProjectileDamage.isEnabled()) return original;
|
||||
|
||||
if ((Object) this instanceof PersistentProjectileEntity arrow) { // aunque lo llame "arrow", también cubre flechas espectrales y tridentes
|
||||
float damage = nametags.getArrowDamage(arrow);
|
||||
if (damage > 0) return original.copy().append(Text.literal(" (" + damage + ")").formatted(Formatting.RED));
|
||||
String damage = nametags.getArrowDamage(arrow);
|
||||
if (!damage.equals("0")) return original.copy().append(Text.literal(" (" + damage + ")").formatted(Formatting.RED));
|
||||
}
|
||||
|
||||
return original;
|
||||
}
|
||||
|
||||
@@ -123,4 +114,12 @@ public abstract class EntityMixin {
|
||||
if ((Object) this instanceof LivingEntity entity && entity.isBaby()) return original.copy().append(" (baby)");
|
||||
return original;
|
||||
}
|
||||
|
||||
|
||||
// otros
|
||||
|
||||
@Inject(method = "isInvisibleTo", at = @At("RETURN"), cancellable = true)
|
||||
public void renderInvisPlayers(PlayerEntity player, CallbackInfoReturnable<Boolean> cir) {
|
||||
if (ModuleManager.INSTANCE.getModuleByClass(AntiInvis.class).isEnabled()) cir.setReturnValue(false);
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
package me.retucio.camtweaks.mixin;
|
||||
|
||||
import me.retucio.camtweaks.mixin.accessor.EntityRenderStateAccessor;
|
||||
import me.retucio.camtweaks.module.ModuleManager;
|
||||
import me.retucio.camtweaks.module.modules.Nametags;
|
||||
import net.minecraft.client.render.VertexConsumerProvider;
|
||||
import net.minecraft.client.render.entity.EntityRenderer;
|
||||
import net.minecraft.client.render.entity.state.EntityRenderState;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.text.Text;
|
||||
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;
|
||||
|
||||
@Mixin(EntityRenderer.class)
|
||||
public abstract class EntityRendererMixin<S extends EntityRenderState> {
|
||||
|
||||
@Inject(method = "renderLabelIfPresent", at = @At("HEAD"))
|
||||
private void renderSneakingPlayerNametags(S state, Text text, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, CallbackInfo ci) {
|
||||
Nametags nametags = ModuleManager.INSTANCE.getModuleByClass(Nametags.class);
|
||||
|
||||
if (nametags.isEnabled() && nametags.alwaysVisible.isEnabled())
|
||||
((EntityRenderStateAccessor) state).setSneaking(false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package me.retucio.camtweaks.mixin;
|
||||
|
||||
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
|
||||
import com.llamalad7.mixinextras.injector.ModifyReturnValue;
|
||||
import me.retucio.camtweaks.module.ModuleManager;
|
||||
import me.retucio.camtweaks.module.modules.NoRender;
|
||||
import net.minecraft.block.enums.CameraSubmersionType;
|
||||
import net.minecraft.client.render.Camera;
|
||||
import net.minecraft.client.render.fog.FogModifier;
|
||||
import net.minecraft.client.render.fog.FogRenderer;
|
||||
import net.minecraft.entity.Entity;
|
||||
import org.joml.Vector4f;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(FogRenderer.class)
|
||||
public abstract class FogRendererMixin {
|
||||
|
||||
@Unique
|
||||
NoRender noRender;
|
||||
|
||||
@Inject(method = "<init>", at = @At("TAIL"))
|
||||
private void getModules(CallbackInfo ci) {
|
||||
noRender = ModuleManager.INSTANCE.getModuleByClass(NoRender.class);
|
||||
}
|
||||
|
||||
@Redirect(method = "applyFog(Lnet/minecraft/client/render/Camera;IZLnet/minecraft/client/render/RenderTickCounter;FLnet/minecraft/client/world/ClientWorld;)Lorg/joml/Vector4f;", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/fog/FogModifier;shouldApply(Lnet/minecraft/block/enums/CameraSubmersionType;Lnet/minecraft/entity/Entity;)Z"))
|
||||
private boolean noRenderFogs(FogModifier instance, CameraSubmersionType cameraSubmersionType, Entity entity) {
|
||||
if (!noRender.isEnabled()) return instance.shouldApply(cameraSubmersionType, entity);
|
||||
String className = instance.getClass().getSimpleName();
|
||||
|
||||
if ((className.equals("BlindnessEffectFogModifier") && !noRender.blindnessEffect.isEnabled())
|
||||
|| (className.equals("DarknessEffectFogModifier") && !noRender.darknessEffect.isEnabled())
|
||||
|| ((className.equals("LavaFogModifier") || className.equals("WaterFogModifier")
|
||||
|| className.equals("PowederSnowFogModifier")) && !noRender.fluidOverlay.isEnabled())
|
||||
|| (className.equals("DimensionOrBossFogModifier") && !noRender.dimensionFog.isEnabled()))
|
||||
return false;
|
||||
|
||||
return instance.shouldApply(cameraSubmersionType, entity);
|
||||
}
|
||||
|
||||
@ModifyReturnValue(method = "getFogColor", at = @At("RETURN"))
|
||||
private Vector4f modifyLavaFog(Vector4f original, Camera camera) {
|
||||
if (noRender.isEnabled() && !noRender.fluidOverlay.isEnabled() &&
|
||||
(camera.getSubmersionType() == CameraSubmersionType.LAVA
|
||||
|| camera.getSubmersionType() == CameraSubmersionType.WATER))
|
||||
return new Vector4f(original.x, original.y, original.z, 0f);
|
||||
|
||||
return original;
|
||||
}
|
||||
|
||||
@ModifyExpressionValue(method = "getFogColor", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;getUnderwaterVisibility()F"))
|
||||
private float noRenderUnderwaterFog(float original) {
|
||||
return (noRender.isEnabled() && !noRender.fluidOverlay.isEnabled()) ? 0 : original;
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import com.llamalad7.mixinextras.injector.ModifyReturnValue;
|
||||
import me.retucio.camtweaks.event.events.GetFOVEvent;
|
||||
import me.retucio.camtweaks.module.ModuleManager;
|
||||
import me.retucio.camtweaks.module.modules.Freecam;
|
||||
import me.retucio.camtweaks.module.modules.PerspectivePlus;
|
||||
import me.retucio.camtweaks.module.modules.NoRender;
|
||||
import me.retucio.camtweaks.module.modules.Zoom;
|
||||
import me.retucio.camtweaks.util.interfaces.IVec3d;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
@@ -20,6 +20,7 @@ import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyVariable;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import static me.retucio.camtweaks.CameraTweaks.EVENT_BUS;
|
||||
@@ -36,6 +37,9 @@ public abstract class GameRendererMixin {
|
||||
@Unique
|
||||
Freecam freecam;
|
||||
|
||||
@Unique
|
||||
NoRender noRender;
|
||||
|
||||
@Shadow @Final
|
||||
private MinecraftClient client;
|
||||
|
||||
@@ -46,6 +50,7 @@ public abstract class GameRendererMixin {
|
||||
private void getModules(MinecraftClient client, HeldItemRenderer firstPersonHeldItemRenderer, BufferBuilderStorage buffers, CallbackInfo ci) {
|
||||
zoom = ModuleManager.INSTANCE.getModuleByClass(Zoom.class);;
|
||||
freecam = ModuleManager.INSTANCE.getModuleByClass(Freecam.class);
|
||||
noRender = ModuleManager.INSTANCE.getModuleByClass(NoRender.class);
|
||||
}
|
||||
|
||||
@ModifyReturnValue(method = "getFov", at = @At("RETURN"))
|
||||
@@ -103,4 +108,9 @@ public abstract class GameRendererMixin {
|
||||
|| (freecam.isEnabled() && !freecam.renderHands.isEnabled()))
|
||||
ci.cancel();
|
||||
}
|
||||
|
||||
@ModifyVariable(method = "renderWorld", ordinal = 6, at = @At(value = "STORE"))
|
||||
private float noRenderNauseaDistortion(float scaledNauseaEffectFactor) {
|
||||
return (noRender.isEnabled() && !noRender.nauseaEffect.isEnabled()) ? 0 : scaledNauseaEffectFactor;
|
||||
}
|
||||
}
|
||||
@@ -4,11 +4,15 @@ import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
|
||||
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 net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.client.gui.hud.InGameHud;
|
||||
import net.minecraft.client.render.RenderTickCounter;
|
||||
import net.minecraft.util.Identifier;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
@@ -16,6 +20,50 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
@Mixin(InGameHud.class)
|
||||
public abstract class InGameHudMixin {
|
||||
|
||||
@Unique
|
||||
NoRender noRender;
|
||||
|
||||
@Inject(method = "<init>", at = @At("TAIL"))
|
||||
private void getModules(MinecraftClient client, CallbackInfo ci) {
|
||||
noRender = ModuleManager.INSTANCE.getModuleByClass(NoRender.class);
|
||||
}
|
||||
|
||||
|
||||
// norender
|
||||
|
||||
@Inject(method = "renderScoreboardSidebar*", at = @At("HEAD"), cancellable = true)
|
||||
private void noRenderScoreboard(CallbackInfo ci) {
|
||||
if (noRender.isEnabled() && !noRender.scoreboard.isEnabled()) ci.cancel();
|
||||
}
|
||||
|
||||
@Inject(method = "renderTitleAndSubtitle", at = @At("HEAD"), cancellable = true)
|
||||
private void noRenderTitles(DrawContext context, RenderTickCounter tickCounter, CallbackInfo ci) {
|
||||
if (noRender.isEnabled() && !noRender.titles.isEnabled()) ci.cancel();
|
||||
}
|
||||
|
||||
@Inject(method = "renderNauseaOverlay", at = @At("HEAD"), cancellable = true)
|
||||
private void noRenderNausea(DrawContext context, float nauseaStrength, CallbackInfo ci) {
|
||||
if (noRender.isEnabled() && !noRender.nauseaEffect.isEnabled()) ci.cancel();
|
||||
}
|
||||
|
||||
@Inject(method = "renderSpyglassOverlay", at = @At("HEAD"), cancellable = true)
|
||||
private void noRenderSpyglass(DrawContext context, float scale, CallbackInfo ci) {
|
||||
if (noRender.isEnabled() && !noRender.spyglassOverlay.isEnabled()) ci.cancel();
|
||||
}
|
||||
|
||||
@Inject(method = "renderPortalOverlay", at = @At("HEAD"), cancellable = true)
|
||||
private void noRenderPortal(DrawContext context, float nauseaStrength, CallbackInfo ci) {
|
||||
if (noRender.isEnabled() && !noRender.portalOverlay.isEnabled()) ci.cancel();
|
||||
}
|
||||
|
||||
@Inject(method = "renderOverlay", at = @At("HEAD"), cancellable = true)
|
||||
private void noRenderPumpkinBlur(DrawContext context, Identifier texture, float opacity, CallbackInfo ci) {
|
||||
if (noRender.isEnabled() && !noRender.pumpkinOverlay.isEnabled() && texture.getPath().equals("textures/misc/pumpkinblur.png")) ci.cancel();
|
||||
}
|
||||
|
||||
|
||||
// otros
|
||||
|
||||
@Inject(method = "render", at = @At("RETURN"))
|
||||
private void renderHUD(DrawContext ctx, RenderTickCounter tc, CallbackInfo ci) {
|
||||
HUD.render(ctx, tc);
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package me.retucio.camtweaks.mixin;
|
||||
|
||||
import me.retucio.camtweaks.module.ModuleManager;
|
||||
import me.retucio.camtweaks.module.modules.NoRender;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.hud.InGameOverlayRenderer;
|
||||
import net.minecraft.client.render.VertexConsumerProvider;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(InGameOverlayRenderer.class)
|
||||
public abstract class InGameOverlayRendererMixin {
|
||||
|
||||
@Unique
|
||||
private static NoRender noRender;
|
||||
|
||||
@Inject(method = "<init>", at = @At("TAIL"))
|
||||
private void getModules(MinecraftClient client, VertexConsumerProvider vertexConsumers, CallbackInfo ci) {
|
||||
noRender = ModuleManager.INSTANCE.getModuleByClass(NoRender.class);
|
||||
}
|
||||
|
||||
@Inject(method = "renderFireOverlay", at = @At("HEAD"), cancellable = true)
|
||||
private static void noRenderFireOverlay(MatrixStack matrices, VertexConsumerProvider vertexConsumers, CallbackInfo ci) {
|
||||
if (noRender.isEnabled() && !noRender.fireOverlay.isEnabled()) ci.cancel();
|
||||
}
|
||||
|
||||
@Inject(method = "renderUnderwaterOverlay", at = @At("HEAD"), cancellable = true)
|
||||
private static void noRenderUnderwaterOverlay(MinecraftClient client, MatrixStack matrices, VertexConsumerProvider vertexConsumers, CallbackInfo ci) {
|
||||
if (noRender.isEnabled() && !noRender.fluidOverlay.isEnabled()) ci.cancel();
|
||||
}
|
||||
}
|
||||
@@ -5,11 +5,9 @@ import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.textures.GpuTexture;
|
||||
import me.retucio.camtweaks.module.ModuleManager;
|
||||
import me.retucio.camtweaks.module.modules.Fullbright;
|
||||
import me.retucio.camtweaks.module.modules.PerspectivePlus;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.render.GameRenderer;
|
||||
import net.minecraft.client.render.LightmapTextureManager;
|
||||
import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket;
|
||||
import net.minecraft.util.math.ColorHelper;
|
||||
import net.minecraft.util.profiler.Profiler;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
@@ -37,7 +35,12 @@ public abstract class LightmapTextureManagerMixin {
|
||||
@Inject(method = "update", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/profiler/Profiler;push(Ljava/lang/String;)V", shift = At.Shift.AFTER), cancellable = true)
|
||||
private void update(float tickProgress, CallbackInfo ci, @Local Profiler profiler) {
|
||||
if (fullbright.isEnabled() && fullbright.mode.is(Fullbright.Modes.GAMMA)) {
|
||||
RenderSystem.getDevice().createCommandEncoder().clearColorTexture(glTexture, ColorHelper.getArgb(255, 255, 255, 255));
|
||||
RenderSystem.getDevice().createCommandEncoder().clearColorTexture(glTexture, ColorHelper.getArgb(
|
||||
fullbright.alpha.getIntValue(),
|
||||
fullbright.red.getIntValue(),
|
||||
fullbright.green.getIntValue(),
|
||||
fullbright.blue.getIntValue()
|
||||
));
|
||||
profiler.pop();
|
||||
ci.cancel();
|
||||
}
|
||||
|
||||
@@ -1,18 +1,55 @@
|
||||
package me.retucio.camtweaks.mixin;
|
||||
|
||||
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
|
||||
import com.llamalad7.mixinextras.injector.ModifyReturnValue;
|
||||
import com.llamalad7.mixinextras.sugar.Local;
|
||||
import me.retucio.camtweaks.module.ModuleManager;
|
||||
import me.retucio.camtweaks.module.modules.Freecam;
|
||||
import me.retucio.camtweaks.module.modules.Nametags;
|
||||
import net.minecraft.client.render.entity.EntityRendererFactory;
|
||||
import net.minecraft.client.render.entity.LivingEntityRenderer;
|
||||
import net.minecraft.client.render.entity.PlayerEntityRenderer;
|
||||
import net.minecraft.client.render.entity.model.EntityModel;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(LivingEntityRenderer.class)
|
||||
public abstract class LivingEntityRendererMixin {
|
||||
public abstract class LivingEntityRendererMixin<T extends LivingEntity> {
|
||||
|
||||
@Unique
|
||||
Nametags nametags;
|
||||
|
||||
@Inject(method = "<init>", at = @At("TAIL"))
|
||||
private void getModules(EntityRendererFactory.Context ctx, EntityModel<?> model, float shadowRadius, CallbackInfo ci) {
|
||||
nametags = ModuleManager.INSTANCE.getModuleByClass(Nametags.class);
|
||||
}
|
||||
|
||||
@ModifyExpressionValue(method = "hasLabel(Lnet/minecraft/entity/LivingEntity;D)Z", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;getCameraEntity()Lnet/minecraft/entity/Entity;"))
|
||||
private Entity hasLabelGetCameraEntityProxy(Entity cameraEntity) {
|
||||
return ModuleManager.INSTANCE.getModuleByClass(Freecam.class).isEnabled() ? null : cameraEntity;
|
||||
}
|
||||
|
||||
@ModifyExpressionValue(method = "hasLabel(Lnet/minecraft/entity/LivingEntity;D)Z", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;isSneaky()Z"))
|
||||
private boolean renderSneakingPlayerNametags(boolean original) {
|
||||
return (nametags.isEnabled() && nametags.alwaysVisible.isEnabled()) || original;
|
||||
}
|
||||
|
||||
@ModifyExpressionValue(method = "hasLabel(Lnet/minecraft/entity/LivingEntity;D)Z", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;isInvisibleTo(Lnet/minecraft/entity/player/PlayerEntity;)Z"))
|
||||
private boolean renderInvisPlayerNametags(boolean original) {
|
||||
if (nametags.isEnabled() && nametags.alwaysVisible.isEnabled()) return false;
|
||||
else return original;
|
||||
}
|
||||
|
||||
@ModifyReturnValue(method = "hasLabel(Lnet/minecraft/entity/LivingEntity;D)Z", at = @At("RETURN"))
|
||||
private boolean shouldRenderPlayerNametag(boolean original, @Local(argsOnly = true) T livingEntity) {
|
||||
if (nametags.isEnabled() && livingEntity instanceof PlayerEntity) return nametags.entities.isEnabled(EntityType.PLAYER) && original;
|
||||
return original;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package me.retucio.camtweaks.mixin;
|
||||
|
||||
import me.retucio.camtweaks.module.ModuleManager;
|
||||
import me.retucio.camtweaks.module.modules.DamageOverlay;
|
||||
import net.minecraft.client.render.OverlayTexture;
|
||||
import net.minecraft.client.texture.NativeImageBackedTexture;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(OverlayTexture.class)
|
||||
public abstract class OverlayTextureMixin implements AutoCloseable {
|
||||
|
||||
@Shadow @Final
|
||||
private NativeImageBackedTexture texture;
|
||||
|
||||
@Inject(method = "<init>", at = @At("TAIL"))
|
||||
private void modifyDamageOverlayColor(CallbackInfo ci) {
|
||||
ModuleManager.INSTANCE.getModuleByClass(DamageOverlay.class).reloadOverlay(texture);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package me.retucio.camtweaks.mixin;
|
||||
|
||||
import me.retucio.camtweaks.module.ModuleManager;
|
||||
import me.retucio.camtweaks.module.modules.NoRender;
|
||||
import net.minecraft.client.particle.Particle;
|
||||
import net.minecraft.client.particle.ParticleManager;
|
||||
import net.minecraft.particle.ParticleEffect;
|
||||
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.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(ParticleManager.class)
|
||||
public abstract class ParticleManagerMixin {
|
||||
|
||||
@Inject(method = "addParticle(Lnet/minecraft/particle/ParticleEffect;DDDDDD)Lnet/minecraft/client/particle/Particle;", at = @At("HEAD"), cancellable = true)
|
||||
private void noRenderParticles(ParticleEffect parameters, double x, double y, double z, double velocityX, double velocityY, double velocityZ, CallbackInfoReturnable<Particle> cir) {
|
||||
NoRender noRender = ModuleManager.INSTANCE.getModuleByClass(NoRender.class);
|
||||
if (!noRender.isEnabled()) return;
|
||||
if (!noRender.particles.isEnabled(parameters.getType())) cir.setReturnValue(null);
|
||||
}
|
||||
}
|
||||
@@ -22,10 +22,10 @@ public abstract class PlayerEntityMixin extends LivingEntity {
|
||||
@ModifyReturnValue(method = "getDisplayName", at = @At("RETURN"))
|
||||
private Text addHealthIndicator(Text original) {
|
||||
Nametags nametags = ModuleManager.INSTANCE.getModuleByClass(Nametags.class);
|
||||
if (nametags.isEnabled() && !nametags.namePlayers.isEnabled()) return null;
|
||||
if (!nametags.isEnabled() || !nametags.health.isEnabled()) return original;
|
||||
|
||||
float health = getHealth();
|
||||
float absorption = getAbsorptionAmount();
|
||||
Formatting color;
|
||||
|
||||
if (health < 5) color = Formatting.RED;
|
||||
@@ -34,7 +34,19 @@ public abstract class PlayerEntityMixin extends LivingEntity {
|
||||
else color = Formatting.DARK_GREEN;
|
||||
|
||||
// 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 :'(
|
||||
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
|
||||
// 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
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package me.retucio.camtweaks.mixin;
|
||||
|
||||
import me.retucio.camtweaks.module.ModuleManager;
|
||||
import me.retucio.camtweaks.module.modules.ScreenshotPlus;
|
||||
import net.minecraft.client.texture.NativeImage;
|
||||
import net.minecraft.client.util.ScreenshotRecorder;
|
||||
import net.minecraft.text.Text;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@Mixin(ScreenshotRecorder.class)
|
||||
public abstract class ScreenshotRecorderMixin {
|
||||
|
||||
// "method_22691" es la lambda de la función "saveScreenshot()" (por lo menos en 1.21.6)
|
||||
@Inject(method = "method_22691", at = @At(value = "INVOKE", target = "Ljava/util/function/Consumer;accept(Ljava/lang/Object;)V"), cancellable = true)
|
||||
private static void sendActionsMessage(NativeImage nativeImage, File file, Consumer<Text> consumer, CallbackInfo ci) {
|
||||
ScreenshotPlus screenshotPlus = getScreenshotPlus();
|
||||
if (screenshotPlus.isEnabled()) ci.cancel();
|
||||
}
|
||||
|
||||
@Inject(method = "method_22691", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/texture/NativeImage;writeTo(Ljava/io/File;)V"), cancellable = true)
|
||||
private static void interceptScreenshotFile(NativeImage nativeImage, File file, Consumer<Text> consumer, CallbackInfo ci) throws IOException {
|
||||
ScreenshotPlus screenshotPlus = getScreenshotPlus();
|
||||
|
||||
// aunque el módulo esté apagado, pasar las referencias para poder usar los comandos para las capturas
|
||||
screenshotPlus.setScreenshot(nativeImage);
|
||||
screenshotPlus.setScreenshotFile(file);
|
||||
|
||||
if (!screenshotPlus.isEnabled()) return;
|
||||
|
||||
screenshotPlus.sendScreenshotMessage();
|
||||
|
||||
switch (screenshotPlus.defaultAction.getValue()) {
|
||||
case COPY -> screenshotPlus.copyScreenshot(nativeImage);
|
||||
case SAVE -> screenshotPlus.saveScreenshot();
|
||||
case NONE -> ci.cancel();
|
||||
}
|
||||
|
||||
ci.cancel();
|
||||
}
|
||||
|
||||
@Unique
|
||||
private static ScreenshotPlus getScreenshotPlus() {
|
||||
return ModuleManager.INSTANCE.getModuleByClass(ScreenshotPlus.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package me.retucio.camtweaks.mixin;
|
||||
|
||||
import com.llamalad7.mixinextras.injector.ModifyReturnValue;
|
||||
import me.retucio.camtweaks.module.ModuleManager;
|
||||
import me.retucio.camtweaks.module.modules.NoRender;
|
||||
import net.minecraft.client.render.entity.feature.StuckArrowsFeatureRenderer;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
|
||||
@Mixin(StuckArrowsFeatureRenderer.class)
|
||||
public abstract class StuckArrowsFeatureRendererMixin {
|
||||
|
||||
@ModifyReturnValue(method = "getObjectCount", at = @At("RETURN"))
|
||||
private int noRenderStuckArrows(int original) {
|
||||
NoRender noRender = ModuleManager.INSTANCE.getModuleByClass(NoRender.class);
|
||||
if (noRender.isEnabled() && !noRender.stuckArrows.isEnabled()) return 0;
|
||||
return original;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package me.retucio.camtweaks.mixin;
|
||||
|
||||
import me.retucio.camtweaks.module.ModuleManager;
|
||||
import me.retucio.camtweaks.module.modules.NoRender;
|
||||
import net.minecraft.client.font.TextRenderer;
|
||||
import net.minecraft.text.Style;
|
||||
import net.minecraft.text.TextColor;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.*;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
// falta italics pero no sé dónde se comprueba eso, no es aquí :P
|
||||
@Mixin(TextRenderer.Drawer.class)
|
||||
public abstract class TextRendererDrawerMixin {
|
||||
|
||||
@Unique
|
||||
NoRender noRender;
|
||||
|
||||
@Inject(method = "<init>(Lnet/minecraft/client/font/TextRenderer;FFIIZ)V", at = @At("TAIL"))
|
||||
private void getModules(TextRenderer textRenderer, float x, float y, int color, int backgroundColor, boolean shadow, CallbackInfo ci) {
|
||||
noRender = ModuleManager.INSTANCE.getModuleByClass(NoRender.class);
|
||||
}
|
||||
|
||||
@Redirect(method = "accept", at = @At(value = "INVOKE", target = "Lnet/minecraft/text/Style;isBold()Z"))
|
||||
private boolean noRenderBold(Style style) {
|
||||
return !(noRender.isEnabled() && !noRender.bold.isEnabled()) && style.isBold();
|
||||
}
|
||||
|
||||
@Redirect(method = "accept", at = @At(value = "INVOKE", target = "Lnet/minecraft/text/Style;isUnderlined()Z"))
|
||||
private boolean noRenderUnderlined(Style style) {
|
||||
return !(noRender.isEnabled() && !noRender.underlined.isEnabled()) && style.isUnderlined();
|
||||
}
|
||||
|
||||
@Redirect(method = "accept", at = @At(value = "INVOKE", target = "Lnet/minecraft/text/Style;isStrikethrough()Z"))
|
||||
private boolean noRenderStrikethrough(Style style) {
|
||||
return !(noRender.isEnabled() && !noRender.strikethrough.isEnabled()) && style.isStrikethrough();
|
||||
}
|
||||
|
||||
@Redirect(method = "accept", at = @At(value = "INVOKE", target = "Lnet/minecraft/text/Style;isObfuscated()Z"))
|
||||
private boolean noRenderMTS(Style style) {
|
||||
return !(noRender.isEnabled() && !noRender.scrambledText.isEnabled()) && style.isObfuscated();
|
||||
}
|
||||
|
||||
@ModifyArg(method = "accept", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/font/TextRenderer$Drawer;getRenderColor(Lnet/minecraft/text/TextColor;)I"))
|
||||
private TextColor noRenderColor(TextColor original) {
|
||||
return !noRender.color.is(NoRender.Colors.DEFAULT) ? TextColor.fromFormatting(noRender.color.getValue().toFormatting()) : original;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package me.retucio.camtweaks.mixin;
|
||||
|
||||
import me.retucio.camtweaks.module.ModuleManager;
|
||||
import me.retucio.camtweaks.module.modules.NoRender;
|
||||
import net.minecraft.client.render.Camera;
|
||||
import net.minecraft.client.render.VertexConsumerProvider;
|
||||
import net.minecraft.client.render.WeatherRendering;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import net.minecraft.particle.ParticlesMode;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@Mixin(WeatherRendering.class)
|
||||
public abstract class WeatherRenderingMixin {
|
||||
|
||||
@Unique
|
||||
NoRender noRender;
|
||||
|
||||
@Inject(method = "<init>", at = @At("TAIL"))
|
||||
public void getModules(CallbackInfo ci) {
|
||||
noRender = ModuleManager.INSTANCE.getModuleByClass(NoRender.class);
|
||||
}
|
||||
|
||||
@Inject(method = "addParticlesAndSound", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/world/ClientWorld;addParticleClient(Lnet/minecraft/particle/ParticleEffect;DDDDDD)V"), cancellable = true)
|
||||
private void noRainParticles(ClientWorld world, Camera camera, int ticks, ParticlesMode particlesMode, CallbackInfo ci) {
|
||||
if (noRender.isEnabled() && !noRender.rain.isEnabled()) ci.cancel();
|
||||
}
|
||||
|
||||
@Inject(method = "renderPrecipitation(Lnet/minecraft/client/render/VertexConsumerProvider;Lnet/minecraft/util/math/Vec3d;IFLjava/util/List;Ljava/util/List;)V", at = @At("HEAD"))
|
||||
private void noRenderRainAndSnow(VertexConsumerProvider vertexConsumers, Vec3d pos, int range, float gradient, List<?> rainPieces, List<?> snowPieces, CallbackInfo ci) {
|
||||
if (noRender.isEnabled()) {
|
||||
if (!noRender.rain.isEnabled()) rainPieces.clear();
|
||||
if (!noRender.snow.isEnabled()) snowPieces.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,16 @@
|
||||
package me.retucio.camtweaks.mixin;
|
||||
|
||||
import me.retucio.camtweaks.module.ModuleManager;
|
||||
import me.retucio.camtweaks.module.modules.BlockOutline;
|
||||
import me.retucio.camtweaks.module.modules.Freecam;
|
||||
import net.minecraft.client.render.WorldRenderer;
|
||||
import net.minecraft.util.math.ColorHelper;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
@Mixin(WorldRenderer.class)
|
||||
public abstract class WorldRendererMixin {
|
||||
@@ -14,4 +19,30 @@ public abstract class WorldRendererMixin {
|
||||
private boolean renderSetupTerrainModifyArg(boolean hasForcedFrustum) {
|
||||
return ModuleManager.INSTANCE.getModuleByClass(Freecam.class).isEnabled() || hasForcedFrustum;
|
||||
}
|
||||
|
||||
@Redirect(method = "renderTargetBlockOutline", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/math/ColorHelper;withAlpha(II)I"))
|
||||
private int modifyBlockOutlineColor(int alpha, int rgb) {
|
||||
BlockOutline outline = ModuleManager.INSTANCE.getModuleByClass(BlockOutline.class);
|
||||
if (!outline.isEnabled()) return ColorHelper.withAlpha(alpha, rgb);
|
||||
|
||||
if (outline.rainbow.isEnabled()) {
|
||||
float speed = 10001 - outline.rainbowSpeed.getFloatValue(); // 10001 para evitar divisiones por cero
|
||||
float hue = (System.currentTimeMillis() % (int) speed) / speed;
|
||||
Color gamingProMax = Color.getHSBColor(hue, 1, 1);
|
||||
|
||||
return new Color(
|
||||
gamingProMax.getRed(),
|
||||
gamingProMax.getGreen(),
|
||||
gamingProMax.getBlue(),
|
||||
outline.alpha.getIntValue()
|
||||
).getRGB();
|
||||
} else {
|
||||
return new Color(
|
||||
outline.red.getIntValue(),
|
||||
outline.green.getIntValue(),
|
||||
outline.blue.getIntValue(),
|
||||
outline.alpha.getIntValue()
|
||||
).getRGB();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
package me.retucio.camtweaks.mixin.accessor;
|
||||
|
||||
import net.minecraft.client.render.entity.state.EntityRenderState;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
@Mixin(EntityRenderState.class)
|
||||
public interface EntityRenderStateAccessor {
|
||||
|
||||
@Accessor("sneaking")
|
||||
void setSneaking(boolean sneaking);
|
||||
}
|
||||
@@ -6,7 +6,7 @@ import me.retucio.camtweaks.event.events.camtweaks.ToggleModuleEvent;
|
||||
import me.retucio.camtweaks.module.settings.BooleanSetting;
|
||||
import me.retucio.camtweaks.module.settings.EnumSetting;
|
||||
import me.retucio.camtweaks.module.settings.KeySetting;
|
||||
import me.retucio.camtweaks.module.settings.Setting;
|
||||
import me.retucio.camtweaks.module.settings.AbstractSetting;
|
||||
import me.retucio.camtweaks.util.ChatUtil;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
@@ -22,13 +22,14 @@ public class Module {
|
||||
private String name;
|
||||
private String description;
|
||||
private boolean enabled;
|
||||
private boolean saveSettings = true;
|
||||
|
||||
// dejar al usuario elegir si el módulo debería apagarse tras soltar su tecla asignada, o si la tecla debería alternar su estado
|
||||
protected EnumSetting<KeyModes> keyMode = new EnumSetting<>("modo de tecla", "cómo interpretar la tecla configurada", KeyModes.class, KeyModes.TOGGLE);
|
||||
protected KeySetting bind = new KeySetting("tecla", "tecla asignada al módulo, ESC para desactivar", GLFW.GLFW_KEY_UNKNOWN);
|
||||
protected BooleanSetting notify = new BooleanSetting("notificar", "notificar en el chat al activar / desactivar", true);
|
||||
|
||||
private final List<Setting> settings = new ArrayList<>();
|
||||
private final List<AbstractSetting> settings = new ArrayList<>();
|
||||
|
||||
protected MinecraftClient mc = MinecraftClient.getInstance();
|
||||
|
||||
@@ -40,19 +41,19 @@ public class Module {
|
||||
|
||||
|
||||
// ajustes
|
||||
public List<Setting> getSettings() {
|
||||
public List<AbstractSetting> getSettings() {
|
||||
return settings;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <S extends Setting> S addSetting(Setting setting) {
|
||||
public <S extends AbstractSetting> S addSetting(AbstractSetting setting) {
|
||||
settings.add(setting);
|
||||
setting.setModule(this);
|
||||
return (S) setting; // por convenciencia
|
||||
}
|
||||
|
||||
public void addSettings(Setting... settings) {
|
||||
for (Setting setting : settings) addSetting(setting);
|
||||
public void addSettings(AbstractSetting... settings) {
|
||||
for (AbstractSetting setting : settings) addSetting(setting);
|
||||
}
|
||||
|
||||
|
||||
@@ -115,6 +116,14 @@ public class Module {
|
||||
return keyMode.is(KeyModes.HOLD);
|
||||
}
|
||||
|
||||
public boolean shouldSaveSettings() {
|
||||
return saveSettings;
|
||||
}
|
||||
|
||||
public void shouldSaveSettings(boolean value) {
|
||||
this.saveSettings = value;
|
||||
}
|
||||
|
||||
public int getKey() {
|
||||
return bind.getKey();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -22,19 +23,29 @@ public class ModuleManager {
|
||||
addModules();
|
||||
}
|
||||
|
||||
// por order alfabético y todo, flipas
|
||||
// por orden alfabético y todo, flipas
|
||||
private void addModules() {
|
||||
modules.add(new AntiInvis());
|
||||
modules.add(new BlockOutline());
|
||||
modules.add(new BossbarStack());
|
||||
modules.add(new ChatPlus());
|
||||
modules.add(new CritsPlus());
|
||||
modules.add(new DamageOverlay());
|
||||
modules.add(new FakePlayer());
|
||||
modules.add(new Freecam());
|
||||
modules.add(new Freelook());
|
||||
modules.add(new Fullbright());
|
||||
modules.add(new HandView());
|
||||
modules.add(new PerspectivePlus());
|
||||
modules.add(new HUD());
|
||||
modules.add(new Nametags());
|
||||
modules.add(new NoRender());
|
||||
modules.add(new PerspectivePlus());
|
||||
modules.add(new ScreenshotPlus());
|
||||
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()) {
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package me.retucio.camtweaks.module.modules;
|
||||
|
||||
import me.retucio.camtweaks.module.Module;
|
||||
|
||||
/** continúa en:
|
||||
* @see me.retucio.camtweaks.mixin.EntityMixin
|
||||
*/
|
||||
|
||||
public class AntiInvis extends Module {
|
||||
|
||||
public AntiInvis() {
|
||||
super("anti invis", "te permite ver a los jugadores invisibles");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
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.NumberSetting;
|
||||
|
||||
/** continúa en:
|
||||
* @see me.retucio.camtweaks.mixin.WorldRendererMixin
|
||||
*/
|
||||
|
||||
public class BlockOutline extends Module {
|
||||
|
||||
public BooleanSetting rainbow = addSetting(new BooleanSetting("RGB", "erre ge be gueiming", false));
|
||||
public NumberSetting rainbowSpeed = addSetting(new NumberSetting("velocidad", "velocidad de la bandera gay", 2000, 0, 10000, 2));
|
||||
|
||||
public NumberSetting red = addSetting(new NumberSetting("rojo", "factor r del rbg", 0, 0, 255, 1));
|
||||
public NumberSetting green = addSetting(new NumberSetting("verde", "factor g del rgb", 0, 0, 255, 1));
|
||||
public NumberSetting blue = addSetting(new NumberSetting("azul", "factor b del rbg", 0, 0, 255, 1));
|
||||
|
||||
public NumberSetting alpha = addSetting(new NumberSetting("opacidad", "transparencia invertida", 102, 0, 255, 1));
|
||||
|
||||
public BlockOutline() {
|
||||
super("contorno", "customiza el contorno de los bloques");
|
||||
rainbow.onUpdate(v -> {
|
||||
rainbowSpeed.setVisible(v);
|
||||
red.setVisible(!v);
|
||||
green.setVisible(!v);
|
||||
blue.setVisible(!v);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,6 @@ import me.retucio.camtweaks.event.events.SendMessageEvent;
|
||||
import me.retucio.camtweaks.module.Module;
|
||||
import me.retucio.camtweaks.module.settings.BooleanSetting;
|
||||
import me.retucio.camtweaks.module.settings.NumberSetting;
|
||||
import me.retucio.camtweaks.ui.frames.ClickGUISettingsFrame;
|
||||
import me.retucio.camtweaks.util.ChatUtil;
|
||||
import me.retucio.camtweaks.util.interfaces.IChatHudLine;
|
||||
import me.retucio.camtweaks.util.interfaces.IChatHudLineVisible;
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
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.NumberSetting;
|
||||
|
||||
/** continúa en:
|
||||
* @see me.retucio.camtweaks.mixin.DamageParticleMixin
|
||||
* @see me.retucio.camtweaks.mixin.DamageParticleFactoryMixin
|
||||
*/
|
||||
|
||||
public class CritsPlus extends Module {
|
||||
|
||||
public BooleanSetting rainbow = addSetting(new BooleanSetting("LUCES GAMING", "PARTÍCULAS GAMING", false));
|
||||
public NumberSetting rainbowSpeed = addSetting(new NumberSetting("velocidad del erre ge be", "qué tan gaming son las luces gaming", 1000, 0, 10000, 2));
|
||||
|
||||
public NumberSetting red = addSetting(new NumberSetting("rojo", "comunismo", 0, 0, 255, 1));
|
||||
public NumberSetting green = addSetting(new NumberSetting("verde", "vox", 0, 0, 255, 1));
|
||||
public NumberSetting blue = addSetting(new NumberSetting("azul", "metanfetamina", 255, 0, 255, 1));
|
||||
public NumberSetting alpha = addSetting(new NumberSetting("alpha", "opacidad", 255, 0, 255, 1));
|
||||
|
||||
public NumberSetting scale = addSetting(new NumberSetting("escala", "tamaño", 1, 0, 2, 0.05));
|
||||
public NumberSetting multiplier; // no sé dónde se calcula cuántas partículas aparecen :/
|
||||
public NumberSetting velocityMultipler = addSetting(new NumberSetting("dispersión", "multiplicador de la velocidad de dispersión", 1, 0, 10, 0.1));
|
||||
public NumberSetting gravity = addSetting(new NumberSetting("gravedad", "multiplicador de fuerza de gravedad", 1, 0, 10, 0.1));
|
||||
public NumberSetting maxAge = addSetting(new NumberSetting("vida máxima", "cuánto persiste la partícula", 4, 0, 50, 1));
|
||||
public BooleanSetting collide = addSetting(new BooleanSetting("colisionar", "colisionar con bloques", false));
|
||||
|
||||
public CritsPlus() {
|
||||
super("críticos", "cambia la apariencia de los críticos al gusto");
|
||||
rainbow.onUpdate(v -> {
|
||||
rainbowSpeed.setVisible(v);
|
||||
red.setVisible(!v);
|
||||
green.setVisible(!v);
|
||||
blue.setVisible(!v);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package me.retucio.camtweaks.module.modules;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.textures.GpuTextureView;
|
||||
import me.retucio.camtweaks.module.Module;
|
||||
import me.retucio.camtweaks.module.settings.NumberSetting;
|
||||
import net.minecraft.client.texture.NativeImage;
|
||||
import net.minecraft.client.texture.NativeImageBackedTexture;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
/** continúa en:
|
||||
* @see me.retucio.camtweaks.mixin.OverlayTextureMixin
|
||||
*/
|
||||
|
||||
public class DamageOverlay extends Module {
|
||||
|
||||
public NumberSetting red = addSetting(new NumberSetting("rojo", "r o j o", 255, 0, 255, 1));
|
||||
public NumberSetting green = addSetting(new NumberSetting("verde", "v e r d e", 0, 0, 255, 1));
|
||||
public NumberSetting blue = addSetting(new NumberSetting("azul", "a z u l", 0, 0, 255, 1));
|
||||
public NumberSetting alpha = addSetting(new NumberSetting("alpha", "o p a c i d a d", 77, 0, 255, 1));
|
||||
|
||||
private NativeImageBackedTexture texture = null;
|
||||
|
||||
public DamageOverlay() {
|
||||
super("superposición de daño", "modifica el color en el que se renderiza la superposición de recibir daño");
|
||||
|
||||
NumberSetting[] settings = {red, green, blue, alpha};
|
||||
for (NumberSetting setting : settings)
|
||||
setting.onUpdate(v -> reloadOverlayIfReady());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
reloadOverlayIfReady();
|
||||
super.onEnable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
reloadOverlayIfReady();
|
||||
super.onDisable();
|
||||
}
|
||||
|
||||
private void reloadOverlayIfReady() {
|
||||
if (texture != null && texture.getImage() != null) reloadOverlay(texture);
|
||||
}
|
||||
|
||||
// recargar el overlay (superposición)
|
||||
public void reloadOverlay(NativeImageBackedTexture texture) {
|
||||
if (this.texture == null) this.texture = texture;
|
||||
|
||||
int color = isEnabled() ?
|
||||
new Color(red.getIntValue(), green.getIntValue(), blue.getIntValue(), 255 - alpha.getIntValue()).getRGB()
|
||||
: new Color(255, 0, 0, 178).getRGB();
|
||||
|
||||
NativeImage image = texture.getImage();
|
||||
for (int y = 0; y < 8; y++)
|
||||
for (int x = 0; x < 16; x++)
|
||||
image.setColorArgb(x, y, color);
|
||||
|
||||
uploadTexture();
|
||||
}
|
||||
|
||||
// resubir las texturas
|
||||
private void uploadTexture() {
|
||||
GpuTextureView overlayTex = RenderSystem.getShaderTexture(33985);
|
||||
RenderSystem.setShaderTexture(33985, overlayTex);
|
||||
|
||||
texture.upload();
|
||||
|
||||
GpuTextureView mainTex = RenderSystem.getShaderTexture(33984);
|
||||
RenderSystem.setShaderTexture(33984, mainTex);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package me.retucio.camtweaks.module.modules;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import me.retucio.camtweaks.module.Module;
|
||||
import me.retucio.camtweaks.module.settings.StringSetting;
|
||||
import net.minecraft.client.network.OtherClientPlayerEntity;
|
||||
import net.minecraft.entity.Entity;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class FakePlayer extends Module {
|
||||
|
||||
public StringSetting name = addSetting(new StringSetting("nombre", "qué nombre asignarle al jugador", "apio boy", 22));
|
||||
|
||||
private OtherClientPlayerEntity player = null;
|
||||
|
||||
public FakePlayer() {
|
||||
super("jugador falso", "invoca una entidad de jugador falsa por motivos de testeo");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
if (mc.world == null) return;
|
||||
|
||||
player = new OtherClientPlayerEntity(mc.world, new GameProfile(UUID.randomUUID(), name.getValue()));
|
||||
// player.copyPositionAndRotation(mc.player);
|
||||
player.copyFrom(mc.player);
|
||||
|
||||
mc.world.addEntity(player);
|
||||
|
||||
super.onEnable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
if (mc.world == null || player == null) return;
|
||||
|
||||
player.setRemoved(Entity.RemovalReason.KILLED);
|
||||
player.onRemoved();
|
||||
player = null;
|
||||
|
||||
super.onDisable();
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package me.retucio.camtweaks.module.modules;
|
||||
|
||||
import me.retucio.camtweaks.event.Stage;
|
||||
import me.retucio.camtweaks.event.SubscribeEvent;
|
||||
import me.retucio.camtweaks.event.events.*;
|
||||
import me.retucio.camtweaks.module.Module;
|
||||
@@ -24,6 +25,7 @@ import org.lwjgl.glfw.GLFW;
|
||||
/** continúa en:
|
||||
* @see me.retucio.camtweaks.mixin.CameraMixin
|
||||
* @see me.retucio.camtweaks.mixin.ChunkBorderDebugRendererMixin
|
||||
* @see me.retucio.camtweaks.mixin.ClientPlayerInteractionManagerMixin
|
||||
* @see me.retucio.camtweaks.mixin.CompassStateMixin
|
||||
* @see me.retucio.camtweaks.mixin.EntityMixin
|
||||
* @see me.retucio.camtweaks.mixin.GameRendererMixin
|
||||
@@ -63,7 +65,7 @@ public class Freecam extends Module {
|
||||
private float yaw, pitch;
|
||||
|
||||
public Freecam() {
|
||||
super("cámara libre", "perrmite a la cámara moverse independientemente del jugador. útil para explorar alrededores");
|
||||
super("cámara libre", "permite a la cámara moverse independientemente del jugador. útil para explorar alrededores");
|
||||
assignKey(GLFW.GLFW_KEY_V);
|
||||
speedSetting.onUpdate(newSpeed -> speed = newSpeed);
|
||||
}
|
||||
@@ -187,12 +189,13 @@ public class Freecam extends Module {
|
||||
@SubscribeEvent
|
||||
public void onPacketSend(PacketEvent.Send event) {
|
||||
if (!isEnabled() || !cancelActionPackets.isEnabled()) return;
|
||||
if (event.getStage() != Stage.PRE) return;
|
||||
|
||||
Packet<?> p = event.getPacket();
|
||||
if (p instanceof PlayerActionC2SPacket
|
||||
|| p instanceof PlayerInteractBlockC2SPacket
|
||||
|| p instanceof PlayerInteractItemC2SPacket
|
||||
|| p instanceof HandSwingC2SPacket) {
|
||||
Packet<?> packet = event.getPacket();
|
||||
if (packet instanceof PlayerActionC2SPacket
|
||||
|| packet instanceof PlayerInteractBlockC2SPacket
|
||||
|| packet instanceof PlayerInteractItemC2SPacket
|
||||
|| packet instanceof HandSwingC2SPacket) {
|
||||
event.cancel();
|
||||
}
|
||||
}
|
||||
@@ -200,7 +203,7 @@ public class Freecam extends Module {
|
||||
@SubscribeEvent
|
||||
public void onKey(KeyEvent event) {
|
||||
if (mc.currentScreen != null) return;
|
||||
if (KeyUtil.isKeyDown(GLFW.GLFW_KEY_F3)) return; // ?
|
||||
if (KeyUtil.isKeyDown(GLFW.GLFW_KEY_F3)) return;
|
||||
|
||||
boolean shouldCancel = true;
|
||||
if (mc.options.forwardKey.matchesKey(event.getKey(), event.getScancode())) {
|
||||
|
||||
@@ -3,6 +3,7 @@ package me.retucio.camtweaks.module.modules;
|
||||
import me.retucio.camtweaks.mixin.accessor.StatusEffectInstanceAccessor;
|
||||
import me.retucio.camtweaks.module.Module;
|
||||
import me.retucio.camtweaks.module.settings.EnumSetting;
|
||||
import me.retucio.camtweaks.module.settings.NumberSetting;
|
||||
import net.minecraft.entity.effect.StatusEffectInstance;
|
||||
import net.minecraft.entity.effect.StatusEffects;
|
||||
import net.minecraft.registry.Registries;
|
||||
@@ -16,10 +17,29 @@ public class Fullbright extends Module {
|
||||
|
||||
public EnumSetting<Modes> mode = addSetting(new EnumSetting<>("modo", "qué modo de iluminación emplear (usar poción con shaders)", Modes.class, Modes.GAMMA));
|
||||
|
||||
public NumberSetting red = addSetting(new NumberSetting("rojo", "cantidad de rojo a aplicar",
|
||||
255, 0, 255, 1));
|
||||
|
||||
public NumberSetting green = addSetting(new NumberSetting("verde", "cantidad de verde a aplicar",
|
||||
255, 0, 255, 1));
|
||||
|
||||
public NumberSetting blue = addSetting(new NumberSetting("azul", "cantidad de azul a aplicar",
|
||||
255, 0, 255, 1));
|
||||
|
||||
public NumberSetting alpha = addSetting(new NumberSetting("opacidad", "opacidad del shader",
|
||||
255, 0, 255, 1));
|
||||
|
||||
public Fullbright() {
|
||||
super("brilli brilli", "deshabilita la oscuridad");
|
||||
super("brilli brilli", "deshabilita la oscuridad (y aplica colores a los shaders)");
|
||||
assignKey(GLFW.GLFW_KEY_K);
|
||||
mode.onUpdate(mode -> { if (mode != Modes.POTION) disableNightVision(); });
|
||||
mode.onUpdate(mode -> {
|
||||
boolean v = mode.equals(Modes.GAMMA);
|
||||
red.setVisible(v);
|
||||
green.setVisible(v);
|
||||
blue.setVisible(v);
|
||||
alpha.setVisible(v);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -34,7 +54,7 @@ public class Fullbright extends Module {
|
||||
|
||||
if (mc.player.hasStatusEffect(Registries.STATUS_EFFECT.getEntry(StatusEffects.NIGHT_VISION.value()))) {
|
||||
StatusEffectInstance instance = mc.player.getStatusEffect(Registries.STATUS_EFFECT.getEntry(StatusEffects.NIGHT_VISION.value()));
|
||||
if (instance != null && instance.getDuration() < 69) ((StatusEffectInstanceAccessor) instance).setDuration(69);
|
||||
if (instance != null && instance.getDuration() < 5200) ((StatusEffectInstanceAccessor) instance).setDuration(5200);
|
||||
} else {
|
||||
mc.player.addStatusEffect(new StatusEffectInstance(Registries.STATUS_EFFECT.getEntry(StatusEffects.NIGHT_VISION.value()), 69, 0));
|
||||
}
|
||||
@@ -53,8 +73,6 @@ public class Fullbright extends Module {
|
||||
|
||||
private final String name;
|
||||
Modes(String name) { this.name = name; }
|
||||
|
||||
@Override
|
||||
public String toString() { return name; }
|
||||
@Override public String toString() { return name; }
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,11 @@
|
||||
package me.retucio.camtweaks.module.modules;
|
||||
|
||||
import me.retucio.camtweaks.CameraTweaks;
|
||||
import me.retucio.camtweaks.command.CommandManager;
|
||||
import me.retucio.camtweaks.event.SubscribeEvent;
|
||||
import me.retucio.camtweaks.event.events.TickEvent;
|
||||
import me.retucio.camtweaks.event.events.camtweaks.LoadClickGUIEvent;
|
||||
import me.retucio.camtweaks.event.events.camtweaks.LoadCommandManagerEvent;
|
||||
import me.retucio.camtweaks.module.Module;
|
||||
import me.retucio.camtweaks.module.ModuleManager;
|
||||
import me.retucio.camtweaks.module.settings.BooleanSetting;
|
||||
@@ -12,37 +17,57 @@ import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
import static me.retucio.camtweaks.util.Colors.*;
|
||||
|
||||
// módulo no visible solo para los ajustes de la interfaz (y del cliente en general)
|
||||
public class GUI extends Module {
|
||||
|
||||
public NumberSetting red = addSetting(new NumberSetting("rojo", "cantidad de rojo en el RGB del marco", 0, 0, 255, 1));
|
||||
public NumberSetting green = addSetting(new NumberSetting("verde", "cantidad de verde en el RGB del marco", 0, 0, 255, 1));
|
||||
public NumberSetting blue = addSetting(new NumberSetting("azul", "cantidad de azul en el RGB del marco", 255, 0, 255, 1));
|
||||
public NumberSetting alpha = addSetting(new NumberSetting("alpha", "opacidad del marco", 180, 0, 255, 1));
|
||||
public BooleanSetting rainbow = addSetting(new BooleanSetting("gaming", "gaming", false));
|
||||
public NumberSetting rainbowSpeed = addSetting(new NumberSetting("velocidad del gaming", "velocidad, del gaming.",
|
||||
1000, 0, 10000, 2));
|
||||
public NumberSetting saturation = addSetting(new NumberSetting("saturación del gaming", "saturación, del gaming",
|
||||
1, 0, 1, 0.01));
|
||||
public NumberSetting brightness = addSetting(new NumberSetting("brillo del gaming", "brillo, del gaming",
|
||||
0.8, 0, 1, 0.01));
|
||||
|
||||
public NumberSetting red = addSetting(new NumberSetting("rojo", "cantidad de rojo en el RGB del marco", 70, 0, 255, 1));
|
||||
public NumberSetting green = addSetting(new NumberSetting("verde", "cantidad de verde en el RGB del marco", 20, 0, 255, 1));
|
||||
public NumberSetting blue = addSetting(new NumberSetting("azul", "cantidad de azul en el RGB del marco", 210, 0, 255, 1));
|
||||
public NumberSetting alpha = addSetting(new NumberSetting("alpha", "opacidad del marco", 230, 0, 255, 1));
|
||||
|
||||
// números negativos para deslizamiento inverso, 0 para desactivar
|
||||
public NumberSetting scrollSens = addSetting(new NumberSetting("sensibilidad del scroll", "qué tan sensible es la interfaz a la rueda del ratón",
|
||||
5, 0, 15, 0.5));
|
||||
5, -15, 15, 0.5));
|
||||
public BooleanSetting scrollBar = addSetting(new BooleanSetting("barra de desplazamiento", "renderizar una barra de desplazamiento a la derecha de la interfaz", true));
|
||||
|
||||
public BooleanSetting searchBar = addSetting(new BooleanSetting("barra de búsqueda", "renderizar una barra de búsqueda que filtra resultados en todos los marcos abiertos", true));
|
||||
public BooleanSetting matchCase = addSetting(new BooleanSetting("distinguir mayúsculas", "la búsqueda es sensible a mayúsculas y minúsculas", false));
|
||||
// ^^^ no sé de qué sirve porque está todo en minúsculas pero bueno
|
||||
|
||||
public BooleanSetting blur = addSetting(new BooleanSetting("desenfoque", "desenfocar el fondo mientras la interfaz está abierta", true));
|
||||
|
||||
public StringSetting commandPrefix = addSetting(new StringSetting("prefijo", "prefijo de los comandos", "$", 10));
|
||||
public StringSetting chatName = addSetting(new StringSetting("nombre", "qué nombre usar en notificaciones por el chat", "smegma", 20));
|
||||
|
||||
public BooleanSetting multipleKeybinds = addSetting(new BooleanSetting("teclas multimódulo", "permitir asignar la misma tecla a más de un módulo", false));
|
||||
|
||||
private int prevRed, prevGreen, prevBlue;
|
||||
|
||||
public GUI() {
|
||||
super("interfaz", "ajustes de la interfaz, y otros misceláneos");
|
||||
assignKey(GLFW.GLFW_KEY_RIGHT_SHIFT);
|
||||
|
||||
// registrar aquí, porque no se añade a ModuleManager.modules. de lo contrario no podría detectar eventos
|
||||
CameraTweaks.EVENT_BUS.register(this);
|
||||
|
||||
keyMode.setVisible(false);
|
||||
notify.setVisible(false);
|
||||
|
||||
commandPrefix.onUpdate(prefix -> CommandManager.INSTANCE.setPrefix(prefix));
|
||||
red.onUpdate(r -> {frameHeadRed = r.intValue(); updateFrameHeadColor();});
|
||||
green.onUpdate(g -> {frameHeadGreen = g.intValue(); updateFrameHeadColor();});
|
||||
blue.onUpdate(b -> {frameHeadBlue = b.intValue(); updateFrameHeadColor();});
|
||||
alpha.onUpdate(a -> {frameHeadAlpha = a.intValue(); updateFrameHeadColor();});
|
||||
searchBar.onUpdate(v -> matchCase.setVisible(v));
|
||||
}
|
||||
|
||||
if (mc != null) mc.execute(() -> commandPrefix.setDefaultValue(CommandManager.INSTANCE.getPrefix()));
|
||||
@SubscribeEvent
|
||||
public void onLoadCommandManager(LoadCommandManagerEvent event) {
|
||||
commandPrefix.onUpdate(prefix -> CommandManager.INSTANCE.setPrefix(prefix));
|
||||
commandPrefix.setDefaultValue(CommandManager.INSTANCE.getPrefix());
|
||||
|
||||
chatName.onUpdate(name -> {
|
||||
ChatUtil.updatePrefix(name);
|
||||
@@ -50,12 +75,65 @@ public class GUI extends Module {
|
||||
});
|
||||
}
|
||||
|
||||
private void updateFrameHeadColor() {
|
||||
Colors.frameHeadColor = new Color(
|
||||
frameHeadRed,
|
||||
frameHeadGreen,
|
||||
frameHeadBlue,
|
||||
frameHeadAlpha
|
||||
).getRGB();
|
||||
// lógica un poco prolija pero bueno
|
||||
@SubscribeEvent
|
||||
public void onLoadClickGUI(LoadClickGUIEvent event) {
|
||||
rainbow.onUpdate(v -> {
|
||||
if (v) {
|
||||
prevRed = red.getIntValue();
|
||||
prevGreen = green.getIntValue();
|
||||
prevBlue = blue.getIntValue();
|
||||
} else {
|
||||
red.setValue(prevRed);
|
||||
green.setValue(prevGreen);
|
||||
blue.setValue(prevBlue);
|
||||
}
|
||||
|
||||
rainbowSpeed.setVisible(v);
|
||||
saturation.setVisible(v);
|
||||
brightness.setVisible(v);
|
||||
red.setVisible(!v);
|
||||
green.setVisible(!v);
|
||||
blue.setVisible(!v);
|
||||
|
||||
applyRGBAColorUpdates();
|
||||
});
|
||||
|
||||
red.onUpdate(r -> applyRGBAColorUpdates());
|
||||
green.onUpdate(g -> applyRGBAColorUpdates());
|
||||
blue.onUpdate(b -> applyRGBAColorUpdates());
|
||||
alpha.onUpdate(a -> applyRGBAColorUpdates());
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onTick(TickEvent.Post event) {
|
||||
if (rainbow.isEnabled()) {
|
||||
float speed = (float) (rainbowSpeed.getMax() - rainbowSpeed.getValue());
|
||||
float hue = (System.currentTimeMillis() % (long) speed) / speed;
|
||||
Color color = Color.getHSBColor(hue, saturation.getFloatValue(), brightness.getFloatValue());
|
||||
|
||||
Colors.red = color.getRed();
|
||||
Colors.green = color.getGreen();
|
||||
Colors.blue = color.getBlue();
|
||||
|
||||
updateColor();
|
||||
}
|
||||
}
|
||||
|
||||
private void applyRGBAColorUpdates() {
|
||||
Colors.red = red.getIntValue();
|
||||
Colors.green = green.getIntValue();
|
||||
Colors.blue = blue.getIntValue();
|
||||
Colors.alpha = alpha.getIntValue();
|
||||
updateColor();
|
||||
}
|
||||
|
||||
private void updateColor() {
|
||||
Colors.updateAllColors(new Color(
|
||||
Colors.red,
|
||||
Colors.green,
|
||||
Colors.blue,
|
||||
Colors.alpha
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -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> 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; }
|
||||
}
|
||||
}
|
||||
@@ -5,8 +5,10 @@ import com.google.gson.JsonParser;
|
||||
import me.retucio.camtweaks.module.Module;
|
||||
import me.retucio.camtweaks.module.settings.BooleanSetting;
|
||||
import me.retucio.camtweaks.module.settings.EnumSetting;
|
||||
import me.retucio.camtweaks.util.ChatUtil;
|
||||
import me.retucio.camtweaks.module.settings.ListSetting;
|
||||
import me.retucio.camtweaks.util.Lists;
|
||||
import net.minecraft.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.LazyEntityReference;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.damage.DamageSource;
|
||||
@@ -14,7 +16,6 @@ import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.projectile.PersistentProjectileEntity;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
@@ -29,30 +30,23 @@ import java.util.concurrent.Executors;
|
||||
/** continúa en:
|
||||
* @see me.retucio.camtweaks.mixin.EntityMixin
|
||||
* @see me.retucio.camtweaks.mixin.ItemEntityMixin
|
||||
* @see me.retucio.camtweaks.mixin.LivingEntityRendererMixin
|
||||
* @see me.retucio.camtweaks.mixin.PlayerEntityMixin
|
||||
*/
|
||||
|
||||
public class Nametags extends Module {
|
||||
|
||||
public BooleanSetting namePlayers = addSetting(new BooleanSetting("nombrar jugadores", "renderiza el nametag de jugadores", true));
|
||||
public ListSetting<EntityType<?>> entities = addSetting(new ListSetting<>("entidades", "entidades cuyo nametag será visible",
|
||||
Lists.entityList, Lists.allFalse(Lists.entityList), Lists.entityNames));
|
||||
|
||||
public BooleanSetting alwaysVisible = addSetting(new BooleanSetting("siempre mostrar nametags", "mostrar nametag cuando el jugador está agachado o es invisible", false));
|
||||
public BooleanSetting health = addSetting(new BooleanSetting("mostrar vida", "muestra la vida de una entidad en su nametag", true));
|
||||
public EnumSetting<HealthMode> healthMode = addSetting(new EnumSetting<>("mostrar vida en", "de qué manera mostrar la vida", HealthMode.class, HealthMode.POINTS));
|
||||
public BooleanSetting alwaysVisible = addSetting(new BooleanSetting("siempre mostrar nametags", "mostrar nametags cuando no deberían de ser visibles", false));
|
||||
|
||||
public BooleanSetting namePassiveMobs = addSetting(new BooleanSetting("nombrar mobs pasivos", "renderiza el nametag de mobs pasivos", false));
|
||||
public BooleanSetting nameHostileMobs = addSetting(new BooleanSetting("nombrar mobs hostiles", "renderiza el nametag de mobs hostiles", false));
|
||||
public BooleanSetting nameMiscMobs = addSetting(new BooleanSetting("nombrar mobs neutrales", "renderiza el nametag de mobs neutrales", false));
|
||||
public BooleanSetting distinguishBabies = addSetting(new BooleanSetting("distinguir bebés", "cambia el nametag cuando una entidad está en su fase bebé", false));
|
||||
|
||||
public BooleanSetting nameProjectiles = addSetting(new BooleanSetting("nombrar proyectiles", "renderiza el nametag de proyectiles", false));
|
||||
public BooleanSetting showProjectileDamage = addSetting(new BooleanSetting("daño del proyectil", "muestra cuánto daño hace un proyectil en su nametag", false));
|
||||
|
||||
public BooleanSetting nameItems = addSetting(new BooleanSetting("nombrar items", "renderiza el nametag de items", true));
|
||||
public BooleanSetting countItems = addSetting(new BooleanSetting("contar items", "muestra cuánto de un item hay en un stack dropeado", true));
|
||||
public BooleanSetting showProjectileDamage = addSetting(new BooleanSetting("daño del proyectil", "muestra cuánto daño hace un proyectil en su nametag", true));
|
||||
|
||||
public BooleanSetting nameVehicles = addSetting(new BooleanSetting("nombrar vehículos", "renderiza el nametag de botes, minecarts, ...", false));
|
||||
public BooleanSetting showPassengers = addSetting(new BooleanSetting("mostrar pasajeros", "muestra qué pasajeros tiene el vehículo", false));
|
||||
|
||||
public BooleanSetting distinguishBabies = addSetting(new BooleanSetting("distinguir bebés", "cambia el nametag cuando una entidad está en su fase bebé", false));
|
||||
public BooleanSetting petOwner = addSetting(new BooleanSetting("mostrar dueño", "muestra el dueño de una mascota (no funciona en servers no premium)", false));
|
||||
|
||||
private final Map<UUID, String> cache = new ConcurrentHashMap<>();
|
||||
@@ -61,46 +55,35 @@ public class Nametags extends Module {
|
||||
public Nametags() {
|
||||
super("nametags", "modifica la manera en la que se renderizan los nametags");
|
||||
|
||||
nameProjectiles.onUpdate(v -> showProjectileDamage.setVisible(v));
|
||||
nameItems.onUpdate(v -> countItems.setVisible(v));
|
||||
nameVehicles.onUpdate(v -> showPassengers.setVisible(v));
|
||||
|
||||
namePassiveMobs.onUpdate(v -> distinguishBabies.setVisible(v || nameMiscMobs.isEnabled() || nameHostileMobs.isEnabled()));
|
||||
nameMiscMobs.onUpdate(v -> distinguishBabies.setVisible(v || namePassiveMobs.isEnabled() || nameHostileMobs.isEnabled()));
|
||||
nameHostileMobs.onUpdate(v -> distinguishBabies.setVisible(v || nameMiscMobs.isEnabled() || namePassiveMobs.isEnabled()));
|
||||
// entidades activadas por defecto
|
||||
entities.setEnabled(EntityType.PLAYER, true);
|
||||
entities.setEnabled(EntityType.ITEM, true);
|
||||
entities.setEnabled(EntityType.ARROW, true);
|
||||
entities.setEnabled(EntityType.SPECTRAL_ARROW, true);
|
||||
entities.setEnabled(EntityType.TRIDENT, true);
|
||||
entities.setDefaultValues(entities.getValues());
|
||||
|
||||
health.onUpdate(v -> healthMode.setVisible(v));
|
||||
}
|
||||
|
||||
public enum HealthMode {
|
||||
POINTS("hp (puntos de vida)"),
|
||||
HEARTS("corazones");
|
||||
|
||||
private final String name;
|
||||
HealthMode(String name) { this.name = name; }
|
||||
@Override public String toString() { return name; }
|
||||
}
|
||||
|
||||
// literalmente cómo lo calcula Minecraft
|
||||
public float getArrowDamage(PersistentProjectileEntity arrow) {
|
||||
if (mc.player == null) return 0;
|
||||
public String getArrowDamage(PersistentProjectileEntity arrow) {
|
||||
if (mc.player == null) return "0";
|
||||
|
||||
double initialDamage = 2;
|
||||
double velocity = arrow.getVelocity().length();
|
||||
DamageSource damageSource = arrow.getDamageSources().arrow(arrow, arrow.getOwner());
|
||||
|
||||
if (arrow.getWeaponStack() != null)
|
||||
if (arrow.getWorld() instanceof ServerWorld world)
|
||||
initialDamage = EnchantmentHelper.getDamage(world, arrow.getWeaponStack(), mc.player, damageSource, (float) initialDamage);
|
||||
if (arrow.getWeaponStack() != null && arrow.getWorld() instanceof ServerWorld world)
|
||||
initialDamage = EnchantmentHelper.getDamage(world, arrow.getWeaponStack(), mc.player, damageSource, (float) initialDamage);
|
||||
|
||||
int finalDamage = MathHelper.ceil(MathHelper.clamp(velocity * initialDamage, 0, 2.147483647E9));
|
||||
|
||||
if (arrow.isCritical()) {
|
||||
long bonus = arrow.getRandom().nextInt(finalDamage / 2 + 2);
|
||||
finalDamage = (int) Math.min(bonus + (long) finalDamage, 2147483647L);
|
||||
}
|
||||
long bonus = 0;
|
||||
if (arrow.isCritical()) bonus = finalDamage / 2 - 1;
|
||||
|
||||
return healthMode.is(HealthMode.HEARTS) ? finalDamage / 2f : finalDamage;
|
||||
if (healthMode.is(HealthMode.HEARTS)) finalDamage /= 2;
|
||||
return finalDamage + (bonus > 0 ? " ~ " + (finalDamage + bonus) : "");
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@@ -141,4 +124,13 @@ public class Nametags extends Module {
|
||||
|
||||
return "...";
|
||||
}
|
||||
public enum HealthMode {
|
||||
POINTS("hp (puntos de vida)"),
|
||||
HEARTS("corazones");
|
||||
|
||||
private final String name;
|
||||
HealthMode(String name) { this.name = name; }
|
||||
@Override public String toString() { return name; }
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
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.ListSetting;
|
||||
import me.retucio.camtweaks.module.settings.NumberSetting;
|
||||
import me.retucio.camtweaks.util.Lists;
|
||||
import net.minecraft.particle.ParticleType;
|
||||
import net.minecraft.util.Formatting;
|
||||
|
||||
/** continúa en:
|
||||
* @see me.retucio.camtweaks.mixin.ClientPlayNetworkHandlerMixin
|
||||
* @see me.retucio.camtweaks.mixin.EntityEffectParticleEffectMixin
|
||||
* @see me.retucio.camtweaks.mixin.FogRendererMixin
|
||||
* @see me.retucio.camtweaks.mixin.GameRendererMixin
|
||||
* @see me.retucio.camtweaks.mixin.InGameHudMixin
|
||||
* @see me.retucio.camtweaks.mixin.InGameOverlayRendererMixin
|
||||
* @see me.retucio.camtweaks.mixin.ParticleManagerMixin
|
||||
* @see me.retucio.camtweaks.mixin.StuckArrowsFeatureRendererMixin
|
||||
* @see me.retucio.camtweaks.mixin.TextRendererDrawerMixin
|
||||
* @see me.retucio.camtweaks.mixin.WeatherRenderingMixin
|
||||
*/
|
||||
|
||||
public class NoRender extends Module {
|
||||
|
||||
public BooleanSetting spyglassOverlay = addSetting(new BooleanSetting("catalejo", "renderizar overlay del catalejo", false));
|
||||
public BooleanSetting fluidOverlay = addSetting(new BooleanSetting("fluídos", "renderizar fluídos sobre la cámara como el agua, lava o nieve en polvo (aunque no sea un fluído)", false));
|
||||
public BooleanSetting pumpkinOverlay = addSetting(new BooleanSetting("calabaza", "renderiza el overlay de la calabaza tallada", false));
|
||||
public BooleanSetting fireOverlay = addSetting(new BooleanSetting("fuego", "renderizar llamas sobre la cámara", false));
|
||||
public BooleanSetting portalOverlay = addSetting(new BooleanSetting("portal", "renderizar el overlay del portal del nether", false));
|
||||
|
||||
public BooleanSetting rain = addSetting(new BooleanSetting("lluvia", "l l u v i a", true));
|
||||
public BooleanSetting snow = addSetting(new BooleanSetting("nieve", "n i e v e", true));
|
||||
public BooleanSetting dimensionFog = addSetting(new BooleanSetting("niebla de dimensión", "n i e b l a", true));
|
||||
public BooleanSetting endFlashes; // para cuando actualice
|
||||
|
||||
public ListSetting<ParticleType<?>> particles = addSetting(new ListSetting<>("partículas", "lista de partículas que se renderizan",
|
||||
Lists.particleList, Lists.allTrue(Lists.particleList), Lists.particleNames));
|
||||
|
||||
public BooleanSetting nauseaEffect = addSetting(new BooleanSetting("náusea", "renderizar borrachera", false));
|
||||
public BooleanSetting blindnessEffect = addSetting(new BooleanSetting("ceguera", "renderizar miopía", false));
|
||||
public BooleanSetting darknessEffect = addSetting(new BooleanSetting("oscuridad", "renderizar miedo a la oscuridad", false));
|
||||
public BooleanSetting nightVisionEffect;
|
||||
public NumberSetting potionParticleAlpha = addSetting(new NumberSetting("opacidad de burbujas", "opacidad de las partículas de pociones",
|
||||
170, 0, 255, 1));
|
||||
|
||||
public BooleanSetting scoreboard = addSetting(new BooleanSetting("marcador", "mostrar marcador a la derecha", false));
|
||||
public BooleanSetting titles = addSetting(new BooleanSetting("títulos", "mostrar títulos (del comando /title)", false));
|
||||
public BooleanSetting totemPop = addSetting(new BooleanSetting("tótem", "renderizar el pop del tótem", true));
|
||||
|
||||
public BooleanSetting stuckArrows = addSetting(new BooleanSetting("flechas clavadas", "renderizar flechas clavadas en jugadores", false));
|
||||
|
||||
public BooleanSetting bold = addSetting(new BooleanSetting("negrita", "letra pero §lgorda", true));
|
||||
// public BooleanSetting italics = addSetting(new BooleanSetting("cursiva", "letra pero §otorcida", true));
|
||||
public BooleanSetting underlined = addSetting(new BooleanSetting("subrayado", "letra pero §nen el suelo", true));
|
||||
public BooleanSetting strikethrough = addSetting(new BooleanSetting("tachado", "letra pero §mdiscriminada", true));
|
||||
public EnumSetting<Colors> color = addSetting(new EnumSetting<>("colores", "§co§4r§6g§eu§al§2l§9o §1g§5a§dy", Colors.class, Colors.DEFAULT));
|
||||
public BooleanSetting scrambledText = addSetting(new BooleanSetting("garabato", "engarabatar texto (o como se diga) (§kasí§r)", false));
|
||||
|
||||
public NoRender() {
|
||||
super("no render", "customiza qué se renderiza y qué no");
|
||||
}
|
||||
|
||||
public enum Colors {
|
||||
BLACK("negro"),
|
||||
DARK_BLUE("azul oscuro"),
|
||||
DARK_GREEN("verde"),
|
||||
DARK_AQUA("cian"),
|
||||
DARK_RED("granate"),
|
||||
DARK_PURPLE("morado"),
|
||||
GOLD("naranja"),
|
||||
GRAY("gris claro"),
|
||||
DARK_GRAY("gris oscuro"),
|
||||
BLUE("azul"),
|
||||
GREEN("lima"),
|
||||
AQUA("turquesa"),
|
||||
RED("rojo"),
|
||||
LIGHT_PURPLE("lila"),
|
||||
YELLOW("amarillo"),
|
||||
WHITE("blanco"),
|
||||
DEFAULT("por defecto");
|
||||
|
||||
private final String name;
|
||||
Colors(String name) { this.name = name; }
|
||||
@Override public String toString() { return name; }
|
||||
public Formatting toFormatting() { return (Formatting.byColorIndex(this.ordinal())); }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,218 @@
|
||||
package me.retucio.camtweaks.module.modules;
|
||||
|
||||
import me.retucio.camtweaks.command.CommandManager;
|
||||
import me.retucio.camtweaks.event.events.ClientClickEvent;
|
||||
import me.retucio.camtweaks.module.Module;
|
||||
import me.retucio.camtweaks.module.settings.BooleanSetting;
|
||||
import me.retucio.camtweaks.module.settings.EnumSetting;
|
||||
import me.retucio.camtweaks.util.ChatUtil;
|
||||
import net.minecraft.client.texture.NativeImage;
|
||||
import net.minecraft.text.ClickEvent;
|
||||
import net.minecraft.text.HoverEvent;
|
||||
import net.minecraft.text.MutableText;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Formatting;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.datatransfer.DataFlavor;
|
||||
import java.awt.datatransfer.Transferable;
|
||||
import java.awt.datatransfer.UnsupportedFlavorException;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
|
||||
/** continúa en:
|
||||
* @see me.retucio.camtweaks.mixin.ScreenshotRecorderMixin
|
||||
*/
|
||||
|
||||
public class ScreenshotPlus extends Module {
|
||||
|
||||
public BooleanSetting saveButton = addSetting(new BooleanSetting("botón de guardar", "mostrar botón para guardar la captura localmente", true));
|
||||
public BooleanSetting copyButton = addSetting(new BooleanSetting("botón de copiar", "mostrar botón para copiar la captura al portapapeles", true));
|
||||
public BooleanSetting openButton = addSetting(new BooleanSetting("botón de abrir", "mostrar botón para abrir el archivo de la captura", true));
|
||||
public BooleanSetting discardButton = addSetting(new BooleanSetting("botón de descartar", "mostrar botón para descartar la captura", true));
|
||||
|
||||
public EnumSetting<ScreenshotActions> defaultAction = addSetting(new EnumSetting<>("por defecto", "qué acción tomar por defecto",
|
||||
ScreenshotActions.class, ScreenshotActions.NONE));
|
||||
|
||||
private NativeImage screenshot;
|
||||
private File screenshotFile;
|
||||
|
||||
public ScreenshotPlus() {
|
||||
super("capturas de pantalla", "elige qué hacer tras tomar una captura de pantalla");
|
||||
}
|
||||
|
||||
public void sendScreenshotMessage() {
|
||||
MutableText baseText = Text.literal("captura de pantalla tomada\n");
|
||||
if (saveButton.isEnabled() && !defaultAction.is(ScreenshotActions.SAVE)) baseText.append(getSaveButton().append(" "));
|
||||
if (copyButton.isEnabled()) baseText.append(getCopyButton().append(" "));
|
||||
if (openButton.isEnabled() && defaultAction.is(ScreenshotActions.SAVE)) baseText.append(getOpenButton().append(" "));
|
||||
if (discardButton.isEnabled() && !defaultAction.is(ScreenshotActions.NONE)) baseText.append(getDiscardButton().append(" "));
|
||||
ChatUtil.info(baseText);
|
||||
}
|
||||
|
||||
|
||||
// acciones con la captura
|
||||
|
||||
public void copyScreenshot(NativeImage nativeImage) {
|
||||
try {
|
||||
BufferedImage bufferedImage = new BufferedImage(nativeImage.getWidth(), nativeImage.getHeight(), BufferedImage.TYPE_INT_ARGB);
|
||||
for (int x = 0; x < nativeImage.getWidth(); x++)
|
||||
for (int y = 0; y < nativeImage.getHeight(); y++)
|
||||
bufferedImage.setRGB(x, y, nativeImage.getColorArgb(x, y));
|
||||
|
||||
ScreenshotPlus.TransferableImage trans = new TransferableImage(bufferedImage);
|
||||
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(trans, null);
|
||||
ChatUtil.info("captura copiada al portapapeles");
|
||||
} catch (Exception e) {
|
||||
ChatUtil.error("no se pudo copiar la captura al portapapeles");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void copyScreenshot() {
|
||||
copyScreenshot(this.screenshot);
|
||||
}
|
||||
|
||||
public void saveScreenshot(NativeImage image) throws IOException {
|
||||
image.writeTo(screenshotFile);
|
||||
ChatUtil.info(Text.literal("captura guardada como: ").append(
|
||||
Text.literal(screenshotFile.getName())
|
||||
.formatted(Formatting.UNDERLINE)
|
||||
.styled(style -> style.withClickEvent(new ClickEvent.OpenFile(screenshotFile.getAbsoluteFile())))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public void saveScreenshot() throws IOException {
|
||||
saveScreenshot(this.screenshot);
|
||||
}
|
||||
|
||||
// clase ayudante para el portapapeles
|
||||
public static class TransferableImage implements Transferable {
|
||||
private final Image image;
|
||||
|
||||
public TransferableImage(Image image) {
|
||||
this.image = image;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataFlavor[] getTransferDataFlavors() {
|
||||
return new DataFlavor[]{DataFlavor.imageFlavor};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDataFlavorSupported(DataFlavor flavor) {
|
||||
return DataFlavor.imageFlavor.equals(flavor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException {
|
||||
if (!DataFlavor.imageFlavor.equals(flavor))
|
||||
throw new UnsupportedFlavorException(flavor);
|
||||
|
||||
return image;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// botones para el mensaje
|
||||
|
||||
@SuppressWarnings("DataFlowIssue")
|
||||
private MutableText getSaveButton() {
|
||||
MutableText button = Text.literal("[GUARDAR]");
|
||||
MutableText hintBaseText = Text.literal("");
|
||||
|
||||
MutableText hintMsg = Text.literal(ScreenshotActions.SAVE.toString());
|
||||
hintMsg.setStyle(hintBaseText.getStyle().withFormatting(Formatting.GRAY));
|
||||
hintBaseText.append(hintMsg);
|
||||
|
||||
button.setStyle(button.getStyle()
|
||||
.withFormatting(Formatting.BOLD, Formatting.GOLD)
|
||||
.withClickEvent(new ClientClickEvent(CommandManager.getCommandByName("guardarcaptura").toString()))
|
||||
.withHoverEvent(new HoverEvent.ShowText(hintBaseText)));
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
@SuppressWarnings("DataFlowIssue")
|
||||
private MutableText getCopyButton() {
|
||||
MutableText button = Text.literal("[COPIAR]");
|
||||
MutableText hintBaseText = Text.literal("");
|
||||
|
||||
MutableText hintMsg = Text.literal(ScreenshotActions.COPY.toString());
|
||||
hintMsg.setStyle(hintBaseText.getStyle().withFormatting(Formatting.GRAY));
|
||||
hintBaseText.append(hintMsg);
|
||||
|
||||
button.setStyle(button.getStyle()
|
||||
.withFormatting(Formatting.BOLD, Formatting.AQUA)
|
||||
.withClickEvent(new ClientClickEvent(CommandManager.getCommandByName("copiarcaptura").toString()))
|
||||
.withHoverEvent(new HoverEvent.ShowText(hintBaseText)));
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
private MutableText getOpenButton() {
|
||||
MutableText button = Text.literal("[ABRIR]");
|
||||
MutableText hintBaseText = Text.literal("");
|
||||
|
||||
MutableText hintMsg = Text.literal("abrir archivo de imagen");
|
||||
hintMsg.setStyle(hintBaseText.getStyle().withFormatting(Formatting.GRAY));
|
||||
hintBaseText.append(hintMsg);
|
||||
|
||||
button.setStyle(button.getStyle()
|
||||
.withFormatting(Formatting.BOLD, Formatting.GRAY)
|
||||
.withClickEvent(new ClickEvent.OpenFile(screenshotFile))
|
||||
.withHoverEvent(new HoverEvent.ShowText(hintBaseText)));
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
@SuppressWarnings("DataFlowIssue")
|
||||
private MutableText getDiscardButton() {
|
||||
MutableText button = Text.literal("[DESCARTAR]");
|
||||
MutableText hintBaseText = Text.literal("");
|
||||
|
||||
MutableText hintMsg = Text.literal(ScreenshotActions.NONE.toString());
|
||||
hintMsg.setStyle(hintBaseText.getStyle().withFormatting(Formatting.GRAY));
|
||||
hintBaseText.append(hintMsg);
|
||||
|
||||
button.setStyle(button.getStyle()
|
||||
.withFormatting(Formatting.BOLD, Formatting.DARK_RED)
|
||||
.withClickEvent(new ClientClickEvent(CommandManager.getCommandByName("purgar").toString("1")))
|
||||
.withHoverEvent(new HoverEvent.ShowText(hintBaseText)));
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
|
||||
// otros
|
||||
|
||||
public enum ScreenshotActions {
|
||||
SAVE("guardar archivo"),
|
||||
COPY("copiar al portapapeles"),
|
||||
NONE("no hacer nada");
|
||||
|
||||
private final String name;
|
||||
ScreenshotActions(String name) { this.name = name; }
|
||||
@Override public String toString() { return name; }
|
||||
}
|
||||
|
||||
public NativeImage getScreenshot() {
|
||||
return screenshot;
|
||||
}
|
||||
|
||||
public void setScreenshot(NativeImage screenshot) {
|
||||
this.screenshot = screenshot;
|
||||
}
|
||||
|
||||
public File getScreenshotFile() {
|
||||
return screenshotFile;
|
||||
}
|
||||
|
||||
public void setScreenshotFile(File screenshotFile) {
|
||||
this.screenshotFile = screenshotFile;
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,21 @@
|
||||
package me.retucio.camtweaks.module.settings;
|
||||
|
||||
import me.retucio.camtweaks.CameraTweaks;
|
||||
import me.retucio.camtweaks.event.events.camtweaks.UpdateSettingEvent;
|
||||
import me.retucio.camtweaks.module.Module;
|
||||
|
||||
// base para los tipos de ajustes
|
||||
public class Setting {
|
||||
public abstract class AbstractSetting {
|
||||
|
||||
private final String name;
|
||||
private final String description;
|
||||
|
||||
private boolean visible = true;
|
||||
private boolean searchMatch = true;
|
||||
|
||||
private Module module;
|
||||
|
||||
protected Setting(String name, String description) {
|
||||
protected AbstractSetting(String name, String description) {
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
}
|
||||
@@ -24,6 +28,14 @@ public class Setting {
|
||||
this.visible = visible;
|
||||
}
|
||||
|
||||
public boolean isSearchMatch() {
|
||||
return searchMatch;
|
||||
}
|
||||
|
||||
public void setSearchMatch(boolean searchMatch) {
|
||||
this.searchMatch = searchMatch;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
@@ -39,4 +51,8 @@ public class Setting {
|
||||
public void setModule(Module module) {
|
||||
this.module = module;
|
||||
}
|
||||
|
||||
public void fireUpdateEvent() {
|
||||
CameraTweaks.EVENT_BUS.post(new UpdateSettingEvent(this, module.shouldSaveSettings()));
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ import me.retucio.camtweaks.event.events.camtweaks.UpdateSettingEvent;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
// ajuste booleano, es decir, o se encuentra encencido o apagado (similar a un interruptor)
|
||||
public class BooleanSetting extends Setting {
|
||||
public class BooleanSetting extends AbstractSetting {
|
||||
|
||||
private boolean defaultValue;
|
||||
private boolean enabled;
|
||||
@@ -31,7 +31,7 @@ public class BooleanSetting extends Setting {
|
||||
public void setEnabled(boolean enabled) {
|
||||
if (this.enabled != enabled) {
|
||||
this.enabled = enabled;
|
||||
CameraTweaks.EVENT_BUS.post(new UpdateSettingEvent(this));
|
||||
fireUpdateEvent();
|
||||
if (updateListener != null) updateListener.accept(enabled);
|
||||
}
|
||||
}
|
||||
@@ -50,5 +50,6 @@ public class BooleanSetting extends Setting {
|
||||
|
||||
public void onUpdate(Consumer<Boolean> listener) {
|
||||
this.updateListener = listener;
|
||||
if (updateListener != null) updateListener.accept(enabled); // actualizar por primera vez
|
||||
}
|
||||
}
|
||||
@@ -8,9 +8,8 @@ import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
// ajuste que te deja elegir entre distintas opciones definidas, dentro de un Enum
|
||||
public class EnumSetting<E extends Enum<E>> extends Setting {
|
||||
public class EnumSetting<E extends Enum<E>> extends AbstractSetting {
|
||||
|
||||
private final Class<E> enumClass;
|
||||
private final List<E> values;
|
||||
private E defaultValue;
|
||||
|
||||
@@ -21,7 +20,6 @@ public class EnumSetting<E extends Enum<E>> extends Setting {
|
||||
|
||||
public EnumSetting(String name, String description, Class<E> enumClass, E defaultValue) {
|
||||
super(name, description);
|
||||
this.enumClass = enumClass;
|
||||
this.values = Arrays.asList(enumClass.getEnumConstants());
|
||||
this.defaultValue = defaultValue;
|
||||
this.value = defaultValue;
|
||||
@@ -36,7 +34,7 @@ public class EnumSetting<E extends Enum<E>> extends Setting {
|
||||
if (this.value != value) {
|
||||
this.value = value;
|
||||
this.index = values.indexOf(value);
|
||||
CameraTweaks.EVENT_BUS.post(new UpdateSettingEvent(this));
|
||||
fireUpdateEvent();
|
||||
if (updateListener != null) updateListener.accept(value);
|
||||
}
|
||||
}
|
||||
@@ -87,5 +85,6 @@ public class EnumSetting<E extends Enum<E>> extends Setting {
|
||||
|
||||
public void onUpdate(Consumer<E> listener) {
|
||||
this.updateListener = listener;
|
||||
if (updateListener != null) updateListener.accept(value);
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,15 @@
|
||||
package me.retucio.camtweaks.module.settings;
|
||||
|
||||
import me.retucio.camtweaks.CameraTweaks;
|
||||
import me.retucio.camtweaks.event.events.camtweaks.UpdateSettingEvent;
|
||||
import me.retucio.camtweaks.module.Module;
|
||||
import me.retucio.camtweaks.module.ModuleManager;
|
||||
import me.retucio.camtweaks.ui.frames.ClickGUISettingsFrame;
|
||||
import me.retucio.camtweaks.ui.frames.ClientSettingsFrame;
|
||||
import me.retucio.camtweaks.util.ChatUtil;
|
||||
import me.retucio.camtweaks.util.KeyUtil;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class KeySetting extends Setting {
|
||||
public class KeySetting extends AbstractSetting {
|
||||
|
||||
private int key;
|
||||
private int defaultKey;
|
||||
@@ -33,21 +31,21 @@ public class KeySetting extends Setting {
|
||||
|
||||
if (key == GLFW.GLFW_KEY_ESCAPE) {
|
||||
this.key = GLFW.GLFW_KEY_UNKNOWN; // asignar la tecla ESC a deshabilitar la tecla
|
||||
CameraTweaks.EVENT_BUS.post(new UpdateSettingEvent(this));
|
||||
fireUpdateEvent();
|
||||
if (updateListener != null) updateListener.accept(key);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ModuleManager.INSTANCE != null) {
|
||||
for (Module module : ModuleManager.INSTANCE.getModules())
|
||||
if (module.getKey() == key && !ClickGUISettingsFrame.guiSettings.multipleKeybinds.isEnabled() && key != -1) {
|
||||
if (module.getKey() == key && !ClientSettingsFrame.guiSettings.multipleKeybinds.isEnabled() && key != -1) {
|
||||
module.setKey(-1);
|
||||
ChatUtil.info("tecla del módulo " + module.getName() + " restablecida");
|
||||
}
|
||||
}
|
||||
this.key = key;
|
||||
|
||||
CameraTweaks.EVENT_BUS.post(new UpdateSettingEvent(this));
|
||||
fireUpdateEvent();
|
||||
if (updateListener != null) updateListener.accept(key);
|
||||
}
|
||||
|
||||
@@ -69,5 +67,6 @@ public class KeySetting extends Setting {
|
||||
|
||||
public void onUpdate(Consumer<Integer> listener) {
|
||||
this.updateListener = listener;
|
||||
if (updateListener != null) updateListener.accept(key);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
package me.retucio.camtweaks.module.settings;
|
||||
|
||||
import me.retucio.camtweaks.CameraTweaks;
|
||||
import me.retucio.camtweaks.event.events.camtweaks.UpdateSettingEvent;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class ListSetting<T> extends AbstractSetting {
|
||||
|
||||
private final List<T> options;
|
||||
private Map<T, Boolean> values;
|
||||
private Map<T, Boolean> defaultValues;
|
||||
private Map<T, String> displayNames = null;
|
||||
|
||||
private Consumer<Map<T, Boolean>> updateListener;
|
||||
|
||||
public ListSetting(String name, String description, List<T> options, Map<T, Boolean> initialValues) {
|
||||
super(name, description);
|
||||
this.options = options;
|
||||
this.defaultValues = new HashMap<>();
|
||||
|
||||
for (T option : options) {
|
||||
boolean enabled = initialValues != null && initialValues.getOrDefault(option, false);
|
||||
defaultValues.put(option, enabled);
|
||||
}
|
||||
this.values = new HashMap<>(defaultValues);
|
||||
}
|
||||
|
||||
public ListSetting(String name, String description, List<T> options, Map<T, Boolean> initialValues, Map<T, String> displayNames) {
|
||||
this(name, description, options, initialValues);
|
||||
this.displayNames = displayNames;
|
||||
}
|
||||
|
||||
public boolean isEnabled(T option) {
|
||||
return values.getOrDefault(option, false);
|
||||
}
|
||||
|
||||
public void setEnabled(T option, boolean enabled) {
|
||||
if (values.containsKey(option) && values.get(option) != enabled) {
|
||||
values.put(option, enabled);
|
||||
fireUpdateEvent();
|
||||
if (updateListener != null) updateListener.accept(new HashMap<>(values));
|
||||
}
|
||||
}
|
||||
|
||||
public void toggle(T option) {
|
||||
setEnabled(option, !isEnabled(option));
|
||||
}
|
||||
|
||||
public Map<T, Boolean> getValues() {
|
||||
return new HashMap<>(values);
|
||||
}
|
||||
|
||||
public void setValues(Map<T, Boolean> values) {
|
||||
this.values = new HashMap<>(values);
|
||||
}
|
||||
|
||||
public Map<T, Boolean> getDefaultValues() {
|
||||
return new HashMap<>(defaultValues);
|
||||
}
|
||||
|
||||
public void setDefaultValues(Map<T, Boolean> values) {
|
||||
defaultValues = values;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
values.clear();
|
||||
values.putAll(defaultValues);
|
||||
fireUpdateEvent();
|
||||
if (updateListener != null) updateListener.accept(new HashMap<>(values));
|
||||
}
|
||||
|
||||
public void setAll(boolean enabled) {
|
||||
for (T option : options) values.put(option, enabled);
|
||||
}
|
||||
|
||||
public void onUpdate(Consumer<Map<T, Boolean>> listener) {
|
||||
this.updateListener = listener;
|
||||
if (updateListener != null) updateListener.accept(new HashMap<>(values));
|
||||
}
|
||||
|
||||
public List<T> getOptions() {
|
||||
return options;
|
||||
}
|
||||
|
||||
public Map<T, String> getDisplayNames() {
|
||||
return displayNames;
|
||||
}
|
||||
|
||||
public String getDisplayName(T key) {
|
||||
if (displayNames != null) return displayNames.get(key);
|
||||
return key.toString();
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ import me.retucio.camtweaks.event.events.camtweaks.UpdateSettingEvent;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
// ajuste numérico, es decir, que eliges un valor númerico entre el mínimo y el máximo disponibles
|
||||
public class NumberSetting extends Setting {
|
||||
public class NumberSetting extends AbstractSetting {
|
||||
|
||||
private double value;
|
||||
private double defaultValue;
|
||||
@@ -60,7 +60,7 @@ public class NumberSetting extends Setting {
|
||||
if (this.value == value) return;
|
||||
double clamped = clamp(value, min, max);
|
||||
this.value = Math.round(clamped / increment) * increment;
|
||||
CameraTweaks.EVENT_BUS.post(new UpdateSettingEvent(this));
|
||||
fireUpdateEvent();
|
||||
if (updateListener != null) updateListener.accept(this.value);
|
||||
}
|
||||
|
||||
@@ -90,6 +90,6 @@ public class NumberSetting extends Setting {
|
||||
|
||||
public void onUpdate(Consumer<Double> listener) {
|
||||
this.updateListener = listener;
|
||||
CameraTweaks.EVENT_BUS.post(new UpdateSettingEvent(this));
|
||||
if (updateListener != null) updateListener.accept(value);
|
||||
}
|
||||
}
|
||||
@@ -3,10 +3,9 @@ package me.retucio.camtweaks.module.settings;
|
||||
import me.retucio.camtweaks.CameraTweaks;
|
||||
import me.retucio.camtweaks.event.events.camtweaks.UpdateSettingEvent;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class StringSetting extends Setting {
|
||||
public class StringSetting extends AbstractSetting {
|
||||
|
||||
private String value;
|
||||
private String defaultValue;
|
||||
@@ -28,7 +27,7 @@ public class StringSetting extends Setting {
|
||||
public void setValue(String value) {
|
||||
if (this.value.equals(value)) return;
|
||||
this.value = value.length() > maxLength ? value.substring(0, maxLength) : value;
|
||||
CameraTweaks.EVENT_BUS.post(new UpdateSettingEvent(this));
|
||||
fireUpdateEvent();
|
||||
if (updateListener != null) updateListener.accept(this.value);
|
||||
}
|
||||
|
||||
@@ -50,6 +49,6 @@ public class StringSetting extends Setting {
|
||||
|
||||
public void onUpdate(Consumer<String> listener) {
|
||||
this.updateListener = listener;
|
||||
CameraTweaks.EVENT_BUS.post(new UpdateSettingEvent(this));
|
||||
if (updateListener != null) updateListener.accept(value);
|
||||
}
|
||||
}
|
||||
@@ -2,30 +2,47 @@ package me.retucio.camtweaks.ui;
|
||||
|
||||
import me.retucio.camtweaks.CameraTweaks;
|
||||
import me.retucio.camtweaks.event.SubscribeEvent;
|
||||
import me.retucio.camtweaks.event.events.KeyEvent;
|
||||
import me.retucio.camtweaks.event.events.MouseClickEvent;
|
||||
import me.retucio.camtweaks.event.events.MouseScrollEvent;
|
||||
import me.retucio.camtweaks.event.events.camtweaks.SettingsFrameEvent;
|
||||
import me.retucio.camtweaks.module.Module;
|
||||
import me.retucio.camtweaks.ui.frames.ClickGUISettingsFrame;
|
||||
import me.retucio.camtweaks.module.settings.AbstractSetting;
|
||||
import me.retucio.camtweaks.ui.buttons.ListButton;
|
||||
import me.retucio.camtweaks.ui.buttons.SettingButton;
|
||||
import me.retucio.camtweaks.ui.frames.ClientSettingsFrame;
|
||||
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.DrawContext;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.text.Text;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static me.retucio.camtweaks.ui.frames.ClickGUISettingsFrame.guiSettings;
|
||||
import static me.retucio.camtweaks.ui.frames.ClientSettingsFrame.guiSettings;
|
||||
|
||||
// interfaz gráfica, se abre con el shift derecho por defecto. aquí se encuentran los módulos y sus ajustes
|
||||
public class ClickGUI extends Screen {
|
||||
|
||||
public static ClickGUI INSTANCE;
|
||||
private boolean anyFocused;
|
||||
private Object selected = null;
|
||||
|
||||
private final ModuleFrame modulesFrame = new ModuleFrame(20, 30, 100, 20);
|
||||
private final List<SettingsFrame> settingsFrames = new ArrayList<>();
|
||||
private final ClickGUISettingsFrame guiSettingsFrame = new ClickGUISettingsFrame(200, 30, 100, 20);
|
||||
private final ClientSettingsFrame guiSettingsFrame = new ClientSettingsFrame(200, 30, 100, 20);
|
||||
|
||||
private final ScrollBarWidget scrollBar = new ScrollBarWidget();
|
||||
private final SearchBarWidget searchBar = new SearchBarWidget(340, 16, 300, 20);
|
||||
|
||||
private final MinecraftClient mc = MinecraftClient.getInstance();
|
||||
|
||||
public ClickGUI() {
|
||||
super(Text.of("interfaz"));
|
||||
@@ -35,6 +52,21 @@ public class ClickGUI extends Screen {
|
||||
|
||||
@Override
|
||||
public void render(DrawContext ctx, int mouseX, int mouseY, float delta) {
|
||||
scrollBar.setWindowHeight(mc.getWindow().getScaledHeight());
|
||||
scrollBar.setContentHeight(calculateContentHeight());
|
||||
scrollBar.render(ctx, mouseX, mouseY);
|
||||
|
||||
int scrollOffset = scrollBar.getScrollOffset();
|
||||
|
||||
searchBar.updateRenderY(scrollOffset);
|
||||
searchBar.render(ctx, mouseX, mouseY, delta);
|
||||
searchBar.updatePosition(mouseX, mouseY);
|
||||
|
||||
// actualizar la posición de renderizado vertical de los marcos cada tick
|
||||
modulesFrame.updateRenderY(scrollOffset);
|
||||
for (SettingsFrame sf : settingsFrames)
|
||||
sf.updateRenderY(scrollOffset);
|
||||
|
||||
// renderizar el marco de los ajustes de cada módulo que lo tenga abierto. se abre haciendo clic derecho sobre el módulo
|
||||
for (SettingsFrame sf : settingsFrames.reversed()) {
|
||||
sf.render(ctx, mouseX, mouseY, delta);
|
||||
@@ -45,11 +77,27 @@ public class ClickGUI extends Screen {
|
||||
modulesFrame.render(ctx, mouseX, mouseY, delta);
|
||||
modulesFrame.updatePosition(mouseX, mouseY);
|
||||
|
||||
for (SettingsFrame sf : settingsFrames)
|
||||
sf.drawTooltips(ctx, mouseX, mouseY);
|
||||
|
||||
filterSearchResults();
|
||||
|
||||
super.render(ctx, mouseX, mouseY, delta);
|
||||
}
|
||||
|
||||
private int calculateContentHeight() {
|
||||
int bottom = modulesFrame.y + modulesFrame.h + modulesFrame.totalHeight;
|
||||
for (SettingsFrame frame : settingsFrames)
|
||||
bottom = Math.max(bottom, frame.y + frame.h + frame.totalHeight);
|
||||
|
||||
return bottom + 20; // padding
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseClicked(double mouseX, double mouseY, int button) {
|
||||
scrollBar.mouseClicked(mouseX, mouseY, button);
|
||||
searchBar.mouseClicked(mouseX, mouseY, button);
|
||||
|
||||
// detectar clics sobre los marcos
|
||||
modulesFrame.mouseClicked(mouseX, mouseY, button);
|
||||
for (SettingsFrame sf : new ArrayList<>(settingsFrames))
|
||||
@@ -60,6 +108,9 @@ public class ClickGUI extends Screen {
|
||||
|
||||
@Override
|
||||
public boolean mouseReleased(double mouseX, double mouseY, int button) {
|
||||
scrollBar.mouseReleased(mouseX, mouseY, button);
|
||||
searchBar.mouseReleased(mouseX, mouseY, button);
|
||||
|
||||
// registrar cuándo se suelta el clic, en cada marco respectivamente
|
||||
modulesFrame.mouseReleased(mouseX, mouseY, button);
|
||||
for (SettingsFrame sf : new ArrayList<>(settingsFrames))
|
||||
@@ -67,14 +118,64 @@ public class ClickGUI extends Screen {
|
||||
return super.mouseReleased(mouseX, mouseY, button);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) {
|
||||
scrollBar.mouseDragged(mouseY);
|
||||
return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onKey(KeyEvent event) {
|
||||
searchBar.onKey(event.getKey(), event.getAction());
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onMouseScroll(MouseScrollEvent event) {
|
||||
// subir y bajar la pantalla con la rueda del ratón
|
||||
if (CameraTweaks.mc.currentScreen != this) return;
|
||||
scrollBar.onMouseScroll(event.getVertical() * guiSettings.scrollSens.getValue());
|
||||
}
|
||||
|
||||
modulesFrame.y += (int) (event.getVertical() * guiSettings.scrollSens.getValue());
|
||||
for (SettingsFrame sf : settingsFrames)
|
||||
sf.y += (int) (event.getVertical() * guiSettings.scrollSens.getValue());
|
||||
@SubscribeEvent
|
||||
public void onMouseMiddleButton(MouseClickEvent event) {
|
||||
// mover todos los marcos a un punto visible al presionar shift + la rueda del ratón
|
||||
if (CameraTweaks.mc.currentScreen != this || event.getButton() != 2 || !KeyUtil.isKeyDown(GLFW.GLFW_KEY_LEFT_SHIFT)) return;
|
||||
|
||||
int h = CameraTweaks.mc.getWindow().getScaledHeight();
|
||||
int minY = Math.min(modulesFrame.y, settingsFrames.stream().mapToInt(sf -> sf.y).min().orElse(modulesFrame.y));
|
||||
int maxY = Math.max(modulesFrame.y + modulesFrame.h, settingsFrames.stream().mapToInt(sf -> sf.y + sf.h).max().orElse(modulesFrame.y + modulesFrame.h));
|
||||
int correction = minY < 0 ? -minY + 4 : (maxY > h ? h - maxY - 4 : 0);
|
||||
|
||||
if (correction != 0) {
|
||||
modulesFrame.y += correction;
|
||||
settingsFrames.forEach(sf -> sf.y += correction);
|
||||
}
|
||||
}
|
||||
|
||||
public void filterSearchResults() {
|
||||
if (!guiSettings.searchBar.isEnabled()) return;
|
||||
String searchInput = searchBar.getSearchInput().trim();
|
||||
if (!guiSettings.matchCase.isEnabled()) searchInput = searchInput.toLowerCase();
|
||||
|
||||
for (SettingsFrame sf : settingsFrames) {
|
||||
for (SettingButton sb : sf.getButtons()) {
|
||||
AbstractSetting setting = sb.getSetting();
|
||||
|
||||
if (searchInput.isEmpty()) {
|
||||
setting.setSearchMatch(true);
|
||||
continue;
|
||||
}
|
||||
|
||||
String name = setting.getName();
|
||||
String description = setting.getDescription();
|
||||
|
||||
if (!guiSettings.matchCase.isEnabled()) {
|
||||
name = name.toLowerCase();
|
||||
description = description.toLowerCase();
|
||||
}
|
||||
|
||||
setting.setSearchMatch(name.contains(searchInput) || description.contains(searchInput));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void openSettingsFrame(Module module, int x, int y) {
|
||||
@@ -85,6 +186,12 @@ public class ClickGUI extends Screen {
|
||||
CameraTweaks.EVENT_BUS.post(new SettingsFrameEvent.Open(frame));
|
||||
}
|
||||
|
||||
public void openListSettingsFrame(Module module, int x, int y) {
|
||||
if (isSettingsFrameOpen(module)) return;
|
||||
SettingsFrame frame = new SettingsFrame(module, x, y, 120, 18);
|
||||
settingsFrames.add(frame);
|
||||
}
|
||||
|
||||
// cerrar el marco de ajustes
|
||||
public void closeSettingsFrame(Module module) {
|
||||
// porque java.util.ConcurrentModificationException o algo no sé es lo único que se me ha ocurrido hacer
|
||||
@@ -93,6 +200,7 @@ public class ClickGUI extends Screen {
|
||||
if (sf.module == module) {
|
||||
CameraTweaks.EVENT_BUS.post(new SettingsFrameEvent.Close(sf));
|
||||
toRemove.add(sf);
|
||||
unselect(sf);
|
||||
}
|
||||
}
|
||||
settingsFrames.removeAll(toRemove);
|
||||
@@ -104,30 +212,92 @@ public class ClickGUI extends Screen {
|
||||
.anyMatch(sf -> sf.module.getName().equals(module.getName()));
|
||||
}
|
||||
|
||||
// no pausar el juego cuando se abre la interfaz
|
||||
|
||||
|
||||
public void refreshListButtons() {
|
||||
for (SettingsFrame frame : settingsFrames)
|
||||
for (SettingButton button : frame.getButtons())
|
||||
if (button instanceof ListButton<?> lb)
|
||||
lb.refreshDummy();
|
||||
}
|
||||
|
||||
|
||||
// métodos del súper
|
||||
|
||||
@Override
|
||||
public void close() { // evitar que al reabrir la interfaz sin previamente haber soltado el clic, se sigan arrastrando objetos
|
||||
modulesFrame.mouseReleased(0, 0, 0);
|
||||
settingsFrames.forEach(sf -> sf.mouseRelease(0, 0, 0));
|
||||
scrollBar.mouseReleased(0, 0, 0);
|
||||
searchBar.mouseReleased(0, 0, 0);
|
||||
|
||||
unselect(selected);
|
||||
super.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldPause() {
|
||||
// no pausar el juego cuando se abre la interfaz
|
||||
return false;
|
||||
}
|
||||
|
||||
public ModuleFrame getModulesFrame() {
|
||||
return modulesFrame;
|
||||
}
|
||||
|
||||
public ClickGUISettingsFrame getGuiSettingsFrame() {
|
||||
return guiSettingsFrame;
|
||||
}
|
||||
|
||||
public void setAnyFocused(boolean anyFocused) {
|
||||
this.anyFocused = anyFocused;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldCloseOnEsc() {
|
||||
return super.shouldCloseOnEsc() && !anyFocused;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void applyBlur(DrawContext context) {
|
||||
if (guiSettings.blur.isEnabled()) super.applyBlur(context);
|
||||
}
|
||||
|
||||
|
||||
// getters y setters de widgets
|
||||
|
||||
public ModuleFrame getModulesFrame() {
|
||||
return modulesFrame;
|
||||
}
|
||||
|
||||
public ClientSettingsFrame getGuiSettingsFrame() {
|
||||
return guiSettingsFrame;
|
||||
}
|
||||
|
||||
public List<SettingsFrame> getSettingsFrames() {
|
||||
return settingsFrames;
|
||||
}
|
||||
|
||||
public SearchBarWidget getSearchBar() {
|
||||
return searchBar;
|
||||
}
|
||||
|
||||
public void setAnyFocused(boolean anyFocused) {
|
||||
this.anyFocused = anyFocused;
|
||||
}
|
||||
|
||||
|
||||
// selección de widgets
|
||||
|
||||
public Object getSelected() {
|
||||
return selected;
|
||||
}
|
||||
|
||||
public void setSelected(Object object) {
|
||||
this.selected = object;
|
||||
}
|
||||
|
||||
public boolean canSelect(Object object) {
|
||||
return getSelected() == null || getSelected() == object;
|
||||
}
|
||||
|
||||
public boolean trySelect(Object object) {
|
||||
if (canSelect(object)) {
|
||||
setSelected(object);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void unselect(Object object) {
|
||||
if (selected == object) setSelected(null);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package me.retucio.camtweaks.ui.buttons;
|
||||
|
||||
import me.retucio.camtweaks.module.settings.KeySetting;
|
||||
import me.retucio.camtweaks.ui.ClickGUI;
|
||||
import me.retucio.camtweaks.ui.frames.SettingsFrame;
|
||||
import me.retucio.camtweaks.util.Colors;
|
||||
import me.retucio.camtweaks.util.KeyUtil;
|
||||
@@ -23,23 +24,17 @@ public class BindButton extends SettingButton {
|
||||
@Override
|
||||
public void render(DrawContext ctx, double mouseX, double mouseY, float delta) {
|
||||
int bgColor = isHovered((int) mouseX, (int) mouseY)
|
||||
? Colors.hoveredSettingButtonColor
|
||||
: Colors.settingButtonColor;
|
||||
? Colors.buttonColor.brighter().getRGB()
|
||||
: Colors.buttonColor.getRGB();
|
||||
|
||||
ctx.fill(x, y, x + w, y + height, bgColor);
|
||||
ctx.fill(x, y, x + w, y + h, bgColor);
|
||||
String label = setting.getName() + ": " + (listening ? "..." : setting.getKeyName());
|
||||
ctx.drawTextWithShadow(parent.mc.textRenderer, label, x + 5, y + 3, -1);
|
||||
|
||||
if (isHovered((int) mouseX, (int) mouseY)) {
|
||||
Screen currentScreen = parent.mc.currentScreen;
|
||||
if (currentScreen != null)
|
||||
ctx.drawTooltip(Text.of(setting.getDescription()), (int) mouseX, (int) mouseY + 20);
|
||||
}
|
||||
ctx.drawText(parent.mc.textRenderer, label, x + 5, y + 3, -1, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseClicked(double mouseX, double mouseY, int button) {
|
||||
if (isHovered((int) mouseX, (int) mouseY)) {
|
||||
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))
|
||||
setting.reset();
|
||||
@@ -67,5 +62,7 @@ public class BindButton extends SettingButton {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(double mouseX, double mouseY, int button) {}
|
||||
public void mouseReleased(double mouseX, double mouseY, int button) {
|
||||
ClickGUI.INSTANCE.unselect(this);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package me.retucio.camtweaks.ui.buttons;
|
||||
|
||||
import me.retucio.camtweaks.module.settings.EnumSetting;
|
||||
import me.retucio.camtweaks.ui.ClickGUI;
|
||||
import me.retucio.camtweaks.ui.frames.SettingsFrame;
|
||||
import me.retucio.camtweaks.util.Colors;
|
||||
import me.retucio.camtweaks.util.KeyUtil;
|
||||
@@ -26,16 +27,18 @@ public class CycleButton<E extends Enum<E>> extends SettingButton {
|
||||
@Override
|
||||
public void render(DrawContext ctx, double mouseX, double mouseY, float delta) {
|
||||
int bgColor = isHovered((int) mouseX, (int) mouseY)
|
||||
? Colors.hoveredSettingButtonColor
|
||||
: Colors.settingButtonColor;
|
||||
? Colors.buttonColor.brighter().getRGB()
|
||||
: Colors.buttonColor.getRGB();
|
||||
|
||||
ctx.fill(x, y, x + w, y + height, bgColor); // fondo del botón
|
||||
ctx.fill(x, y, x + w, y + h, bgColor); // fondo del botón
|
||||
|
||||
// texto del botón: nombre + valor de texto del enum
|
||||
String label = setting.getName() + ": " + setting.getValue().toString();
|
||||
ctx.drawTextWithShadow(parent.mc.textRenderer, label, x + 5, y + 3, -1);
|
||||
ctx.drawText(parent.mc.textRenderer, label, x + 5, y + 3, -1, true);
|
||||
}
|
||||
|
||||
// tooltip
|
||||
@Override
|
||||
public void drawTooltip(DrawContext ctx, double mouseX, double mouseY) {
|
||||
if (isHovered((int) mouseX, (int) mouseY)) {
|
||||
Screen currentScreen = parent.mc.currentScreen;
|
||||
if (currentScreen != null) {
|
||||
@@ -56,10 +59,9 @@ public class CycleButton<E extends Enum<E>> extends SettingButton {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void mouseClicked(double mouseX, double mouseY, int button) {
|
||||
if (isHovered((int) mouseX, (int) mouseY)) {
|
||||
if (isHovered((int) mouseX, (int) mouseY) && ClickGUI.INSTANCE.trySelect(this)) {
|
||||
if (button == 0) {
|
||||
setting.cycle(); // clic izquierdo -> ciclar
|
||||
} else if (button == 1) {
|
||||
@@ -67,7 +69,7 @@ public class CycleButton<E extends Enum<E>> extends SettingButton {
|
||||
if (KeyUtil.isKeyDown(GLFW.GLFW_KEY_LEFT_SHIFT))
|
||||
setting.reset();
|
||||
else
|
||||
setting.cycleBackwards(); // simplemente clic derecho -> ciclar valores pero hacia atrás
|
||||
setting.cycleBackwards(); // solamente clic derecho -> ciclar valores pero hacia atrás
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -77,5 +79,7 @@ public class CycleButton<E extends Enum<E>> extends SettingButton {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(double mouseX, double mouseY, int button) {}
|
||||
public void mouseReleased(double mouseX, double mouseY, int button) {
|
||||
ClickGUI.INSTANCE.unselect(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
package me.retucio.camtweaks.ui.buttons;
|
||||
|
||||
import me.retucio.camtweaks.module.Module;
|
||||
import me.retucio.camtweaks.module.settings.BooleanSetting;
|
||||
import me.retucio.camtweaks.module.settings.ListSetting;
|
||||
import me.retucio.camtweaks.ui.ClickGUI;
|
||||
import me.retucio.camtweaks.ui.frames.SettingsFrame;
|
||||
import me.retucio.camtweaks.util.Colors;
|
||||
import me.retucio.camtweaks.util.KeyUtil;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.text.Text;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class ListButton<T> extends SettingButton {
|
||||
|
||||
private final ListSetting<T> setting;
|
||||
private final Module dummy;
|
||||
|
||||
private final Map<T, BooleanSetting> optionButtons = new HashMap<>();
|
||||
|
||||
public ListButton(ListSetting<T> setting, SettingsFrame parent, int offset) {
|
||||
super(setting, parent, offset);
|
||||
this.setting = setting;
|
||||
|
||||
// crear un módulo "dummy" (falso), que se le añade cada entrada en la lista como un BooleanSetting
|
||||
dummy = new Module(setting.getName(), setting.getDescription()) {
|
||||
@Override public void onEnable() {}
|
||||
@Override public void onDisable() {}
|
||||
};
|
||||
|
||||
// ocultar cosas innecesarias
|
||||
dummy.getBind().setVisible(false);
|
||||
dummy.getSettings().stream()
|
||||
.filter(s -> s.getName().equalsIgnoreCase("modo de tecla"))
|
||||
.findFirst()
|
||||
.ifPresent(s -> s.setVisible(false));
|
||||
dummy.getSettings().stream()
|
||||
.filter(s -> s.getName().equalsIgnoreCase("notificar"))
|
||||
.findFirst()
|
||||
.ifPresent(s -> s.setVisible(false));
|
||||
dummy.shouldSaveSettings(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(DrawContext ctx, double mouseX, double mouseY, float delta) {
|
||||
int bgColor = isHovered(mouseX, mouseY)
|
||||
? Colors.buttonColor.brighter().getRGB()
|
||||
: Colors.buttonColor.getRGB();
|
||||
|
||||
ctx.fill(x, y, x + w, y + h, bgColor);
|
||||
|
||||
String label = setting.getName() + " (" + countEnabled() + "/" + setting.getOptions().size() + ")";
|
||||
ctx.drawText(parent.mc.textRenderer, label, x + 5, y + 3, -1, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawTooltip(DrawContext ctx, double mouseX, double mouseY) {
|
||||
if (isHovered(mouseX, mouseY))
|
||||
ctx.drawTooltip(Text.of(setting.getDescription() + "( " + countEnabled() + " de " + setting.getOptions().size() + ")"), (int) mouseX, (int) mouseY);
|
||||
}
|
||||
|
||||
@Override
|
||||
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 (ClickGUI.INSTANCE.isSettingsFrameOpen(dummy)) {
|
||||
ClickGUI.INSTANCE.closeSettingsFrame(dummy);
|
||||
return;
|
||||
}
|
||||
|
||||
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)) {
|
||||
setting.reset();
|
||||
refreshDummy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void rebuildDummy() {
|
||||
dummy.getSettings().clear();
|
||||
optionButtons.clear();
|
||||
|
||||
setting.getOptions().stream()
|
||||
.sorted(Comparator.comparing(setting::getDisplayName, String.CASE_INSENSITIVE_ORDER))
|
||||
.forEach(option -> {
|
||||
String displayName = setting.getDisplayName(option);
|
||||
BooleanSetting b = dummy.addSetting(new BooleanSetting(
|
||||
displayName,
|
||||
"incluir " + displayName,
|
||||
setting.isEnabled(option)
|
||||
));
|
||||
b.onUpdate(value -> setting.setEnabled(option, value));
|
||||
optionButtons.put(option, b);
|
||||
});
|
||||
}
|
||||
|
||||
public void refreshDummy() {
|
||||
optionButtons.forEach((option, boolSetting) ->
|
||||
boolSetting.setEnabled(setting.isEnabled(option)));
|
||||
}
|
||||
|
||||
private int countEnabled() {
|
||||
return (int) setting.getOptions().stream().filter(setting::isEnabled).count();
|
||||
}
|
||||
|
||||
public ListSetting<T> getSetting() {
|
||||
return setting;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(double mouseX, double mouseY, int button) {
|
||||
ClickGUI.INSTANCE.unselect(this);
|
||||
}
|
||||
}
|
||||
@@ -24,43 +24,51 @@ public class ModuleButton {
|
||||
|
||||
public void render(DrawContext ctx, double mouseX, double mouseY, float delta) {
|
||||
ctx.fill( // dibujar el contorno del botón
|
||||
parent.x + 2, parent.y + offset + 3,
|
||||
parent.x + parent.w - 2 , parent.y + height + offset,
|
||||
parent.x + 2, parent.renderY + offset + 3,
|
||||
parent.x + parent.w - 2 , parent.renderY + height + offset,
|
||||
determineColor(mouseX, mouseY));
|
||||
|
||||
ctx.drawTextWithShadow( // dibujar el nombre del módulo
|
||||
ctx.drawText( // dibujar el nombre del módulo
|
||||
parent.mc.textRenderer, module.getName(),
|
||||
parent.x + 5, parent.y + offset + (height / 2) - (parent.mc.textRenderer.fontHeight / 2) + 2, -1);
|
||||
parent.x + 5, parent.renderY + offset + (height / 2) - (parent.mc.textRenderer.fontHeight / 2) + 2,
|
||||
-1, true);
|
||||
|
||||
// dibujar "tooltips" (cajas de texto) al pasar el puntero encima del botón, para mostrar su descripción
|
||||
if (isHovered((int) mouseX, (int) mouseY)) {
|
||||
Screen currentScreen = parent.mc.currentScreen;
|
||||
if (currentScreen != null)
|
||||
ctx.drawTooltip(Text.of(module.getDescription()), (int) mouseX, (int) mouseY + 20);
|
||||
}
|
||||
if (isHovered((int) mouseX, (int) mouseY))
|
||||
ctx.drawTooltip(Text.of(module.getDescription()), (int) mouseX, (int) mouseY + 20);
|
||||
}
|
||||
|
||||
public void mouseClicked(double mouseX, double mouseY, int button) {
|
||||
if (button == 0) {// clic izquierdo para activar / desactivar el módulo
|
||||
module.toggle();
|
||||
} else if (button == 1) { // clic derecho para el marco de ajustes (también lo cierra si está abierto)
|
||||
if (ClickGUI.INSTANCE.isSettingsFrameOpen(module))
|
||||
ClickGUI.INSTANCE.closeSettingsFrame(module);
|
||||
else
|
||||
ClickGUI.INSTANCE.openSettingsFrame(module,
|
||||
parent.x + parent.w + 120, parent.y + offset);
|
||||
if (isHovered((int) mouseX, (int) mouseY) && ClickGUI.INSTANCE.trySelect(this)) {
|
||||
if (button == 0) { // clic izquierdo para activar / desactivar el módulo
|
||||
module.toggle();
|
||||
} else if (button == 1) { // clic derecho para el marco de ajustes (también lo cierra si está abierto)
|
||||
if (ClickGUI.INSTANCE.isSettingsFrameOpen(module))
|
||||
ClickGUI.INSTANCE.closeSettingsFrame(module);
|
||||
else
|
||||
ClickGUI.INSTANCE.openSettingsFrame(module,
|
||||
parent.x + parent.w + 120, parent.renderY + offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void mouseReleased(double mouseX, double mouseY, int button) {
|
||||
ClickGUI.INSTANCE.unselect(this);
|
||||
}
|
||||
|
||||
// verifica si el puntero del ratón se encuentra sobre el botón del módulo
|
||||
public boolean isHovered(int mouseX, int mouseY) {
|
||||
return mouseX > parent.x && mouseX < parent.x + parent.w && mouseY > parent.y + offset && mouseY < parent.y + height + offset;
|
||||
return ClickGUI.INSTANCE.canSelect(this)
|
||||
&& mouseX > parent.x
|
||||
&& mouseX < parent.x + parent.w
|
||||
&& mouseY > parent.renderY + offset
|
||||
&& mouseY < parent.renderY + height + offset;
|
||||
}
|
||||
|
||||
public int determineColor(double mouseX, double mouseY) {
|
||||
// determina el color del botón, dependiendo de si está el puntero encima y si está activado
|
||||
if (module.isEnabled())
|
||||
return isHovered((int) mouseX, (int) mouseY) ? Colors.enabledHoveredModuleButtonColor : Colors.enabledModuleButtonColor;
|
||||
return isHovered((int) mouseX, (int) mouseY) ? Colors.hoveredModuleButtonColor : Colors.moduleButtonColor;
|
||||
return isHovered((int) mouseX, (int) mouseY) ? Colors.mainColor.brighter().getRGB() : Colors.mainColor.getRGB();
|
||||
return isHovered((int) mouseX, (int) mouseY) ? Colors.buttonColor.brighter().getRGB() : Colors.buttonColor.getRGB();
|
||||
}
|
||||
}
|
||||
@@ -1,20 +1,22 @@
|
||||
package me.retucio.camtweaks.ui.buttons;
|
||||
|
||||
import me.retucio.camtweaks.module.settings.Setting;
|
||||
import me.retucio.camtweaks.module.settings.AbstractSetting;
|
||||
import me.retucio.camtweaks.ui.ClickGUI;
|
||||
import me.retucio.camtweaks.ui.frames.SettingsFrame;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
// clase base para los botones de los ajustes
|
||||
public abstract class SettingButton {
|
||||
|
||||
protected final Setting setting;
|
||||
protected final AbstractSetting setting;
|
||||
protected final SettingsFrame parent;
|
||||
protected int offset;
|
||||
protected final int height = 15;
|
||||
|
||||
protected int x, y, w, h;
|
||||
|
||||
public SettingButton(Setting setting, SettingsFrame parent, int offset) {
|
||||
public SettingButton(AbstractSetting setting, SettingsFrame parent, int offset) {
|
||||
this.setting = setting;
|
||||
this.parent = parent;
|
||||
this.offset = offset;
|
||||
@@ -24,12 +26,23 @@ public abstract class SettingButton {
|
||||
public abstract void mouseClicked(double mouseX, double mouseY, int button);
|
||||
public abstract void mouseReleased(double mouseX, double mouseY, int button);
|
||||
|
||||
// dibujar "tooltips" (cajitas de texto bajo el puntero del ratón) con la descripción para asistir al usuario en el caso de que tenga down
|
||||
public void drawTooltip(DrawContext ctx, double mouseX, double mouseY) {
|
||||
if (isHovered((int) mouseX, (int) mouseY))
|
||||
ctx.drawTooltip(Text.of(setting.getDescription()), (int) mouseX, (int) mouseY + 20);
|
||||
}
|
||||
|
||||
protected boolean isHovered(double mouseX, double mouseY) {
|
||||
return isHovered((int) mouseX, (int) mouseY);
|
||||
}
|
||||
|
||||
protected boolean isHovered(int mouseX, int mouseY) {
|
||||
if (!ClickGUI.INSTANCE.canSelect(this)) return false;
|
||||
return mouseX > x && mouseX < x + w &&
|
||||
mouseY > y && mouseY < y + h;
|
||||
}
|
||||
|
||||
public Setting getSetting() {
|
||||
public AbstractSetting getSetting() {
|
||||
return setting;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,8 @@ package me.retucio.camtweaks.ui.buttons;
|
||||
import me.retucio.camtweaks.event.SubscribeEvent;
|
||||
import me.retucio.camtweaks.event.events.KeyEvent;
|
||||
import me.retucio.camtweaks.module.settings.NumberSetting;
|
||||
import me.retucio.camtweaks.ui.frames.ClickGUISettingsFrame;
|
||||
import me.retucio.camtweaks.ui.ClickGUI;
|
||||
import me.retucio.camtweaks.ui.frames.ClientSettingsFrame;
|
||||
import me.retucio.camtweaks.ui.frames.SettingsFrame;
|
||||
import me.retucio.camtweaks.util.Colors;
|
||||
import me.retucio.camtweaks.util.KeyUtil;
|
||||
@@ -12,6 +13,7 @@ import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.text.Text;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import java.awt.*;
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
import static me.retucio.camtweaks.CameraTweaks.EVENT_BUS;
|
||||
@@ -32,15 +34,23 @@ public class SliderButton extends SettingButton {
|
||||
|
||||
@Override
|
||||
public void render(DrawContext ctx, double mouseX, double mouseY, float delta) {
|
||||
ctx.fill(x, y, x + w, y + height, Colors.moduleButtonColor);
|
||||
Color bgColor = Colors.buttonColor;
|
||||
Color fillingColor = Colors.mainColor;
|
||||
|
||||
// calcular cómo de llena tendría que estar el "slider"
|
||||
if (isHovered(mouseX, mouseY)) {
|
||||
bgColor = bgColor.brighter();
|
||||
fillingColor = fillingColor.brighter();
|
||||
}
|
||||
|
||||
ctx.fill(x, y, x + w, y + h, bgColor.getRGB());
|
||||
|
||||
// calcular cómo de lleno tendría que estar el "slider"
|
||||
double percent = (setting.getValue() - setting.getMin()) / (setting.getMax() - setting.getMin());
|
||||
int filled = (int) (percent * w);
|
||||
ctx.fill(x, y, x + filled, y + height, Colors.sliderFillingColor);
|
||||
ctx.fill(x, y, x + filled, y + h, fillingColor.getRGB());
|
||||
|
||||
String label = setting.getName() + ": " + df.format(setting.getValue());
|
||||
ctx.drawTextWithShadow(parent.mc.textRenderer, label, x + 5, y + 3, -1);
|
||||
ctx.drawText(parent.mc.textRenderer, label, x + 5, y + 3, -1, true);
|
||||
|
||||
// lógica para el arrastre (arrastramiento?) del valor
|
||||
if (dragging) {
|
||||
@@ -49,18 +59,11 @@ public class SliderButton extends SettingButton {
|
||||
newVal = Math.round(newVal / setting.getIncrement()) * setting.getIncrement();
|
||||
setting.setValue((float) newVal);
|
||||
}
|
||||
|
||||
// dibujar "tooltips" (cajas de texto) al pasar el puntero encima del botón, para mostrar su descripción
|
||||
if (isHovered((int) mouseX, (int) mouseY)) {
|
||||
Screen currentScreen = parent.mc.currentScreen;
|
||||
if (currentScreen != null)
|
||||
ctx.drawTooltip(Text.of(setting.getDescription()), (int) mouseX, (int) mouseY + 20);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseClicked(double mouseX, double mouseY, int button) {
|
||||
if (isHovered((int) mouseX, (int) mouseY)) {
|
||||
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
|
||||
setting.reset();
|
||||
@@ -69,13 +72,14 @@ public class SliderButton extends SettingButton {
|
||||
|
||||
@Override
|
||||
public void mouseReleased(double mouseX, double mouseY, int button) {
|
||||
ClickGUI.INSTANCE.unselect(this);
|
||||
if (button == 0) dragging = false;
|
||||
}
|
||||
|
||||
@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
|
||||
if (event.getKey() == GLFW.GLFW_KEY_ESCAPE || event.getKey() == ClickGUISettingsFrame.guiSettings.getKey()) dragging = false;
|
||||
if (event.getKey() == GLFW.GLFW_KEY_ESCAPE || event.getKey() == ClientSettingsFrame.guiSettings.getKey()) dragging = false;
|
||||
}
|
||||
|
||||
public NumberSetting getSetting() {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package me.retucio.camtweaks.ui.buttons;
|
||||
|
||||
import me.retucio.camtweaks.module.settings.StringSetting;
|
||||
import me.retucio.camtweaks.ui.ClickGUI;
|
||||
import me.retucio.camtweaks.ui.frames.SettingsFrame;
|
||||
import me.retucio.camtweaks.util.Colors;
|
||||
import me.retucio.camtweaks.util.KeyUtil;
|
||||
@@ -8,6 +9,8 @@ import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.text.Text;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import static me.retucio.camtweaks.CameraTweaks.mc;
|
||||
|
||||
// botón para los ajustes que requieran introducir texto
|
||||
public class TextButton extends SettingButton {
|
||||
|
||||
@@ -23,23 +26,18 @@ public class TextButton extends SettingButton {
|
||||
@Override
|
||||
public void render(DrawContext ctx, double mouseX, double mouseY, float delta) {
|
||||
int bgColor = isHovered((int) mouseX, (int) mouseY)
|
||||
? Colors.hoveredSettingButtonColor
|
||||
: Colors.settingButtonColor;
|
||||
? Colors.buttonColor.brighter().getRGB()
|
||||
: Colors.buttonColor.getRGB();
|
||||
|
||||
ctx.fill(x, y, x + w, y + height, bgColor);
|
||||
ctx.fill(x, y, x + w, y + h, bgColor);
|
||||
|
||||
String label = setting.getName() + ": " + (typing ? buffer + "_" : setting.getValue());
|
||||
ctx.drawTextWithShadow(parent.mc.textRenderer, label, x + 5, y + 3, -1);
|
||||
|
||||
if (isHovered((int) mouseX, (int) mouseY)) {
|
||||
if (parent.mc.currentScreen != null)
|
||||
ctx.drawTooltip(Text.of(setting.getDescription()), (int) mouseX, (int) mouseY + 20);
|
||||
}
|
||||
ctx.drawText(parent.mc.textRenderer, label, x + 5, y + 3, -1, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseClicked(double mouseX, double mouseY, int button) {
|
||||
if (isHovered((int) mouseX, (int) mouseY)) {
|
||||
if (isHovered((int) mouseX, (int) mouseY) && ClickGUI.INSTANCE.trySelect(this)) {
|
||||
if (button == 0) {
|
||||
typing = true;
|
||||
buffer.setLength(0);
|
||||
@@ -53,6 +51,11 @@ public class TextButton extends SettingButton {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(double mouseX, double mouseY, int button) {
|
||||
ClickGUI.INSTANCE.unselect(this);
|
||||
}
|
||||
|
||||
public void onKey(int key, int action) {
|
||||
if (!typing || action == GLFW.GLFW_RELEASE) return;
|
||||
|
||||
@@ -79,6 +82,7 @@ public class TextButton extends SettingButton {
|
||||
private void charTyped(char c) {
|
||||
if (!typing) return;
|
||||
buffer.append(c);
|
||||
if (mc.textRenderer.getWidth(setting.getName() + ": " + buffer + "_") > w - 8) onBackspace();
|
||||
}
|
||||
|
||||
public boolean isFocused() {
|
||||
@@ -92,7 +96,4 @@ public class TextButton extends SettingButton {
|
||||
private void onBackspace() {
|
||||
if (!buffer.isEmpty()) buffer.deleteCharAt(buffer.length() - 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(double mouseX, double mouseY, int button) {}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package me.retucio.camtweaks.ui.buttons;
|
||||
|
||||
import me.retucio.camtweaks.module.settings.BooleanSetting;
|
||||
import me.retucio.camtweaks.ui.ClickGUI;
|
||||
import me.retucio.camtweaks.ui.frames.SettingsFrame;
|
||||
import me.retucio.camtweaks.util.Colors;
|
||||
import me.retucio.camtweaks.util.KeyUtil;
|
||||
@@ -28,34 +29,27 @@ public class ToggleButton extends SettingButton {
|
||||
: Colors.disabledToggleButtonColor;
|
||||
|
||||
if (isHovered((int) mouseX, (int) mouseY))
|
||||
color = color.brighter(); // simplemente utilizar el método "built-in" de Java para hacer el botón más claro cuando el puntero se encuentra encima de él
|
||||
// quizás debería de utilizar .brighter() más, en vez de dar valores personalizados
|
||||
color = color.brighter();
|
||||
|
||||
ctx.fill(x, y, x + w, y + height, color.getRGB());
|
||||
ctx.drawTextWithShadow(parent.mc.textRenderer,
|
||||
setting.getName(), x + 5, y + 3, -1);
|
||||
|
||||
// dibujar "tooltips" (cajas de texto) al pasar el puntero encima del botón, para mostrar su descripción
|
||||
if (isHovered((int) mouseX, (int) mouseY)) {
|
||||
Screen currentScreen = parent.mc.currentScreen;
|
||||
if (currentScreen != null)
|
||||
ctx.drawTooltip(Text.of(setting.getDescription()), (int) mouseX, (int) mouseY + 20);
|
||||
}
|
||||
ctx.fill(x, y, x + w, y + h, color.getRGB());
|
||||
ctx.drawText(parent.mc.textRenderer, setting.getName(), x + 5, y + 3, -1, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseClicked(double mouseX, double mouseY, int button) {
|
||||
if (isHovered((int) mouseX, (int) mouseY)) {
|
||||
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
|
||||
setting.reset();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(double mouseX, double mouseY, int button) {
|
||||
ClickGUI.INSTANCE.unselect(this);
|
||||
}
|
||||
|
||||
public BooleanSetting getSetting() {
|
||||
return setting;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(double mouseX, double mouseY, int button) {}
|
||||
}
|
||||
@@ -3,61 +3,68 @@ package me.retucio.camtweaks.ui.frames;
|
||||
import me.retucio.camtweaks.CameraTweaks;
|
||||
import me.retucio.camtweaks.event.events.camtweaks.GUISettingsFrameEvent;
|
||||
import me.retucio.camtweaks.module.modules.GUI;
|
||||
import me.retucio.camtweaks.ui.ClickGUI;
|
||||
import me.retucio.camtweaks.ui.buttons.SettingButton;
|
||||
import me.retucio.camtweaks.util.Colors;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ClickGUISettingsFrame extends SettingsFrame {
|
||||
public class ClientSettingsFrame extends SettingsFrame {
|
||||
|
||||
public static final GUI guiSettings = new GUI();
|
||||
public boolean extended = false;
|
||||
private String title = "ajustes de la interfaz -";
|
||||
private final String title = "ajustes del mod";
|
||||
|
||||
public ClickGUISettingsFrame(int x, int y, int w, int h) {
|
||||
public ClientSettingsFrame(int x, int y, int w, int h) {
|
||||
super(guiSettings, x, y, w, h);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(DrawContext ctx, int mouseX, int mouseY, float delta) {
|
||||
updateWidth();
|
||||
ctx.fill(x, y, x + w, y + h, Colors.frameHeadColor);
|
||||
ctx.fill(x, renderY, x + w, renderY + h, Colors.mainColor.getRGB());
|
||||
|
||||
ctx.drawText(mc.textRenderer, title,
|
||||
x + (w / 2) - (mc.textRenderer.getWidth(title) / 2),
|
||||
y + (h / 2) - (mc.textRenderer.fontHeight / 2),
|
||||
-1, false);
|
||||
x + 8,
|
||||
renderY + (h / 2) - (mc.textRenderer.fontHeight / 2),
|
||||
-1, true);
|
||||
|
||||
ctx.drawText(mc.textRenderer, extended ? "-" : "+",
|
||||
x + w - mc.textRenderer.getWidth("+") - 8,
|
||||
renderY + (h / 2) - (mc.textRenderer.fontHeight / 2),
|
||||
-1, true);
|
||||
|
||||
List<SettingButton> visibleButtons = settingButtons.stream()
|
||||
.filter(sb -> sb.getSetting().isVisible())
|
||||
.filter(sb -> sb.getSetting().isVisible() && sb.getSetting().isSearchMatch())
|
||||
.toList();
|
||||
|
||||
if (extended) {
|
||||
int currentY = y + h + 3;
|
||||
ctx.fill(x, currentY - 2, x + w, currentY + visibleButtons.size() * h, Colors.frameBGColor);
|
||||
int currentY = renderY + h + 3;
|
||||
totalHeight = visibleButtons.size() * h;
|
||||
ctx.fill(x, currentY - 2, x + w, currentY + totalHeight, Colors.frameBGColor.getRGB());
|
||||
|
||||
for (SettingButton sb : visibleButtons) {
|
||||
sb.setX(x + 4);
|
||||
sb.setY(currentY);
|
||||
sb.setW(w - 8);
|
||||
sb.setH(h);
|
||||
sb.setH(h - h / 4);
|
||||
sb.render(ctx, mouseX, mouseY, delta);
|
||||
sb.drawTooltip(ctx, mouseX, mouseY);
|
||||
currentY += h;
|
||||
}
|
||||
}
|
||||
} else totalHeight = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseClicked(double mouseX, double mouseY, int button) {
|
||||
if (isHovered(mouseX, mouseY)) {
|
||||
if (isHovered(mouseX, mouseY) && ClickGUI.INSTANCE.trySelect(this)) {
|
||||
if (button == 0) {
|
||||
dragging = true;
|
||||
dragX = (int) (mouseX - x);
|
||||
dragY = (int) (mouseY - y);
|
||||
} else if (button == 1) {
|
||||
extended = !extended;
|
||||
title = extended ? "ajustes de la interfaz -" : "ajustes de la interfaz +";
|
||||
CameraTweaks.EVENT_BUS.post(new GUISettingsFrameEvent.Extend());
|
||||
}
|
||||
}
|
||||
@@ -69,9 +76,10 @@ public class ClickGUISettingsFrame extends SettingsFrame {
|
||||
|
||||
@Override
|
||||
public void mouseRelease(double mouseX, double mouseY, int button) {
|
||||
if (button == 0 && dragging) {
|
||||
ClickGUI.INSTANCE.unselect(this);
|
||||
if (button == 0 && dragging)
|
||||
CameraTweaks.EVENT_BUS.post(new GUISettingsFrameEvent.Move());
|
||||
}
|
||||
|
||||
super.mouseRelease(mouseX, mouseY, button);
|
||||
}
|
||||
}
|
||||
@@ -4,10 +4,13 @@ import me.retucio.camtweaks.CameraTweaks;
|
||||
import me.retucio.camtweaks.event.events.camtweaks.ModuleFrameEvent;
|
||||
import me.retucio.camtweaks.module.Module;
|
||||
import me.retucio.camtweaks.module.ModuleManager;
|
||||
import me.retucio.camtweaks.ui.ClickGUI;
|
||||
import me.retucio.camtweaks.ui.buttons.ModuleButton;
|
||||
import me.retucio.camtweaks.util.Colors;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Formatting;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -15,9 +18,12 @@ import java.util.List;
|
||||
// marco para los módulos
|
||||
public class ModuleFrame {
|
||||
|
||||
public int x, y, w, h, dragX, dragY;
|
||||
public int x, y, w, h;
|
||||
public int renderY;
|
||||
public int dragX, dragY;
|
||||
public int totalHeight = 0;
|
||||
public boolean dragging, extended;
|
||||
public String title = "módulos -";
|
||||
public final String title = "módulos";
|
||||
|
||||
private final List<ModuleButton> moduleButtons = new ArrayList<>();
|
||||
|
||||
@@ -40,6 +46,10 @@ public class ModuleFrame {
|
||||
}
|
||||
}
|
||||
|
||||
public void updateRenderY(int scrollOffset) {
|
||||
renderY = y - scrollOffset;
|
||||
}
|
||||
|
||||
void updateWidth() {
|
||||
// asegurarse de que todos los botones caben en el marco, haciendo que la anchura se ajuste al texto más largo
|
||||
if (mc.textRenderer == null) return;
|
||||
@@ -55,61 +65,68 @@ public class ModuleFrame {
|
||||
|
||||
public void render(DrawContext ctx, int mouseX, int mouseY, float delta) {
|
||||
updateWidth();
|
||||
ctx.fill(x, y, x + w, y + h, Colors.frameHeadColor); // cabeza del marco
|
||||
ctx.fill(x, renderY, x + w, renderY + h, Colors.mainColor.getRGB()); // cabeza del marco
|
||||
// título del marco
|
||||
ctx.drawText(mc.textRenderer, title,
|
||||
x + (w / 2) - (mc.textRenderer.getWidth(title) / 2),
|
||||
y + ( h /2) - (mc.textRenderer.fontHeight / 2),
|
||||
-1, false);
|
||||
ctx.drawText(mc.textRenderer, Text.literal(Formatting.BOLD + title),
|
||||
x + 8,
|
||||
renderY + (h / 2) - (mc.textRenderer.fontHeight / 2),
|
||||
-1, true);
|
||||
|
||||
ctx.drawText(mc.textRenderer, extended ? "-" : "+",
|
||||
x + w - mc.textRenderer.getWidth("+") - 8, // '+' y '-' tienen la misma anchura, o sea que no importa cuál use
|
||||
renderY + (h / 2) - (mc.textRenderer.fontHeight / 2),
|
||||
-1, true);
|
||||
|
||||
// dibujar sus módulos solo si está extendido
|
||||
if (extended) {
|
||||
int totalHeight = moduleButtons.size() * h + 3;
|
||||
ctx.fill( // fondo para los botones
|
||||
x, y + h + 1,
|
||||
x + w, y + h + totalHeight,
|
||||
Colors.frameBGColor);
|
||||
totalHeight = moduleButtons.size() * h + 3;
|
||||
ctx.fill( // fondo para los botones
|
||||
x, renderY + h + 1,
|
||||
x + w, renderY + h + totalHeight,
|
||||
Colors.frameBGColor.getRGB());
|
||||
|
||||
// dibujar los botones para cada módulo
|
||||
for (ModuleButton moduleButton : moduleButtons)
|
||||
moduleButton.render(ctx, mouseX, mouseY, delta);
|
||||
}
|
||||
} else totalHeight = 0;
|
||||
}
|
||||
|
||||
public void mouseClicked(double mouseX, double mouseY, int button) {
|
||||
// registrar clics
|
||||
if (isHovered(mouseX, mouseY)) {
|
||||
if (isHovered(mouseX, mouseY) && ClickGUI.INSTANCE.trySelect(this)) {
|
||||
if (button == 0) { // clic izquierdo para arrastrarlo
|
||||
dragging = true;
|
||||
dragX = (int) (mouseX - x);
|
||||
dragY = (int) (mouseY - y);
|
||||
} else if (button == 1) { // clic derecho para extenderlo
|
||||
extended = !extended;
|
||||
title = extended ? "módulos -" : "módulos +";
|
||||
CameraTweaks.EVENT_BUS.post(new ModuleFrameEvent.Extend());
|
||||
}
|
||||
}
|
||||
|
||||
if (!extended) return; // solo dejar clicar en los módulos si el marco está extendido
|
||||
for (ModuleButton moduleButton : moduleButtons) {
|
||||
if (moduleButton.isHovered((int) mouseX, (int) mouseY)) {
|
||||
for (ModuleButton moduleButton : moduleButtons)
|
||||
moduleButton.mouseClicked(mouseX, mouseY, button);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// detectar cuándo se suelta el clic
|
||||
public void mouseReleased(double mouseX, double mouseY, int button) {
|
||||
if (button == 0 && dragging) {
|
||||
ClickGUI.INSTANCE.unselect(this);
|
||||
if (button == 0 && dragging)
|
||||
dragging = false;
|
||||
|
||||
for (ModuleButton moduleButton : moduleButtons) {
|
||||
if (moduleButton.isHovered((int) mouseX, (int) mouseY))
|
||||
moduleButton.mouseReleased(mouseX, mouseY, button);
|
||||
}
|
||||
CameraTweaks.EVENT_BUS.post(new ModuleFrameEvent.Move());
|
||||
|
||||
if (isHovered(mouseX, mouseY))
|
||||
CameraTweaks.EVENT_BUS.post(new ModuleFrameEvent.Move());
|
||||
}
|
||||
|
||||
// verificar si el puntero del ratón se encuentra encima
|
||||
public boolean isHovered(double mouseX, double mouseY) {
|
||||
return mouseX > x && mouseX < x + w && mouseY > y && mouseY < y + h;
|
||||
return mouseX > x && mouseX < x + w && mouseY > renderY && mouseY < renderY + h;
|
||||
}
|
||||
|
||||
// actualizar la posición al arrastrar el marco
|
||||
|
||||
@@ -13,6 +13,7 @@ import me.retucio.camtweaks.util.Colors;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -23,9 +24,13 @@ public class SettingsFrame {
|
||||
public final Module module;
|
||||
final List<SettingButton> settingButtons = new ArrayList<>();
|
||||
|
||||
public List<SettingButton> visibleButtons = new ArrayList<>();
|
||||
|
||||
public int x, y, w, h;
|
||||
boolean dragging;
|
||||
public int renderY;
|
||||
int dragX, dragY;
|
||||
boolean dragging;
|
||||
public int totalHeight = 0;
|
||||
|
||||
public final MinecraftClient mc = MinecraftClient.getInstance();
|
||||
|
||||
@@ -39,7 +44,7 @@ public class SettingsFrame {
|
||||
|
||||
// añadir el respectivo tipo de botón de cada ajuste a la lista de botones
|
||||
int offset = h;
|
||||
for (Setting setting : module.getSettings()) {
|
||||
for (AbstractSetting setting : module.getSettings()) {
|
||||
if (!setting.isVisible()) continue;
|
||||
switch (setting) {
|
||||
case BooleanSetting b -> {
|
||||
@@ -57,10 +62,17 @@ public class SettingsFrame {
|
||||
} case StringSetting s -> {
|
||||
addButton(new TextButton(s, this, offset));
|
||||
offset += 18;
|
||||
} case ListSetting l -> {
|
||||
addButton(new ListButton<>(l, this, offset));
|
||||
offset += 18;
|
||||
} default -> {}
|
||||
}
|
||||
}
|
||||
title = "ajustes de " + module.getName() + " -";
|
||||
title = "ajustes de " + module.getName();
|
||||
|
||||
visibleButtons = settingButtons.stream()
|
||||
.filter(sb -> sb.getSetting().isVisible())
|
||||
.toList();
|
||||
}
|
||||
|
||||
public void addButton(SettingButton button) {
|
||||
@@ -68,6 +80,119 @@ public class SettingsFrame {
|
||||
updateWidth(); // actualizar anchura del frame tras cada iteración
|
||||
}
|
||||
|
||||
public void render(DrawContext ctx, int mouseX, int mouseY, float delta) {
|
||||
updateWidth();
|
||||
|
||||
// cabezal
|
||||
int centerX = x + w / 2;
|
||||
int centerY = renderY + h / 2;
|
||||
int titleX = x + 8;
|
||||
int titleY = centerY - mc.textRenderer.fontHeight / 2;
|
||||
|
||||
int headerColor = module.isEnabled()
|
||||
? Colors.enabledToggleButtonColor.getRGB()
|
||||
: Colors.disabledToggleButtonColor.getRGB();
|
||||
|
||||
int closeButtonColor = isCloseButtonHovered(mouseX, mouseY)
|
||||
? Color.RED.getRGB()
|
||||
: -1;
|
||||
|
||||
if (!module.shouldSaveSettings()) headerColor = (int) module.getSettings().stream().filter(s -> ((BooleanSetting) s).isEnabled()).count() > 0
|
||||
? Colors.enabledToggleButtonColor.getRGB()
|
||||
: Colors.disabledToggleButtonColor.getRGB();
|
||||
|
||||
ctx.fill(x, renderY, x + w, renderY + h, headerColor);
|
||||
ctx.drawText(mc.textRenderer, title, titleX, titleY, -1, true);
|
||||
ctx.drawText(mc.textRenderer, "×", x + w - mc.textRenderer.getWidth("×") - 8, titleY, closeButtonColor, true);
|
||||
|
||||
// descripción
|
||||
visibleButtons = settingButtons.stream()
|
||||
.filter(sb -> sb.getSetting().isVisible() && sb.getSetting().isSearchMatch())
|
||||
.toList();
|
||||
|
||||
List<String> descLines = wrapDescription(module.getDescription(), w - 8);
|
||||
int lineSpacing = 2;
|
||||
|
||||
int descHeight = descLines.size() * mc.textRenderer.fontHeight + (descLines.size() - 1) * lineSpacing;
|
||||
int descBoxTop = renderY + h + 5;
|
||||
int descBoxBottom = descBoxTop + descHeight + 8;
|
||||
|
||||
totalHeight = descHeight + 8 + h * visibleButtons.size() + 4;
|
||||
|
||||
ctx.fill(x, descBoxTop - 4, x + w, descBoxTop + totalHeight, Colors.frameBGColor.getRGB());
|
||||
ctx.fill(x + 4, descBoxTop, x + w - 4, descBoxBottom, Colors.buttonColor.getRGB());
|
||||
|
||||
int firstLineY = descBoxTop + ((descBoxBottom - descBoxTop) - descHeight) / 2;
|
||||
for (int i = 0; i < descLines.size(); i++) {
|
||||
String line = descLines.get(i);
|
||||
int lineX = centerX - mc.textRenderer.getWidth(line) / 2;
|
||||
int lineY = firstLineY + i * (mc.textRenderer.fontHeight + lineSpacing);
|
||||
ctx.drawText(mc.textRenderer, line, lineX, lineY, -1, true);
|
||||
}
|
||||
|
||||
int startButtonY = firstLineY - descBoxTop + descBoxBottom;
|
||||
for (SettingButton sb : visibleButtons) {
|
||||
sb.setX(x + 4);
|
||||
sb.setY(startButtonY);
|
||||
sb.setW(w - 8);
|
||||
sb.setH(h - h / 4);
|
||||
sb.render(ctx, mouseX, mouseY, delta);
|
||||
startButtonY += h;
|
||||
}
|
||||
}
|
||||
|
||||
public void drawTooltips(DrawContext ctx, double mouseX, double mouseY) {
|
||||
for (SettingButton sb : visibleButtons)
|
||||
sb.drawTooltip(ctx, mouseX, mouseY);
|
||||
}
|
||||
|
||||
|
||||
public void mouseClicked(double mouseX, double mouseY, int button) {
|
||||
if (isHovered(mouseX, mouseY) && ClickGUI.INSTANCE.trySelect(this)) {
|
||||
if (isCloseButtonHovered(mouseX, mouseY)) {
|
||||
ClickGUI.INSTANCE.closeSettingsFrame(this.module);
|
||||
return;
|
||||
} if (button == 0) {
|
||||
dragging = true;
|
||||
dragX = (int) (mouseX - x);
|
||||
dragY = (int) (mouseY - y);
|
||||
} else if (button == 1) {
|
||||
ClickGUI.INSTANCE.closeSettingsFrame(module);
|
||||
}
|
||||
}
|
||||
|
||||
for (SettingButton sb : settingButtons)
|
||||
if (sb.getSetting().isVisible())
|
||||
sb.mouseClicked(mouseX, mouseY, button);
|
||||
}
|
||||
|
||||
public void mouseRelease(double mouseX, double mouseY, int button) {
|
||||
ClickGUI.INSTANCE.unselect(this);
|
||||
if (button == 0) {
|
||||
dragging = false;
|
||||
CameraTweaks.EVENT_BUS.post(new SettingsFrameEvent.Move(this));
|
||||
}
|
||||
for (SettingButton sb : settingButtons)
|
||||
if (sb.getSetting().isVisible()) sb.mouseReleased(mouseX, mouseY, button);
|
||||
}
|
||||
|
||||
public void updatePosition(double mouseX, double mouseY) {
|
||||
if (dragging) {
|
||||
x = (int) (mouseX - dragX);
|
||||
y = (int) (mouseY - dragY);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isHovered(double mouseX, double mouseY) {
|
||||
return mouseX > x && mouseX < x + w &&
|
||||
mouseY > renderY && mouseY < renderY + h;
|
||||
}
|
||||
|
||||
public boolean isCloseButtonHovered(double mouseX, double mouseY) {
|
||||
return mouseX > x + w - mc.textRenderer.getWidth("×") - 12 && mouseX < x + w - 4
|
||||
&& mouseY > renderY + 4 && mouseY < renderY + h - 4;
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
void updateWidth() {
|
||||
// asegurarse de que todos los botones caben en el marco, haciendo que la anchura se ajuste al texto más largo
|
||||
@@ -88,76 +213,34 @@ public class SettingsFrame {
|
||||
int textWidth = mc.textRenderer.getWidth(text);
|
||||
maxWidth = Math.max(maxWidth, textWidth);
|
||||
}
|
||||
this.w = maxWidth + 22;
|
||||
this.w = maxWidth + 30;
|
||||
}
|
||||
|
||||
public void render(DrawContext ctx, int mouseX, int mouseY, float delta) {
|
||||
updateWidth();
|
||||
ctx.fill(x, y, x + w, y + h, module.isEnabled()
|
||||
? Colors.enabledToggleButtonColor.getRGB()
|
||||
: Colors.disabledToggleButtonColor.getRGB());
|
||||
private List<String> wrapDescription(String text, int maxWidth) {
|
||||
List<String> lines = new ArrayList<>();
|
||||
if (mc.textRenderer == null) return lines;
|
||||
|
||||
ctx.drawText(mc.textRenderer, title,
|
||||
x + (w / 2) - (mc.textRenderer.getWidth(title) / 2),
|
||||
y + (h / 2) - (mc.textRenderer.fontHeight / 2),
|
||||
-1, false);
|
||||
String[] words = text.split(" ");
|
||||
StringBuilder line = new StringBuilder();
|
||||
|
||||
List<SettingButton> visibleButtons = settingButtons.stream()
|
||||
.filter(sb -> sb.getSetting().isVisible())
|
||||
.toList();
|
||||
|
||||
int currentY = y + h + 3;
|
||||
ctx.fill(x, currentY - 2, x + w, currentY + visibleButtons.size() * h, Colors.frameBGColor);
|
||||
|
||||
for (SettingButton sb : visibleButtons) {
|
||||
sb.setX(x + 4);
|
||||
sb.setY(currentY);
|
||||
sb.setW(w - 8);
|
||||
sb.setH(h);
|
||||
sb.render(ctx, mouseX, mouseY, delta);
|
||||
currentY += h;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void mouseClicked(double mouseX, double mouseY, int button) {
|
||||
if (isHovered(mouseX, mouseY)) {
|
||||
if (button == 0) {
|
||||
dragging = true;
|
||||
dragX = (int) (mouseX - x);
|
||||
dragY = (int) (mouseY - y);
|
||||
} else if (button == 1) {
|
||||
ClickGUI.INSTANCE.closeSettingsFrame(module);
|
||||
for (String word : words) {
|
||||
String testLine = line.isEmpty() ? word : line + " " + word;
|
||||
if (mc.textRenderer.getWidth(testLine) > maxWidth - 8) { // padding of 4 each side
|
||||
if (!line.isEmpty()) lines.add(line.toString());
|
||||
line = new StringBuilder(word);
|
||||
} else {
|
||||
line = new StringBuilder(testLine);
|
||||
}
|
||||
}
|
||||
|
||||
for (SettingButton sb : settingButtons)
|
||||
if (sb.getSetting().isVisible())
|
||||
sb.mouseClicked(mouseX, mouseY, button);
|
||||
}
|
||||
|
||||
public void mouseRelease(double mouseX, double mouseY, int button) {
|
||||
if (button == 0) {
|
||||
dragging = false;
|
||||
CameraTweaks.EVENT_BUS.post(new SettingsFrameEvent.Move(this));
|
||||
}
|
||||
for (SettingButton sb : settingButtons)
|
||||
if (sb.getSetting().isVisible()) sb.mouseReleased(mouseX, mouseY, button);
|
||||
}
|
||||
|
||||
public void updatePosition(double mouseX, double mouseY) {
|
||||
if (dragging) {
|
||||
x = (int) (mouseX - dragX);
|
||||
y = (int) (mouseY - dragY);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isHovered(double mouseX, double mouseY) {
|
||||
return mouseX > x && mouseX < x + w &&
|
||||
mouseY > y && mouseY < y + h;
|
||||
if (!line.isEmpty()) lines.add(line.toString());
|
||||
return lines;
|
||||
}
|
||||
|
||||
public List<SettingButton> getButtons() {
|
||||
return settingButtons;
|
||||
}
|
||||
|
||||
public void updateRenderY(int scrollOffset) {
|
||||
renderY = y - scrollOffset;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
package me.retucio.camtweaks.ui.widgets;
|
||||
|
||||
import me.retucio.camtweaks.ui.ClickGUI;
|
||||
import me.retucio.camtweaks.ui.frames.ClientSettingsFrame;
|
||||
import me.retucio.camtweaks.util.Colors;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
public class ScrollBarWidget {
|
||||
|
||||
private boolean dragging;
|
||||
private int dragY, scrollStart;
|
||||
private int scrollOffset = 0;
|
||||
|
||||
private int contentHeight, windowHeight;
|
||||
|
||||
private final MinecraftClient mc = MinecraftClient.getInstance();
|
||||
|
||||
public ScrollBarWidget() {}
|
||||
|
||||
public void render(DrawContext ctx, double mouseX, double mouseY) {
|
||||
if (contentHeight <= windowHeight || !ClientSettingsFrame.guiSettings.scrollBar.isEnabled()) return;
|
||||
|
||||
int trackX1 = mc.getWindow().getScaledWidth() - 10;
|
||||
int trackX2 = trackX1 + 10;
|
||||
|
||||
ctx.fill(trackX1, 0, trackX2, windowHeight, Colors.buttonColor.getRGB());
|
||||
|
||||
int thumbHeight = getThumbHeight();
|
||||
int thumbY = getThumbY();
|
||||
|
||||
Color thumbColor = isThumbHovered(mouseX, mouseY)
|
||||
? Colors.mainColor.brighter()
|
||||
: Colors.mainColor;
|
||||
|
||||
if (dragging) thumbColor = Colors.mainColor.darker();
|
||||
|
||||
ctx.fill(trackX1 + 1, thumbY + 1, trackX2 - 1, thumbY + thumbHeight - 1, thumbColor.getRGB());
|
||||
}
|
||||
|
||||
public void mouseClicked(double mouseX, double mouseY, int button) {
|
||||
if (button != 0 || !ClientSettingsFrame.guiSettings.scrollBar.isEnabled()) return;
|
||||
if (isThumbHovered(mouseX, mouseY) && ClickGUI.INSTANCE.trySelect(this)) {
|
||||
dragging = true;
|
||||
dragY = (int) mouseY;
|
||||
scrollStart = scrollOffset;
|
||||
}
|
||||
}
|
||||
|
||||
public void mouseReleased(double mouseX, double mouseY, int button) {
|
||||
ClickGUI.INSTANCE.unselect(this);
|
||||
dragging = false;
|
||||
}
|
||||
|
||||
public void mouseDragged(double mouseY) {
|
||||
if (!dragging || !ClientSettingsFrame.guiSettings.scrollBar.isEnabled()) return;
|
||||
|
||||
int thumbHeight = getThumbHeight();
|
||||
int trackHeight = windowHeight - thumbHeight;
|
||||
|
||||
float ratio = (float) (contentHeight - windowHeight) / trackHeight;
|
||||
int deltaY = (int) mouseY - dragY;
|
||||
scrollOffset = scrollStart + (int) (deltaY * ratio);
|
||||
clampOffset();
|
||||
}
|
||||
|
||||
public void onMouseScroll(double amount) {
|
||||
if (contentHeight <= windowHeight) return;
|
||||
scrollOffset -= (int) amount * 20;
|
||||
clampOffset();
|
||||
}
|
||||
|
||||
private boolean isThumbHovered(double mouseX, double mouseY) {
|
||||
if (!ClickGUI.INSTANCE.canSelect(this)) return false;
|
||||
int trackX1 = mc.getWindow().getScaledWidth() - 10;
|
||||
int trackX2 = trackX1 + 10;
|
||||
int thumbY = getThumbY();
|
||||
int thumbHeight = getThumbHeight();
|
||||
return mouseX >= trackX1 && mouseX <= trackX2 && mouseY >= thumbY && mouseY <= thumbY + thumbHeight;
|
||||
}
|
||||
|
||||
private void clampOffset() {
|
||||
if (contentHeight <= windowHeight)
|
||||
scrollOffset = 0;
|
||||
else
|
||||
scrollOffset = Math.max(0, Math.min(contentHeight - windowHeight, scrollOffset));
|
||||
}
|
||||
|
||||
private int getThumbY() {
|
||||
int thumbHeight = getThumbHeight();
|
||||
float scrollProgress = (float) scrollOffset / (contentHeight - windowHeight);
|
||||
return (int) (scrollProgress * (windowHeight - thumbHeight));
|
||||
}
|
||||
|
||||
private int getThumbHeight() {
|
||||
float visibleRatio = (float) windowHeight / contentHeight;
|
||||
return Math.max(20, (int) (windowHeight * visibleRatio));
|
||||
}
|
||||
|
||||
public int getScrollOffset() {
|
||||
return scrollOffset;
|
||||
}
|
||||
|
||||
public void setContentHeight(int h) {
|
||||
this.contentHeight = h;
|
||||
clampOffset();
|
||||
}
|
||||
|
||||
public void setWindowHeight(int h) {
|
||||
this.windowHeight = h;
|
||||
clampOffset();
|
||||
}
|
||||
}
|
||||
@@ -1,52 +1,156 @@
|
||||
package me.retucio.camtweaks.ui.widgets;
|
||||
|
||||
import me.retucio.camtweaks.ui.ClickGUI;
|
||||
import me.retucio.camtweaks.ui.frames.ClientSettingsFrame;
|
||||
import me.retucio.camtweaks.util.ChatUtil;
|
||||
import me.retucio.camtweaks.util.Colors;
|
||||
import me.retucio.camtweaks.util.KeyUtil;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.font.TextRenderer;
|
||||
import net.minecraft.client.gl.RenderPipelines;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.client.gui.widget.TextFieldWidget;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.Formatting;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
public class SearchBarWidget extends TextFieldWidget {
|
||||
import java.awt.Color;
|
||||
|
||||
private static final Identifier MENU_LIST_BACKGROUND_TEXTURE = Identifier.ofVanilla("textures/gui/menu_list_background.png");
|
||||
private static final Identifier INWORLD_MENU_LIST_BACKGROUND_TEXTURE = Identifier.ofVanilla("textures/gui/inworld_menu_list_background.png");
|
||||
public class SearchBarWidget {
|
||||
|
||||
private boolean hookBackground;
|
||||
private boolean dragging;
|
||||
private int dragX, dragY;
|
||||
|
||||
public SearchBarWidget(TextRenderer textRenderer, int width, int height) {
|
||||
super(textRenderer, width, height, Text.empty());
|
||||
private int x, y;
|
||||
private final int w, h;
|
||||
private int renderY;
|
||||
|
||||
private boolean focused;
|
||||
private final StringBuilder buffer = new StringBuilder();
|
||||
|
||||
private final MinecraftClient mc = MinecraftClient.getInstance();
|
||||
|
||||
public SearchBarWidget(int x, int y, int w, int h) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.w = w;
|
||||
this.h = h;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderWidget(DrawContext context, int mouseX, int mouseY, float deltaTicks) {
|
||||
if (drawsBackground()) drawBackground(context);
|
||||
public void render(DrawContext ctx, double mouseX, double mouseY, float delta) {
|
||||
if (!ClientSettingsFrame.guiSettings.searchBar.isEnabled()) return;
|
||||
|
||||
hookBackground = true;
|
||||
super.renderWidget(context, mouseX, mouseY, deltaTicks);
|
||||
hookBackground = false;
|
||||
Color textFieldColor = isTextFieldHovered(mouseX, mouseY)
|
||||
? Colors.buttonColor.brighter()
|
||||
: Colors.buttonColor;
|
||||
|
||||
if (focused) textFieldColor = Colors.buttonColor.darker();
|
||||
|
||||
// bordes de la barra, para no obstruir la transparencia del campo de texto
|
||||
ctx.fill(x, renderY, x + 20, renderY + h, Colors.mainColor.getRGB());
|
||||
ctx.fill(x, renderY, x + w, renderY + 2, Colors.mainColor.getRGB());
|
||||
ctx.fill(x, renderY + h, x + w, renderY + h - 2, Colors.mainColor.getRGB());
|
||||
ctx.fill(x + w - 20, renderY, x + w, renderY + h, Colors.mainColor.getRGB());
|
||||
|
||||
ctx.fill(x + 20, renderY + 2, x + w - 20, renderY + h - 2, textFieldColor.getRGB());
|
||||
|
||||
// dibujar líneas en la parte agarrable, para indicárselo al usuario
|
||||
for (int i = 0; i < 4; i++)
|
||||
ctx.drawHorizontalLine(x + 4, x + 16, renderY + 3 * i + 5, Color.LIGHT_GRAY.getRGB());
|
||||
|
||||
// texto
|
||||
Text label = Text.literal(focused ? buffer + "_" : (buffer.isEmpty() ? Formatting.ITALIC + "buscar..." : buffer.toString()));
|
||||
ctx.drawText(mc.textRenderer, label,
|
||||
x + 24, renderY + h / 2 - mc.textRenderer.fontHeight / 2,
|
||||
(buffer.isEmpty() && !focused) ? Color.LIGHT_GRAY.getRGB() : -1, true);
|
||||
|
||||
// botón para borrar búsqueda actual
|
||||
ctx.drawText(mc.textRenderer, "×", x + w - mc.textRenderer.getWidth("×") - 6, renderY + (h / 2) - mc.textRenderer.fontHeight / 2,
|
||||
isClearButtonHovered(mouseX, mouseY) ? Color.RED.getRGB() : -1, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean drawsBackground() {
|
||||
if (hookBackground) return false;
|
||||
return super.drawsBackground();
|
||||
public void mouseClicked(double mouseX, double mouseY, int button) {
|
||||
if (button != 0 || !ClientSettingsFrame.guiSettings.searchBar.isEnabled()) return;
|
||||
if (isHandleHovered(mouseX, mouseY) && ClickGUI.INSTANCE.trySelect(this)) {
|
||||
dragging = true;
|
||||
dragX = (int) mouseX - x;
|
||||
dragY = (int) mouseY - y;
|
||||
} else if (isClearButtonHovered(mouseX, mouseY)) {
|
||||
buffer.setLength(0);
|
||||
}
|
||||
focused = isTextFieldHovered(mouseX, mouseY) && ClickGUI.INSTANCE.trySelect(this);
|
||||
}
|
||||
|
||||
private void drawBackground(DrawContext context) {
|
||||
Identifier identifier = MinecraftClient.getInstance().world == null ? MENU_LIST_BACKGROUND_TEXTURE : INWORLD_MENU_LIST_BACKGROUND_TEXTURE;
|
||||
context.drawTexture(
|
||||
RenderPipelines.GUI,
|
||||
identifier,
|
||||
this.getX(),
|
||||
this.getY(),
|
||||
this.getRight(),
|
||||
this.getBottom(),
|
||||
this.getWidth(),
|
||||
this.getHeight(),
|
||||
32,
|
||||
32
|
||||
);
|
||||
public void mouseReleased(double mouseX, double mouseY, int button) {
|
||||
if (!ClientSettingsFrame.guiSettings.searchBar.isEnabled()) return;
|
||||
ClickGUI.INSTANCE.unselect(this);
|
||||
if (button == 0 && dragging) dragging = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void onKey(int key, int action) {
|
||||
if (!ClientSettingsFrame.guiSettings.searchBar.isEnabled()) return;
|
||||
if (!focused || action == GLFW.GLFW_RELEASE) return;
|
||||
|
||||
switch (key) {
|
||||
case GLFW.GLFW_KEY_ENTER -> focused = false;
|
||||
case GLFW.GLFW_KEY_ESCAPE -> {
|
||||
buffer.setLength(0);
|
||||
focused = false;
|
||||
}
|
||||
case GLFW.GLFW_KEY_BACKSPACE -> onBackspace();
|
||||
default -> {
|
||||
String c = KeyUtil.getKeyName(key);
|
||||
if (c.length() == 1) {
|
||||
if (KeyUtil.isKeyDown(GLFW.GLFW_KEY_LEFT_SHIFT) || KeyUtil.isKeyDown(GLFW.GLFW_KEY_RIGHT_SHIFT))
|
||||
charTyped(KeyUtil.shiftKey(c).charAt(0));
|
||||
else
|
||||
charTyped(c.toLowerCase().charAt(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void onBackspace() {
|
||||
if (!buffer.isEmpty()) buffer.deleteCharAt(buffer.length() - 1);
|
||||
}
|
||||
|
||||
public void charTyped(char c) {
|
||||
if (!focused) return;
|
||||
buffer.append(c);
|
||||
if (mc.textRenderer.getWidth(buffer.toString()) > w - 30) onBackspace();
|
||||
}
|
||||
|
||||
public String getSearchInput() {
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
public boolean isHandleHovered(double mouseX, double mouseY) {
|
||||
return ClickGUI.INSTANCE.canSelect(this)
|
||||
&& mouseX > x && mouseX < x + 18
|
||||
&& mouseY > renderY && mouseY < renderY + h;
|
||||
}
|
||||
|
||||
public boolean isTextFieldHovered(double mouseX, double mouseY) {
|
||||
return ClickGUI.INSTANCE.canSelect(this)
|
||||
&& mouseX > x + 20 && mouseX < x + w - 20
|
||||
&& mouseY > renderY + 2 && mouseY < renderY + h - 2;
|
||||
}
|
||||
|
||||
public boolean isClearButtonHovered(double mouseX, double mouseY) {
|
||||
return ClickGUI.INSTANCE.canSelect(this)
|
||||
&& mouseX > x + w - 15 && mouseX < x + w - 3
|
||||
&& mouseY > renderY + 3 && mouseY < renderY + h - 5;
|
||||
}
|
||||
|
||||
public boolean isFocused() {
|
||||
return focused && ClientSettingsFrame.guiSettings.searchBar.isEnabled();
|
||||
}
|
||||
|
||||
public void updateRenderY(int scrollOffset) {
|
||||
renderY = y - scrollOffset;
|
||||
}
|
||||
|
||||
public void updatePosition(double mouseX, double mouseY) {
|
||||
if (dragging) {
|
||||
x = (int) (mouseX - dragX);
|
||||
y = (int) (mouseY - dragY);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,9 @@
|
||||
package me.retucio.camtweaks.util;
|
||||
|
||||
import me.retucio.camtweaks.ui.frames.ClickGUISettingsFrame;
|
||||
import me.retucio.camtweaks.CameraTweaks;
|
||||
import me.retucio.camtweaks.event.SubscribeEvent;
|
||||
import me.retucio.camtweaks.event.events.camtweaks.LoadModuleManagerEvent;
|
||||
import me.retucio.camtweaks.ui.frames.ClientSettingsFrame;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Formatting;
|
||||
@@ -9,15 +12,20 @@ import net.minecraft.util.Formatting;
|
||||
public class ChatUtil {
|
||||
|
||||
private static final MinecraftClient mc = MinecraftClient.getInstance();
|
||||
private static String prefix = Formatting.GREEN + "[" + ClickGUISettingsFrame.guiSettings.chatName.getValue() + "] ";
|
||||
private static String prefix = getDefaultPrefix();
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onLoadModuleManager(LoadModuleManagerEvent event) {
|
||||
prefix = Colors.getFormatting(Colors.mainColor) + "[" + ClientSettingsFrame.guiSettings.chatName.getValue() + "] ";
|
||||
}
|
||||
|
||||
|
||||
public static void addMessage(String text) {
|
||||
if (mc.inGameHud == null) return;
|
||||
mc.inGameHud.getChatHud().addMessage(Text.of(text));
|
||||
addMessage(Text.of(text));
|
||||
}
|
||||
|
||||
public static void addMessage(Text text) {
|
||||
if (mc.inGameHud == null) return;
|
||||
if (mc.inGameHud == null || !CameraTweaks.INSTANCE.settingsApplied) return;
|
||||
mc.inGameHud.getChatHud().addMessage(text);
|
||||
}
|
||||
|
||||
@@ -26,31 +34,31 @@ public class ChatUtil {
|
||||
}
|
||||
|
||||
public static void addMessageWithPrefix(Text text) {
|
||||
addMessage(Text.literal(prefix + Formatting.RESET).append(text));
|
||||
addMessage(Text.literal(getPrefix() + Formatting.RESET).append(text));
|
||||
}
|
||||
|
||||
public static void info(String text) {
|
||||
addMessage(Text.literal(prefix + Formatting.RESET + text));
|
||||
addMessage(Text.literal(getPrefix() + Formatting.RESET + text));
|
||||
}
|
||||
|
||||
public static void info(Text text) {
|
||||
addMessage(Text.literal(prefix + Formatting.RESET).append(text));
|
||||
addMessage(Text.literal(getPrefix() + Formatting.RESET).append(text));
|
||||
}
|
||||
|
||||
public static void warn(String text) {
|
||||
addMessage(Text.literal(prefix + Formatting.YELLOW + text));
|
||||
addMessage(Text.literal(getPrefix() + Formatting.YELLOW + text));
|
||||
}
|
||||
|
||||
public static void warn(Text text) {
|
||||
addMessage(Text.literal(prefix + Formatting.YELLOW).append(text));
|
||||
addMessage(Text.literal(getPrefix() + Formatting.YELLOW).append(text));
|
||||
}
|
||||
|
||||
public static void error(String text) {
|
||||
addMessage(Text.literal(prefix + Formatting.RED + text));
|
||||
addMessage(Text.literal(getPrefix() + Formatting.RED + text));
|
||||
}
|
||||
|
||||
public static void error(Text text) {
|
||||
addMessage(Text.literal(prefix + Formatting.RED).append(text));
|
||||
addMessage(Text.literal(getPrefix() + Formatting.RED).append(text));
|
||||
}
|
||||
|
||||
public static void sendServerMessage(String text) {
|
||||
@@ -66,11 +74,20 @@ public class ChatUtil {
|
||||
return prefix;
|
||||
}
|
||||
|
||||
public static String getPrefixNoFormatting() {
|
||||
return "[" + ClickGUISettingsFrame.guiSettings.chatName.getValue() + "] ";
|
||||
public static String getJustPrefix() {
|
||||
return ClientSettingsFrame.guiSettings.chatName.getValue();
|
||||
}
|
||||
|
||||
public static String getPrefixNoFormatting() {
|
||||
return getPrefix().split(Colors.getFormatting(Colors.mainColor).toString())[1];
|
||||
}
|
||||
|
||||
|
||||
public static void updatePrefix(String newPrefix) {
|
||||
prefix = Formatting.GREEN + "[" + newPrefix + "] ";
|
||||
prefix = Colors.getFormatting(Colors.mainColor) + "[" + newPrefix + "] ";
|
||||
}
|
||||
|
||||
public static String getDefaultPrefix() {
|
||||
return Colors.getFormatting(Colors.mainColor) + "[smegma] ";
|
||||
}
|
||||
}
|
||||
@@ -1,39 +1,76 @@
|
||||
package me.retucio.camtweaks.util;
|
||||
|
||||
import net.minecraft.util.Formatting;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
import static me.retucio.camtweaks.ui.frames.ClickGUISettingsFrame.guiSettings;
|
||||
import static me.retucio.camtweaks.ui.frames.ClientSettingsFrame.guiSettings;
|
||||
|
||||
|
||||
// clase para los colores, para no repetirme (regla DRY)
|
||||
// clase para los colores
|
||||
// si se ve especificado como color en algún lado "-1", significa blanco
|
||||
public class Colors {
|
||||
|
||||
public static int frameHeadRed = guiSettings.red.getIntValue();
|
||||
public static int frameHeadGreen = guiSettings.green.getIntValue();
|
||||
public static int frameHeadBlue = guiSettings.blue.getIntValue();
|
||||
public static int frameHeadAlpha = guiSettings.alpha.getIntValue();
|
||||
public static int red = guiSettings.red.getIntValue();
|
||||
public static int green = guiSettings.green.getIntValue();
|
||||
public static int blue = guiSettings.blue.getIntValue();
|
||||
public static int alpha = guiSettings.alpha.getIntValue();
|
||||
|
||||
public static int frameHeadColor = new Color(
|
||||
frameHeadRed,
|
||||
frameHeadGreen,
|
||||
frameHeadBlue,
|
||||
frameHeadAlpha
|
||||
).getRGB();
|
||||
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 enabledToggleButtonColor;
|
||||
public static Color disabledToggleButtonColor;
|
||||
|
||||
public static int frameBGColor = new Color(60, 60, 60, 70).getRGB();
|
||||
static {
|
||||
updateAllColors(new Color(red, green, blue, alpha));
|
||||
}
|
||||
|
||||
public static int enabledHoveredModuleButtonColor = new Color(20, 20, 255, 180).getRGB();
|
||||
public static int enabledModuleButtonColor = new Color(0, 0, 255, 180).getRGB();
|
||||
public static int hoveredModuleButtonColor = new Color(30, 30, 30, 100).getRGB();
|
||||
public static int moduleButtonColor = new Color(40, 40, 40, 75).getRGB();
|
||||
public static void updateAllColors(Color color) {
|
||||
mainColor = color;
|
||||
enabledToggleButtonColor = mixWithMainColor(new Color(10, 150, 10), 0.8f);
|
||||
disabledToggleButtonColor = mixWithMainColor(new Color(150, 10, 10), 0.8f);
|
||||
|
||||
public static int hoveredSettingButtonColor = new Color(30, 30, 30, 100).getRGB();
|
||||
public static int settingButtonColor = new Color(40, 40, 40, 75).getRGB();
|
||||
public static int sliderFillingColor = new Color(60, 120, 220, 180).getRGB();
|
||||
ChatUtil.updatePrefix(ChatUtil.getJustPrefix());
|
||||
}
|
||||
|
||||
// necesitan ser de tipo java.awt.Color para utilizar el método .brighter()
|
||||
public static Color enabledToggleButtonColor = new Color(0, 180, 0, 180);
|
||||
public static Color disabledToggleButtonColor = new Color(120, 30, 30, 150);
|
||||
public static Color mixWithMainColor(Color color, float ratio) {
|
||||
return mix(mainColor, color, ratio);
|
||||
}
|
||||
|
||||
public static Color mix(Color c1, Color c2, float ratio) {
|
||||
float r = c1.getRed() * (1 - ratio) + c2.getRed() * ratio;
|
||||
float g = c1.getGreen() * (1 - ratio) + c2.getGreen() * ratio;
|
||||
float b = c1.getBlue() * (1 - ratio) + c2.getBlue() * ratio;
|
||||
return new Color((int) r, (int) g, (int) b, alpha);
|
||||
}
|
||||
|
||||
public static Formatting getFormatting(Color color) {
|
||||
return nearest(color);
|
||||
}
|
||||
|
||||
public static Formatting nearest(Color input) {
|
||||
Formatting nearest = null;
|
||||
double minDistance = Double.MAX_VALUE;
|
||||
|
||||
for (Formatting formatting : Formatting.values()) {
|
||||
if (formatting.getColorValue() == null) continue; // saltarse los modificadores
|
||||
|
||||
Color candidate = new Color(formatting.getColorValue());
|
||||
double dist = colorDistance(input, candidate);
|
||||
|
||||
if (dist < minDistance) {
|
||||
minDistance = dist;
|
||||
nearest = formatting;
|
||||
}
|
||||
}
|
||||
return nearest;
|
||||
}
|
||||
|
||||
private static double colorDistance(Color c1, Color c2) {
|
||||
int rDiff = c1.getRed() - c2.getRed();
|
||||
int gDiff = c1.getGreen() - c2.getGreen();
|
||||
int bDiff = c1.getBlue() - c2.getBlue();
|
||||
return rDiff * rDiff + gDiff * gDiff + bDiff * bDiff;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package me.retucio.camtweaks.util;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.client.particle.Particle;
|
||||
import net.minecraft.client.resource.language.I18n;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.particle.ParticleType;
|
||||
import net.minecraft.particle.ParticleTypes;
|
||||
import net.minecraft.registry.Registries;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static me.retucio.camtweaks.CameraTweaks.mc;
|
||||
|
||||
public class Lists {
|
||||
|
||||
public static final List<EntityType<?>> entityList = Registries.ENTITY_TYPE.stream().toList();
|
||||
public static Map<EntityType<?>, String> entityNames;
|
||||
|
||||
|
||||
public static final List<ParticleType<?>> particleList = Registries.PARTICLE_TYPE.stream().toList();
|
||||
public static Map<ParticleType<?>, String> particleNames;
|
||||
|
||||
public static final List<Block> blockList = Registries.BLOCK.stream().toList();
|
||||
|
||||
public static void init() {
|
||||
// no consigo traducir el texto. a tomar por culo, se queda en inglés, si no entiendes pues a estudiar
|
||||
entityNames = getMapOfLists(entityList,
|
||||
entityList.stream().map(entity -> I18n.translate(entity.getTranslationKey())).toList());
|
||||
|
||||
// no hay traducciones para nombres de partículas, y paso de hacerlas yo
|
||||
particleNames = getMapOfLists(particleList,
|
||||
particleList.stream().map(particle -> Registries.PARTICLE_TYPE.getId(particle).toShortTranslationKey()).toList());
|
||||
}
|
||||
|
||||
public static <T> Map<T, Boolean> allTrue(List<T> options) {
|
||||
Map<T, Boolean> map = new HashMap<>();
|
||||
for (T option : options) map.put(option, true);
|
||||
return map;
|
||||
}
|
||||
|
||||
public static <T> Map<T, Boolean> allFalse(List<T> options) {
|
||||
Map<T, Boolean> map = new HashMap<>();
|
||||
for (T option : options) map.put(option, false);
|
||||
return map;
|
||||
}
|
||||
|
||||
public static <T> Map<T, String> getMapOfLists(List<T> options, List<String> names) {
|
||||
Map<T, String> result = new HashMap<>();
|
||||
|
||||
// no exceder los límites de ninguna de las dos listas
|
||||
int size = Math.min(options.size(), names.size());
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
result.put(options.get(i), names.get(i));
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,13 @@
|
||||
package me.retucio.camtweaks.util.interfaces;
|
||||
|
||||
import net.minecraft.client.gui.hud.ChatHudLine;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface IChatHud {
|
||||
|
||||
void smegma$add(Text message, int id);
|
||||
|
||||
List<ChatHudLine.Visible> smegma$getVisibleMessages();
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
accessWidener v2 named
|
||||
|
||||
accessible class net/minecraft/client/font/TextRenderer$Drawer
|
||||
|
||||
accessible field net/minecraft/client/particle/Particle alpha F
|
||||
accessible field net/minecraft/client/particle/BillboardParticle scale F
|
||||
accessible field net/minecraft/client/particle/Particle velocityMultiplier F
|
||||
accessible field net/minecraft/client/particle/Particle gravityStrength F
|
||||
accessible field net/minecraft/client/particle/Particle collidesWithWorld Z
|
||||
@@ -5,6 +5,7 @@
|
||||
"mixins": [
|
||||
"ClientConnectionMixin",
|
||||
"DimensionTypeMixin",
|
||||
"EntityEffectParticleEffectMixin",
|
||||
"EntityMixin",
|
||||
"ItemEntityMixin",
|
||||
"KeyInputMixin",
|
||||
@@ -29,25 +30,34 @@
|
||||
"ChatScreenMixin",
|
||||
"ChunkBorderDebugRendererMixin",
|
||||
"ChunkOcclusionDataBuilderMixin",
|
||||
"ClientPlayerInteractionManagerMixin",
|
||||
"ClientPlayNetworkHandlerMixin",
|
||||
"ClientWorldPropertiesMixin",
|
||||
"CompassStateMixin",
|
||||
"EntityRendererMixin",
|
||||
"DamageParticleFactoryMixin",
|
||||
"DamageParticleMixin",
|
||||
"FogRendererMixin",
|
||||
"GameOptionsMixin",
|
||||
"GameRendererMixin",
|
||||
"HeldItemRendererMixin",
|
||||
"InGameHudMixin",
|
||||
"InGameOverlayRendererMixin",
|
||||
"KeyboardMixin",
|
||||
"LightmapTextureManagerMixin",
|
||||
"LivingEntityRendererMixin",
|
||||
"MessageHandlerMixin",
|
||||
"MinecraftClientMixin",
|
||||
"MouseMixin",
|
||||
"OverlayTextureMixin",
|
||||
"ParticleManagerMixin",
|
||||
"ScreenMixin",
|
||||
"ScreenshotRecorderMixin",
|
||||
"SkyRendererMixin",
|
||||
"StuckArrowsFeatureRendererMixin",
|
||||
"TextRendererDrawerMixin",
|
||||
"WeatherRenderingMixin",
|
||||
"WorldRendererMixin",
|
||||
"accessor.ClientPlayNetworkHandlerAccessor",
|
||||
"accessor.EntityRenderStateAccessor",
|
||||
"accessor.KeyBindingAccessor"
|
||||
]
|
||||
}
|
||||
@@ -23,6 +23,7 @@
|
||||
"mixins": [
|
||||
"camtweaks.mixins.json"
|
||||
],
|
||||
"accessWidener": "camtweaks.accesswidener",
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.14",
|
||||
"minecraft": "~1.21.6",
|
||||
|
||||