Compare commits

...
2 Commits
Author SHA1 Message Date
retuci0 a9cf6dd924 v1.9.1 2025-12-28 00:58:08 +01:00
retuci0 8e44dda9cf v1.9 2025-12-26 22:45:43 +01:00
104 changed files with 2501 additions and 432 deletions

No files matched your search

+2 -17
View File
@@ -1,30 +1,15 @@
# v1.7 # v1.9.1
## novedades ## novedades
- ARREGLADO EL SELECTOR DE COLORES
### adiciones ### adiciones
- comando `$echest` (o `$ec` si eres un puto vago) para previsualizar los contenidos del enderchest en cualquier momento
- se ha añadido un gradiente negro leve en la parte inferior del clickgui si el contenido excede los límites de la pantalla, para indicarlo visualmente
#### módulos nuevos: #### módulos nuevos:
- aviso de baja durabilidad: te avisa cuando un ítem llega a cierto porcentaje de durabilidad
- bypassear packs: te permite omitir packs de recursos forzados por el servidor, al establecer el modo en "preguntar" y seleccionar la opción "nuh uh"
- destello de enchants.: modifica el color del destello de los items y armadura encantada
### arreglos / mejoras ### arreglos / mejoras
- ahora puedes volver a abrir el clickgui y el editor de hud en la pantalla de inicio
- ya no se deja de renderizar el hud si algún modo de debug (chunks, hitboxes, etc.) está activado y "mostar en F3" está desactivado
- ahora se pueden previsualizar enderchests igual que shulkers, desde el inventario (prev. de shulkers)
- ahora el mod funciona al compilarlo tras clonarlo por github, ya que había gitignorado algunos archivos importantes jsajajs
- arreglados los problemas del módulo zoom (creo)
- arregladas las opciones de ceguera y oscuridad de norender
- el color de la interfaz ya no es negro en el primer launch o cuando no se ha generado el archivo de config todavía
- arreglado el problema donde se muestra la marca de agua por defecto en la pantalla de inicio si no se abre un mundo primero
## problemas reconocidos ## problemas reconocidos
- muchos, pero repórtalos en la página de problemas si quieres para que queden bien registrados - muchos, pero repórtalos en la página de problemas si quieres para que queden bien registrados
+1 -1
View File
@@ -6,7 +6,7 @@ yarn_mappings=1.21.10+build.2
loader_version=0.17.3 loader_version=0.17.3
loom_version=1.11-SNAPSHOT loom_version=1.11-SNAPSHOT
mod_version=1.8 mod_version=1.9
maven_group=me.retucio maven_group=me.retucio
archives_base_name=camtweaks archives_base_name=camtweaks
@@ -80,9 +80,10 @@ public class CameraTweaks implements ClientModInitializer {
ConfigManager.load(); ConfigManager.load();
EVENT_BUS.register(this); EVENT_BUS.register(this);
EVENT_BUS.register(new HudRenderer());
EVENT_BUS.register(MiscUtil.class); EVENT_BUS.register(MiscUtil.class);
EVENT_BUS.register(ChatUtil.class); EVENT_BUS.register(ChatUtil.class);
EVENT_BUS.register(HudRenderer.class);
Lists.init(); Lists.init();
@@ -186,7 +187,12 @@ public class CameraTweaks implements ClientModInitializer {
// manejar la lógica de apertura del editor de elementos del hud, con la misma lógica que handleClickGUIKey() // manejar la lógica de apertura del editor de elementos del hud, con la misma lógica que handleClickGUIKey()
private void handleHudEditorKey(int key, boolean anyFocused) { private void handleHudEditorKey(int key, boolean anyFocused) {
if (key != ModuleManager.INSTANCE.getModuleByClass(HUD.class).editorKey.getKey() || anyFocused) return; HUD hud = ModuleManager.INSTANCE.getModuleByClass(HUD.class);
if (key != hud.editorKey.getKey() || anyFocused) return;
if (!hud.isEnabled()) {
ChatUtil.warn("HUD está desactivado, lumbreras");
return;
}
if (mc.currentScreen != HudEditorScreen.INSTANCE) { if (mc.currentScreen != HudEditorScreen.INSTANCE) {
prevScreen = mc.currentScreen; prevScreen = mc.currentScreen;
@@ -41,6 +41,7 @@ public class CommandManager {
addCommand(new PurgeCommand()); addCommand(new PurgeCommand());
addCommand(new SaveScreenshotCommand()); addCommand(new SaveScreenshotCommand());
addCommand(new SendCommand()); addCommand(new SendCommand());
addCommand(new SpectateCommand());
addCommand(new ToggleCommand()); addCommand(new ToggleCommand());
commands.sort(Comparator.comparing(Command::getName)); commands.sort(Comparator.comparing(Command::getName));
@@ -0,0 +1,208 @@
package me.retucio.camtweaks.command.args;
import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.arguments.ArgumentType;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.exceptions.DynamicCommandExceptionType;
import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import me.retucio.camtweaks.util.MiscUtil;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.text.Text;
import javax.swing.*;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.regex.Pattern;
// para autocompletar entidades
import static me.retucio.camtweaks.CameraTweaks.mc;
public class EntityArgumentType implements ArgumentType<Entity> {
public static final EntityArgumentType INSTANCE = new EntityArgumentType();
private static final DynamicCommandExceptionType NO_SUCH_ENTITY = new DynamicCommandExceptionType(
name -> Text.literal("Entidad \"" + name + "\" no encontrada"));
private static final Collection<String> EXAMPLES = List.of(
"AdlerHitdolf",
"@p"
);
private static final Pattern UUID_PATTERN = Pattern.compile(
"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"
);
private EntityArgumentType() {}
@Override
public Entity parse(StringReader reader) throws CommandSyntaxException {
String argument = reader.readString();
if (mc.world == null)
throw NO_SUCH_ENTITY.create(argument);
if (argument.startsWith("@"))
return parseSelector(argument);
if (isUUID(argument)) {
UUID uuid = UUID.fromString(argument);
return findEntityByUUID(uuid);
}
return findPlayerByName(argument);
}
private boolean isUUID(String input) {
return UUID_PATTERN.matcher(input).matches();
}
private Entity parseSelector(String selector) throws CommandSyntaxException {
if (mc.player == null) throw NO_SUCH_ENTITY.create(selector);
return switch (selector.toLowerCase()) {
case "@p" ->
findNearestPlayer();
case "@r" ->
findRandomPlayer();
case "@s" ->
mc.player;
case "@a" -> throw CommandSyntaxException.BUILT_IN_EXCEPTIONS.dispatcherUnknownArgument()
.createWithContext(new StringReader(selector));
default -> {
if (selector.startsWith("@e"))
yield parseEntitySelector(selector);
else if (selector.startsWith("@p") && selector.length() > 2)
yield parsePlayerSelector(selector);
throw NO_SUCH_ENTITY.create(selector);
}
};
}
private Entity findNearestPlayer() throws CommandSyntaxException {
PlayerEntity nearest = null;
double nearestDistance = Double.MAX_VALUE;
for (PlayerEntity player : mc.world.getPlayers()) {
if (player == mc.player) continue;
double distance = mc.player.squaredDistanceTo(player);
if (distance < nearestDistance) {
nearestDistance = distance;
nearest = player;
}
}
if (nearest == null)
throw NO_SUCH_ENTITY.create("@p");
return nearest;
}
private Entity findRandomPlayer() throws CommandSyntaxException {
List<PlayerEntity> players = new ArrayList<>(mc.world.getPlayers());
if (players.isEmpty()) throw NO_SUCH_ENTITY.create("@r");
players.remove(mc.player);
if (players.isEmpty()) return mc.player;
Random random = new Random();
return players.get(random.nextInt(players.size()));
}
private Entity parseEntitySelector(String selector) throws CommandSyntaxException {
if (selector.equals("@e")) {
List<Entity> entities = new ArrayList<>();
for (Entity entity : mc.world.getEntities())
if (!(entity instanceof PlayerEntity))
entities.add(entity);
if (entities.isEmpty()) throw NO_SUCH_ENTITY.create(selector);
Random random = new Random();
return entities.get(random.nextInt(entities.size()));
}
if (selector.startsWith("@e[type=")) {
String type = selector.substring(8, selector.length() - 1);
return findEntityByType(type);
}
throw NO_SUCH_ENTITY.create(selector);
}
private Entity parsePlayerSelector(String selector) throws CommandSyntaxException {
return findNearestPlayer();
}
private Entity findEntityByType(String type) throws CommandSyntaxException {
List<Entity> matchingEntities = new ArrayList<>();
for (Entity entity : mc.world.getEntities()) {
String entityType = entity.getType().getTranslationKey();
if (entityType.contains(type.toLowerCase().replace("minecraft:", "")))
matchingEntities.add(entity);
}
if (matchingEntities.isEmpty()) throw NO_SUCH_ENTITY.create(type);
Entity nearest = null;
double nearestDistance = Double.MAX_VALUE;
for (Entity entity : matchingEntities) {
double distance = mc.player.squaredDistanceTo(entity);
if (distance < nearestDistance) {
nearestDistance = distance;
nearest = entity;
}
}
return nearest;
}
private Entity findEntityByUUID(UUID uuid) throws CommandSyntaxException {
for (Entity entity : mc.world.getEntities())
if (entity.getUuid().equals(uuid))
return entity;
throw NO_SUCH_ENTITY.create(uuid.toString());
}
private PlayerEntity findPlayerByName(String name) throws CommandSyntaxException {
for (PlayerEntity player : mc.world.getPlayers())
if (player.getName().getString().equalsIgnoreCase(name))
return player;
throw NO_SUCH_ENTITY.create(name);
}
@Override
public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder) {
if (mc.world != null)
for (PlayerEntity player : mc.world.getPlayers())
builder.suggest(player.getName().getString());
builder.suggest("@p");
builder.suggest("@r");
builder.suggest("@s");
Entity lookingAt = MiscUtil.getEntityPlayerIsLookingAt();
if (lookingAt != null)
builder.suggest(lookingAt.getUuid().toString());
return builder.buildFuture();
}
@Override
public Collection<String> getExamples() {
return EXAMPLES;
}
public static Entity get(CommandContext<?> context, String name) {
return context.getArgument(name, Entity.class);
}
}
@@ -19,7 +19,7 @@ import java.util.concurrent.CompletableFuture;
public class ModuleArgumentType implements ArgumentType<Module> { public class ModuleArgumentType implements ArgumentType<Module> {
public static final ModuleArgumentType INSTANCE = new ModuleArgumentType(); public static final ModuleArgumentType INSTANCE = new ModuleArgumentType();
private static final DynamicCommandExceptionType unknownModuleE = new DynamicCommandExceptionType( private static final DynamicCommandExceptionType UNKNOWN_MODULE = new DynamicCommandExceptionType(
name -> Text.literal("módulo \"" + name + "\" no encontrado")); name -> Text.literal("módulo \"" + name + "\" no encontrado"));
private static final Collection<String> examples = ModuleManager.INSTANCE.getModules() private static final Collection<String> examples = ModuleManager.INSTANCE.getModules()
@@ -29,7 +29,7 @@ public class ModuleArgumentType implements ArgumentType<Module> {
public Module parse(StringReader reader) throws CommandSyntaxException { public Module parse(StringReader reader) throws CommandSyntaxException {
String argument = reader.readString().replace("_", " "); String argument = reader.readString().replace("_", " ");
Module module = ModuleManager.INSTANCE.getModuleByName(argument); Module module = ModuleManager.INSTANCE.getModuleByName(argument);
if (module == null) throw unknownModuleE.create(argument); if (module == null) throw UNKNOWN_MODULE.create(argument);
return module; return module;
} }
@@ -45,7 +45,8 @@ public class PlayerArgumentType implements ArgumentType<PlayerEntity> {
@Override @Override
public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder) { public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder) {
return CommandSource.suggestMatching(mc.world.getPlayers().stream().map(abstractClientPlayerEntity -> abstractClientPlayerEntity.getName().getString()), builder); return CommandSource.suggestMatching(mc.world.getPlayers().stream().map(
abstractClientPlayerEntity -> abstractClientPlayerEntity.getName().getString()), builder);
} }
@Override @Override
@@ -42,8 +42,7 @@ public class BindCommand extends Command {
public static boolean onKeyPress(int key) { public static boolean onKeyPress(int key) {
if (listeningModule == null) return false; if (listeningModule == null) return false;
KeySetting bind = listeningModule.getBind(); KeySetting bind = listeningModule.getBind();
if (bind != null) if (bind != null) bind.setKey(key);
bind.setKey(key);
ChatUtil.info( ChatUtil.info(
Text.of("la tecla " + Formatting.AQUA + KeyUtil.getKeyName(key) + Formatting.RESET + Text.of("la tecla " + Formatting.AQUA + KeyUtil.getKeyName(key) + Formatting.RESET +
@@ -49,7 +49,7 @@ public class EnderChestCommand extends Command {
} }
@SubscribeEvent @SubscribeEvent
public void tickEvent(TickEvent.Post event) { public void onTick(TickEvent.Post event) {
if (shouldOpenEchest) { if (shouldOpenEchest) {
shouldOpenEchest = false; shouldOpenEchest = false;
if (MiscUtil.getEchestInv() != null) if (MiscUtil.getEchestInv() != null)
@@ -9,14 +9,14 @@ import net.minecraft.text.Text;
public class GarbageCleanerCommand extends Command { public class GarbageCleanerCommand extends Command {
public GarbageCleanerCommand() { public GarbageCleanerCommand() {
super("cleanram", "limpia la ram mediante el recolector de basura (gc)", "gc", "garbagecollect"); super("gc", "limpia la ram mediante el recolector de basura (gc)", "garbagecollect");
} }
@Override @Override
public void build(LiteralArgumentBuilder<CommandSource> builder) { public void build(LiteralArgumentBuilder<CommandSource> builder) {
builder.executes(context -> { builder.executes(context -> {
System.gc(); System.gc();
ChatUtil.info(Text.of("ram limpiada")); ChatUtil.info(Text.of("basura recolectada"));
return SUCCESS; return SUCCESS;
}); });
} }
@@ -0,0 +1,49 @@
package me.retucio.camtweaks.command.commands;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import me.retucio.camtweaks.command.Command;
import me.retucio.camtweaks.command.args.EntityArgumentType;
import me.retucio.camtweaks.event.SubscribeEvent;
import me.retucio.camtweaks.event.events.KeyEvent;
import me.retucio.camtweaks.util.MiscUtil;
import net.minecraft.command.CommandSource;
import net.minecraft.entity.Entity;
import org.lwjgl.glfw.GLFW;
public class SpectateCommand extends Command {
public SpectateCommand() {
super("espectar", "te permite adquirir el punto de vista de una entidad", "spectate", "spec");
}
@Override
public void build(LiteralArgumentBuilder<CommandSource> builder) {
builder
.executes(ctx -> { // If no argument, use the entity player is looking at
mc.execute(() -> {
Entity target = MiscUtil.getEntityPlayerIsLookingAt();
if (target != null)
mc.setCameraEntity(target);
});
return SUCCESS;
})
.then(argument("entidad", EntityArgumentType.INSTANCE)
.executes(ctx -> {
Entity entity = EntityArgumentType.get(ctx, "entidad");
if (mc.player != null && entity != null) {
mc.setCameraEntity(entity);
}
return SUCCESS;
})
);
}
@SubscribeEvent
public void onKey(KeyEvent event) {
if (mc.getCameraEntity() != mc.player && mc.currentScreen == null
&& event.getKey() == GLFW.GLFW_KEY_ESCAPE && event.getAction() != GLFW.GLFW_RELEASE ) {
event.cancel();
mc.setCameraEntity(mc.player);
}
}
}
@@ -32,6 +32,9 @@ public class ClientConfig {
// id del elemento del hud -> true: visible / false: no visible // id del elemento del hud -> true: visible / false: no visible
public Map<String, Boolean> hudVisibilities = new HashMap<>(); public Map<String, Boolean> hudVisibilities = new HashMap<>();
// posición de la barra de búsqueda (x, y)
public int[] searchBarPosition = new int[]{340, 16};
public ClientConfig() { public ClientConfig() {
EVENT_BUS.register(this); EVENT_BUS.register(this);
} }
@@ -55,6 +58,7 @@ public class ClientConfig {
case NumberSetting n: value = n.getValue(); break; case NumberSetting n: value = n.getValue(); break;
case StringSetting s: value = s.getValue(); break; case StringSetting s: value = s.getValue(); break;
case ListSetting l: value = l.getValues(); break; case ListSetting l: value = l.getValues(); break;
case ColorSetting c: value = c.getConfigValue(); break;
default: break; default: break;
} }
@@ -72,6 +72,11 @@ public class ConfigManager {
} }
}); });
if (config.searchBarPosition != null && config.searchBarPosition.length == 2) {
ClickGUI.INSTANCE.getSearchBar().setX(config.searchBarPosition[0]);
ClickGUI.INSTANCE.getSearchBar().setY(config.searchBarPosition[1]);
}
ClientSettingsFrame.guiSettings.setEnabled(true); ClientSettingsFrame.guiSettings.setEnabled(true);
ClientSettingsFrame.guiSettings.getSettings().forEach(setting -> applySetting(ClientSettingsFrame.guiSettings, setting)); ClientSettingsFrame.guiSettings.getSettings().forEach(setting -> applySetting(ClientSettingsFrame.guiSettings, setting));
@@ -138,6 +143,12 @@ public class ConfigManager {
save(); save();
} }
public static void setSearchBarPosition(int x, int y) {
ensureConfig();
config.searchBarPosition = new int[]{x, y};
save();
}
@SuppressWarnings({"rawtypes", "unchecked"}) @SuppressWarnings({"rawtypes", "unchecked"})
public static void applySetting(Module parent, AbstractSetting setting) { public static void applySetting(Module parent, AbstractSetting setting) {
@@ -161,7 +172,27 @@ public class ConfigManager {
} }
l.setValues(converted); l.setValues(converted);
} }
} default -> {} } case ColorSetting c -> {
if (value instanceof Map<?, ?> map) {
Number r = (Number) map.get("r");
Number g = (Number) map.get("g");
Number b = (Number) map.get("b");
Number a = (Number) map.get("a");
Boolean rainbow = (Boolean) map.get("rb");
Number rainbowSpeed = (Number) map.get("rs");
Number saturation = (Number) map.get("sat");
Number brightness = (Number) map.get("bri");
if (r != null && g != null && b != null && a != null)
c.setRGB(r.intValue(), g.intValue(), b.intValue(), a.intValue());
if (rainbow != null) c.setRainbow(rainbow);
if (rainbowSpeed != null) c.setRainbowSpeed(rainbowSpeed.intValue());
if (saturation != null) c.setSaturation(saturation.floatValue());
if (brightness != null) c.setBrightness(brightness.floatValue());
}
}
default -> {}
} }
} }
} }
@@ -2,6 +2,7 @@ package me.retucio.camtweaks.event;
// evento base, cancelable (usado en mixins) // evento base, cancelable (usado en mixins)
public class Event { public class Event {
private boolean cancelled; private boolean cancelled;
public boolean isCancelled() { public boolean isCancelled() {
@@ -6,6 +6,7 @@ import java.util.*;
// al llamar un evento, se guarda en el bus de eventos, de donde luego se puede detectar si ese evento ha sucedido // al llamar un evento, se guarda en el bus de eventos, de donde luego se puede detectar si ese evento ha sucedido
public class EventBus { public class EventBus {
private final Map<Class<?>, List<ListenerMethod>> listeners = new HashMap<>(); private final Map<Class<?>, List<ListenerMethod>> listeners = new HashMap<>();
private record ListenerMethod(Object instance, Method method) {} private record ListenerMethod(Object instance, Method method) {}
@@ -1,8 +1,12 @@
package me.retucio.camtweaks.event.events.camtweaks; package me.retucio.camtweaks.event.events;
import me.retucio.camtweaks.event.Event; import me.retucio.camtweaks.event.Event;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
/**
* @see me.retucio.camtweaks.mixin.ClientWorldMixin#onAddEntity
*/
public class AddEntityEvent extends Event { public class AddEntityEvent extends Event {
private final Entity entity; private final Entity entity;
@@ -3,6 +3,10 @@ package me.retucio.camtweaks.event.events;
import me.retucio.camtweaks.event.Event; import me.retucio.camtweaks.event.Event;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
/**
* @see me.retucio.camtweaks.mixin.ClientPlayerInteractionManagerMixin#onAttackEntity
*/
public class AttackEntityEvent extends Event { public class AttackEntityEvent extends Event {
private final Entity entity; private final Entity entity;
@@ -3,6 +3,10 @@ package me.retucio.camtweaks.event.events;
import me.retucio.camtweaks.event.Event; import me.retucio.camtweaks.event.Event;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
/**
* @see me.retucio.camtweaks.mixin.ClientPlayerInteractionManagerMixin#onBlockBreak
*/
public class BreakBlockEvent extends Event { public class BreakBlockEvent extends Event {
private BlockPos pos; private BlockPos pos;
@@ -2,6 +2,12 @@ package me.retucio.camtweaks.event.events;
import me.retucio.camtweaks.event.Event; import me.retucio.camtweaks.event.Event;
/**
* @see me.retucio.camtweaks.mixin.EntityMixin#onRotation
* @see me.retucio.camtweaks.mixin.EntityMixin#onChangeYaw
* @see me.retucio.camtweaks.mixin.EntityMixin#onChangePitch
*/
public class ChangeRotationEvent extends Event { public class ChangeRotationEvent extends Event {
private float yaw; private float yaw;
@@ -2,8 +2,8 @@ package me.retucio.camtweaks.event.events;
import me.retucio.camtweaks.event.Event; import me.retucio.camtweaks.event.Event;
/** /**
* @see me.retucio.camtweaks.mixin.ChunkOcclusionDataBuilderMixin#onChunkOcclusion * @see me.retucio.camtweaks.mixin.ChunkOcclusionDataBuilderMixin#onChunkOcclusion
*/ */
public class ChunkOcclusionEvent extends Event {} public class ChunkOcclusionEvent extends Event {}
@@ -2,10 +2,10 @@ package me.retucio.camtweaks.event.events;
import net.minecraft.text.ClickEvent; import net.minecraft.text.ClickEvent;
/** este evento es solo para asegurarse de que comandos del mod se puedan ejecutar solo desde el lado del cliente /** este evento es solo para asegurarse de que comandos del mod se puedan ejecutar solo desde el lado del cliente
* @see me.retucio.camtweaks.module.modules.ChatPlus#getSendButton * @see me.retucio.camtweaks.module.modules.ChatPlus#getSendButton
*/ */
public class ClientClickEvent implements ClickEvent { public class ClientClickEvent implements ClickEvent {
private final String value; private final String value;
@@ -3,6 +3,10 @@ package me.retucio.camtweaks.event.events;
import me.retucio.camtweaks.event.Event; import me.retucio.camtweaks.event.Event;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
/**
* @see me.retucio.camtweaks.mixin.ItemStackMixin#onDamage
*/
public class DamageItemEvent extends Event { public class DamageItemEvent extends Event {
private final int amount; private final int amount;
@@ -1,9 +1,28 @@
package me.retucio.camtweaks.event.events; package me.retucio.camtweaks.event.events;
import me.retucio.camtweaks.event.Event; import me.retucio.camtweaks.event.Event;
import net.minecraft.client.network.ServerInfo;
import net.minecraft.network.DisconnectionInfo;
/** /**
* @see me.retucio.camtweaks.mixin.ClientConnectionMixin#onDisconnect * @see me.retucio.camtweaks.mixin.ClientConnectionMixin#onDisconnect
*/ */
public class DisconnectEvent extends Event {
public class DisconnectEvent extends Event {} private final DisconnectionInfo info;
private final ServerInfo server;
public DisconnectEvent(DisconnectionInfo info, ServerInfo server) {
this.info = info;
this.server = server;
}
public DisconnectionInfo getInfo() {
return info;
}
public ServerInfo getServer() {
return server;
}
}
@@ -2,10 +2,10 @@ package me.retucio.camtweaks.event.events;
import me.retucio.camtweaks.event.Event; import me.retucio.camtweaks.event.Event;
/** /**
* @see me.retucio.camtweaks.mixin.GameRendererMixin#modifyFov * @see me.retucio.camtweaks.mixin.GameRendererMixin#modifyFov
*/ */
public class GetFOVEvent extends Event { public class GetFOVEvent extends Event {
private float fov; private float fov;
@@ -2,9 +2,12 @@ package me.retucio.camtweaks.event.events;
import me.retucio.camtweaks.event.Event; import me.retucio.camtweaks.event.Event;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
/**
* @see me.retucio.camtweaks.mixin.ClientPlayerInteractionManagerMixin#onEntityInteract
*/
public class InteractEntityEvent extends Event { public class InteractEntityEvent extends Event {
private final Entity entity; private final Entity entity;
@@ -2,10 +2,10 @@ package me.retucio.camtweaks.event.events;
import me.retucio.camtweaks.event.Event; import me.retucio.camtweaks.event.Event;
/** /**
* @see me.retucio.camtweaks.mixin.KeyboardMixin#onKeyPress * @see me.retucio.camtweaks.mixin.KeyboardMixin#onKeyPress
*/ */
public class KeyEvent extends Event { public class KeyEvent extends Event {
private final int key, scancode, action; private final int key, scancode, action;
@@ -2,10 +2,10 @@ package me.retucio.camtweaks.event.events;
import me.retucio.camtweaks.event.Event; import me.retucio.camtweaks.event.Event;
/** /**
* @see me.retucio.camtweaks.mixin.MouseMixin#onMouseButton * @see me.retucio.camtweaks.mixin.MouseMixin#onMouseButton
*/ */
public class MouseClickEvent extends Event { public class MouseClickEvent extends Event {
private final int action, button; private final int action, button;
@@ -2,10 +2,10 @@ package me.retucio.camtweaks.event.events;
import me.retucio.camtweaks.event.Event; import me.retucio.camtweaks.event.Event;
/** /**
* @see me.retucio.camtweaks.mixin.MouseMixin#onMouseScroll * @see me.retucio.camtweaks.mixin.MouseMixin#onMouseScroll
*/ */
public class MouseScrollEvent extends Event { public class MouseScrollEvent extends Event {
private double horizontal, vertical; private double horizontal, vertical;
@@ -3,10 +3,10 @@ package me.retucio.camtweaks.event.events;
import me.retucio.camtweaks.event.Event; import me.retucio.camtweaks.event.Event;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
/** /**
* @see me.retucio.camtweaks.mixin.MinecraftClientMixin#onOpenScreen * @see me.retucio.camtweaks.mixin.MinecraftClientMixin#onOpenScreen
*/ */
public class OpenScreenEvent extends Event { public class OpenScreenEvent extends Event {
private final Screen screen; private final Screen screen;
@@ -4,12 +4,12 @@ import me.retucio.camtweaks.event.Event;
import me.retucio.camtweaks.event.Stage; import me.retucio.camtweaks.event.Stage;
import net.minecraft.network.packet.Packet; import net.minecraft.network.packet.Packet;
/** /**
* @see me.retucio.camtweaks.mixin.ClientConnectionMixin#onSendPacketPre * @see me.retucio.camtweaks.mixin.ClientConnectionMixin#onSendPacketPre
* @see me.retucio.camtweaks.mixin.ClientConnectionMixin#onSendPacketPost * @see me.retucio.camtweaks.mixin.ClientConnectionMixin#onSendPacketPost
* @see me.retucio.camtweaks.mixin.ClientConnectionMixin#onReceivePacket * @see me.retucio.camtweaks.mixin.ClientConnectionMixin#onReceivePacket
*/ */
public class PacketEvent { public class PacketEvent {
public static class Send extends Event { public static class Send extends Event {
@@ -3,10 +3,10 @@ package me.retucio.camtweaks.event.events;
import me.retucio.camtweaks.event.Event; import me.retucio.camtweaks.event.Event;
import net.minecraft.client.option.Perspective; import net.minecraft.client.option.Perspective;
/** /**
* @see me.retucio.camtweaks.mixin.GameOptionsMixin#changePerspective * @see me.retucio.camtweaks.mixin.GameOptionsMixin#changePerspective
*/ */
public class PerspectiveChangeEvent extends Event { public class PerspectiveChangeEvent extends Event {
private Perspective perspective; private Perspective perspective;
@@ -1,10 +1,13 @@
package me.retucio.camtweaks.event.events; package me.retucio.camtweaks.event.events;
import me.retucio.camtweaks.event.Event; import me.retucio.camtweaks.event.Event;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.hit.BlockHitResult;
/**
* @see me.retucio.camtweaks.mixin.ClientPlayerInteractionManagerMixin#onBlockPlace
*/
public class PlaceBlockEvent extends Event { public class PlaceBlockEvent extends Event {
private Hand hand; private Hand hand;
@@ -7,7 +7,6 @@ import net.minecraft.text.Text;
/** /**
* @see me.retucio.camtweaks.mixin.ChatHudMixin#onAddMessage * @see me.retucio.camtweaks.mixin.ChatHudMixin#onAddMessage
*/ */
public class ReceiveMessageEvent extends Event { public class ReceiveMessageEvent extends Event {
private Text text; private Text text;
@@ -1,8 +1,12 @@
package me.retucio.camtweaks.event.events.camtweaks; package me.retucio.camtweaks.event.events;
import me.retucio.camtweaks.event.Event; import me.retucio.camtweaks.event.Event;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
/**
* @see me.retucio.camtweaks.mixin.ClientWorldMixin#onRemoveEntity
*/
public class RemoveEntityEvent extends Event { public class RemoveEntityEvent extends Event {
private final Entity entity; private final Entity entity;
@@ -4,10 +4,10 @@ import me.retucio.camtweaks.event.Event;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
/** /**
* @see me.retucio.camtweaks.mixin.HeldItemRendererMixin#onRenderArm * @see me.retucio.camtweaks.mixin.HeldItemRendererMixin#onRenderArm
*/ */
public class RenderArmEvent extends Event { public class RenderArmEvent extends Event {
private MatrixStack matrices; private MatrixStack matrices;
@@ -6,12 +6,12 @@ import net.minecraft.text.Text;
import java.util.Iterator; import java.util.Iterator;
/** /**
* @see me.retucio.camtweaks.mixin.BossBarHudMixin#modifyBossBarIterator * @see me.retucio.camtweaks.mixin.BossBarHudMixin#modifyBossBarIterator
* @see me.retucio.camtweaks.mixin.BossBarHudMixin#modifyBossBarName * @see me.retucio.camtweaks.mixin.BossBarHudMixin#modifyBossBarName
* @see me.retucio.camtweaks.mixin.BossBarHudMixin#modifySpacingConstant * @see me.retucio.camtweaks.mixin.BossBarHudMixin#modifySpacingConstant
*/ */
public class RenderBossbarEvent { public class RenderBossbarEvent {
public static class BossText extends Event { public static class BossText extends Event {
@@ -4,10 +4,10 @@ import me.retucio.camtweaks.event.Event;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
/** /**
* @see me.retucio.camtweaks.mixin.HeldItemRendererMixin#onRenderItem * @see me.retucio.camtweaks.mixin.HeldItemRendererMixin#onRenderItem
*/ */
public class RenderHeldItemEvent extends Event { public class RenderHeldItemEvent extends Event {
private MatrixStack matrices; private MatrixStack matrices;
@@ -5,6 +5,10 @@ import net.minecraft.client.render.Camera;
import net.minecraft.client.render.RenderTickCounter; import net.minecraft.client.render.RenderTickCounter;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
/**
* @see me.retucio.camtweaks.mixin.WorldRendererMixin#render
*/
public class RenderWorldEvent extends Event { public class RenderWorldEvent extends Event {
private final MatrixStack matrices; private final MatrixStack matrices;
@@ -2,10 +2,10 @@ package me.retucio.camtweaks.event.events;
import me.retucio.camtweaks.event.Event; import me.retucio.camtweaks.event.Event;
/** /**
* @see me.retucio.camtweaks.mixin.ClientPlayNetworkHandlerMixin#onSendMessage * @see me.retucio.camtweaks.mixin.ClientPlayNetworkHandlerMixin#onSendMessage
*/ */
public class SendMessageEvent extends Event { public class SendMessageEvent extends Event {
private String message; private String message;
@@ -2,10 +2,10 @@ package me.retucio.camtweaks.event.events;
import me.retucio.camtweaks.event.Event; import me.retucio.camtweaks.event.Event;
/** /**
* @see me.retucio.camtweaks.mixin.MinecraftClientMixin#onStop * @see me.retucio.camtweaks.mixin.MinecraftClientMixin#onStop
*/ */
public class ShutdownEvent extends Event { public class ShutdownEvent extends Event {
public ShutdownEvent() {} public ShutdownEvent() {}
@@ -2,11 +2,11 @@ package me.retucio.camtweaks.event.events;
import me.retucio.camtweaks.event.Event; import me.retucio.camtweaks.event.Event;
/** /**
* @see me.retucio.camtweaks.mixin.MinecraftClientMixin#onTickPre * @see me.retucio.camtweaks.mixin.MinecraftClientMixin#onTickPre
* @see me.retucio.camtweaks.mixin.MinecraftClientMixin#onTickPost * @see me.retucio.camtweaks.mixin.MinecraftClientMixin#onTickPost
*/ */
public class TickEvent { public class TickEvent {
public static class Pre extends Event {} public static class Pre extends Event {}
@@ -4,6 +4,10 @@ import me.retucio.camtweaks.event.Event;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
/**
* @see me.retucio.camtweaks.mixin.MinecraftClientMixin#onUseItem
*/
public class UseItemEvent extends Event { public class UseItemEvent extends Event {
private ItemStack stack; private ItemStack stack;
@@ -2,4 +2,5 @@ package me.retucio.camtweaks.event.events.camtweaks;
import me.retucio.camtweaks.event.Event; import me.retucio.camtweaks.event.Event;
// se genera cuando carga la interfaz del mod
public class LoadClickGUIEvent extends Event {} public class LoadClickGUIEvent extends Event {}
@@ -2,4 +2,5 @@ package me.retucio.camtweaks.event.events.camtweaks;
import me.retucio.camtweaks.event.Event; import me.retucio.camtweaks.event.Event;
// se genera cuando carga el gestor de comandos
public class LoadCommandManagerEvent extends Event {} public class LoadCommandManagerEvent extends Event {}
@@ -2,4 +2,5 @@ package me.retucio.camtweaks.event.events.camtweaks;
import me.retucio.camtweaks.event.Event; import me.retucio.camtweaks.event.Event;
// se genera cuando carga el gestor de módulos
public class LoadModuleManagerEvent extends Event {} public class LoadModuleManagerEvent extends Event {}
@@ -16,7 +16,7 @@ import java.util.Iterator;
import static me.retucio.camtweaks.CameraTweaks.EVENT_BUS; import static me.retucio.camtweaks.CameraTweaks.EVENT_BUS;
@Mixin(BossBarHud.class) @Mixin(BossBarHud.class)
public class BossBarHudMixin { public abstract class BossBarHudMixin {
@ModifyExpressionValue(method = "render", at = @At(value = "INVOKE", target = "Ljava/util/Collection;iterator()Ljava/util/Iterator;")) @ModifyExpressionValue(method = "render", at = @At(value = "INVOKE", target = "Ljava/util/Collection;iterator()Ljava/util/Iterator;"))
public Iterator<ClientBossBar> modifyBossBarIterator(Iterator<ClientBossBar> original) { public Iterator<ClientBossBar> modifyBossBarIterator(Iterator<ClientBossBar> original) {
@@ -61,6 +61,7 @@ public abstract class ChatHudMixin implements IChatHud {
chatPlus = ModuleManager.INSTANCE.getModuleByClass(ChatPlus.class); chatPlus = ModuleManager.INSTANCE.getModuleByClass(ChatPlus.class);
} }
// métodos relacionados a las interfaces IChatHud, IChatHudLine, IChadHudLineVisible y IMessageHandler // métodos relacionados a las interfaces IChatHud, IChatHudLine, IChadHudLineVisible y IMessageHandler
@Override @Override
@@ -109,8 +110,8 @@ public abstract class ChatHudMixin implements IChatHud {
} }
// modificar contenido del mensaje // modificar contenido del mensaje
@Inject(at = @At("HEAD"), method = "addMessage(Lnet/minecraft/text/Text;Lnet/minecraft/network/message/MessageSignatureData;Lnet/minecraft/client/gui/hud/MessageIndicator;)V", cancellable = true) @Inject(at = @At("HEAD"), method = "addMessage(Lnet/minecraft/text/Text;Lnet/minecraft/network/message/MessageSignatureData;Lnet/minecraft/client/gui/hud/MessageIndicator;)V", cancellable = true)
private void onAddMessage(Text message, MessageSignatureData signatureData, MessageIndicator indicator, CallbackInfo ci) { private void onAddMessage(Text message, MessageSignatureData signatureData, MessageIndicator indicator, CallbackInfo ci) {
if (skipOnAddMessage) return; if (skipOnAddMessage) return;
@@ -36,7 +36,7 @@ public abstract class ClientCommonNetworkHandlerMixin {
@Shadow @Final protected ServerInfo serverInfo; @Shadow @Final protected ServerInfo serverInfo;
@Shadow @Final protected ClientConnection connection; @Shadow @Final protected ClientConnection connection;
@Unique // tardar 3 segundos porque algunos servers @Unique // tardar 3 segundos porque algunos servers detectar el tiempo entre que se acepta y se carga el pack
private final Executor DELAYED_EXECUTOR = CompletableFuture.delayedExecutor(3L, TimeUnit.SECONDS); private final Executor DELAYED_EXECUTOR = CompletableFuture.delayedExecutor(3L, TimeUnit.SECONDS);
@Inject(method = "createConfirmServerResourcePackScreen", at = @At("TAIL")) @Inject(method = "createConfirmServerResourcePackScreen", at = @At("TAIL"))
@@ -14,6 +14,7 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import static me.retucio.camtweaks.CameraTweaks.EVENT_BUS; import static me.retucio.camtweaks.CameraTweaks.EVENT_BUS;
import static me.retucio.camtweaks.CameraTweaks.mc;
@Mixin(ClientConnection.class) @Mixin(ClientConnection.class)
public abstract class ClientConnectionMixin { public abstract class ClientConnectionMixin {
@@ -46,7 +47,7 @@ public abstract class ClientConnectionMixin {
@Inject(method = "disconnect(Lnet/minecraft/network/DisconnectionInfo;)V", at = @At("HEAD"), cancellable = true) @Inject(method = "disconnect(Lnet/minecraft/network/DisconnectionInfo;)V", at = @At("HEAD"), cancellable = true)
private void onDisconnect(DisconnectionInfo disconnectionInfo, CallbackInfo ci) { private void onDisconnect(DisconnectionInfo disconnectionInfo, CallbackInfo ci) {
DisconnectEvent event = EVENT_BUS.post(new DisconnectEvent()); DisconnectEvent event = EVENT_BUS.post(new DisconnectEvent(disconnectionInfo, mc.getCurrentServerEntry()));
if (event.isCancelled()) ci.cancel(); if (event.isCancelled()) ci.cancel();
} }
} }
@@ -56,6 +56,7 @@ public abstract class ClientPlayNetworkHandlerMixin {
@Redirect(method = "onEntityStatus", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/GameRenderer;showFloatingItem(Lnet/minecraft/item/ItemStack;)V")) @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) { private void noRenderTotemPop(GameRenderer instance, ItemStack floatingItem) {
NoRender noRender = ModuleManager.INSTANCE.getModuleByClass(NoRender.class); NoRender noRender = ModuleManager.INSTANCE.getModuleByClass(NoRender.class);
if (!noRender.isEnabled() || noRender.totemPop.isEnabled()) mc.gameRenderer.showFloatingItem(Items.TOTEM_OF_UNDYING.getDefaultStack()); if (!noRender.isEnabled() || noRender.totemPop.isEnabled())
mc.gameRenderer.showFloatingItem(floatingItem);
} }
} }
@@ -34,9 +34,9 @@ import static me.retucio.camtweaks.CameraTweaks.mc;
@Mixin(ClientPlayerInteractionManager.class) @Mixin(ClientPlayerInteractionManager.class)
public abstract class ClientPlayerInteractionManagerMixin { public abstract class ClientPlayerInteractionManagerMixin {
@Shadow @Shadow @Final
@Final
private MinecraftClient client; private MinecraftClient client;
@Unique @Unique
Freecam freecam; Freecam freecam;
@@ -68,7 +68,7 @@ public abstract class ClientPlayerInteractionManagerMixin {
@Inject(method = "attackEntity", at = @At("HEAD"), cancellable = true) @Inject(method = "attackEntity", at = @At("HEAD"), cancellable = true)
private void onAttackEntity(PlayerEntity player, Entity target, CallbackInfo ci) { private void onAttackEntity(PlayerEntity player, Entity target, CallbackInfo ci) {
if (player != client.player) return; if (mc.player != player) return;
AttackEntityEvent event = EVENT_BUS.post(new AttackEntityEvent(target)); AttackEntityEvent event = EVENT_BUS.post(new AttackEntityEvent(target));
if (event.isCancelled()) ci.cancel(); if (event.isCancelled()) ci.cancel();
} }
@@ -1,7 +1,7 @@
package me.retucio.camtweaks.mixin; package me.retucio.camtweaks.mixin;
import me.retucio.camtweaks.event.events.camtweaks.AddEntityEvent; import me.retucio.camtweaks.event.events.AddEntityEvent;
import me.retucio.camtweaks.event.events.camtweaks.RemoveEntityEvent; import me.retucio.camtweaks.event.events.RemoveEntityEvent;
import net.minecraft.client.world.ClientWorld; import net.minecraft.client.world.ClientWorld;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -20,7 +20,7 @@ public abstract class ClientWorldMixin {
public abstract Entity getEntityById(int id); public abstract Entity getEntityById(int id);
@Inject(method = "addEntity", at = @At("HEAD")) @Inject(method = "addEntity", at = @At("HEAD"))
private void onEntityAdded(Entity entity, CallbackInfo ci) { private void onAddEntity(Entity entity, CallbackInfo ci) {
if (entity != null) EVENT_BUS.post(new AddEntityEvent(entity)); if (entity != null) EVENT_BUS.post(new AddEntityEvent(entity));
} }
@@ -3,10 +3,8 @@ package me.retucio.camtweaks.mixin;
import com.llamalad7.mixinextras.injector.ModifyReturnValue; import com.llamalad7.mixinextras.injector.ModifyReturnValue;
import me.retucio.camtweaks.module.ModuleManager; import me.retucio.camtweaks.module.ModuleManager;
import me.retucio.camtweaks.module.modules.CritsPlus; import me.retucio.camtweaks.module.modules.CritsPlus;
import me.retucio.camtweaks.util.Colors;
import net.minecraft.client.particle.BillboardParticle; import net.minecraft.client.particle.BillboardParticle;
import net.minecraft.client.particle.DamageParticle; import net.minecraft.client.particle.DamageParticle;
import net.minecraft.client.particle.ParticleTextureSheet;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyVariable; import org.spongepowered.asm.mixin.injection.ModifyVariable;
@@ -32,20 +30,13 @@ abstract class DamageParticleFactoryMixin {
CritsPlus crits = ModuleManager.INSTANCE.getModuleByClass(CritsPlus.class); CritsPlus crits = ModuleManager.INSTANCE.getModuleByClass(CritsPlus.class);
if (!crits.isEnabled()) return original; if (!crits.isEnabled()) return original;
if (crits.rainbow.isEnabled()) { original.setColor(
Color gamning = Colors.rainbowColor(crits.rainbowSpeed.getIntValue(), crits.alpha.getIntValue()); crits.color.getR() / 255f,
original.setColor( crits.color.getG() / 255f,
gamning.getRed() / 255f, crits.color.getB() / 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.alpha = crits.color.getA() / 255f;
original.scale *= crits.scale.getFloatValue(); original.scale *= crits.scale.getFloatValue();
original.velocityMultiplier *= crits.velocityMultipler.getFloatValue(); original.velocityMultiplier *= crits.velocityMultipler.getFloatValue();
original.gravityStrength *= crits.gravity.getFloatValue(); original.gravityStrength *= crits.gravity.getFloatValue();
@@ -1,8 +1,10 @@
package me.retucio.camtweaks.mixin; package me.retucio.camtweaks.mixin;
import com.llamalad7.mixinextras.injector.ModifyReturnValue; import com.llamalad7.mixinextras.injector.ModifyReturnValue;
import com.llamalad7.mixinextras.sugar.Local;
import me.retucio.camtweaks.module.ModuleManager; import me.retucio.camtweaks.module.ModuleManager;
import me.retucio.camtweaks.module.modules.TimeChanger; import me.retucio.camtweaks.module.modules.TimeChanger;
import me.retucio.camtweaks.util.ChatUtil;
import net.minecraft.world.dimension.DimensionType; import net.minecraft.world.dimension.DimensionType;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
@@ -12,11 +14,17 @@ import static me.retucio.camtweaks.CameraTweaks.mc;
@Mixin(DimensionType.class) @Mixin(DimensionType.class)
public abstract class DimensionTypeMixin { public abstract class DimensionTypeMixin {
// no consigo arreglar lo de que la fase lunar por defecto siempre sea luna llena
@ModifyReturnValue(method = "getMoonPhase", at = @At("RETURN")) @ModifyReturnValue(method = "getMoonPhase", at = @At("RETURN"))
private int overrideMoonPhase(int original) { private int overrideMoonPhase(int original, @Local(argsOnly = true) long time) {
TimeChanger timeChanger = ModuleManager.INSTANCE.getModuleByClass(TimeChanger.class); TimeChanger timeChanger = ModuleManager.INSTANCE.getModuleByClass(TimeChanger.class);
if (timeChanger.isEnabled() && mc.world != null && !timeChanger.moonPhase.is(TimeChanger.MoonPhases.DEFAULT)) if (timeChanger == null || !timeChanger.isEnabled() || mc.world == null) {
return timeChanger.getMoonPhase(); return original;
return original; }
if (timeChanger.moonPhase.is(TimeChanger.MoonPhases.DEFAULT))
return (int) (time / 24000L % 8L + 8L) % 8;
return timeChanger.getMoonPhase();
} }
} }
@@ -0,0 +1,34 @@
package me.retucio.camtweaks.mixin;
import me.retucio.camtweaks.module.ModuleManager;
import me.retucio.camtweaks.module.modules.Reconnect;
import net.minecraft.client.gui.screen.DisconnectedScreen;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.gui.widget.DirectionalLayoutWidget;
import net.minecraft.text.Text;
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(DisconnectedScreen.class)
public abstract class DisconnectedScreenMixin {
@Shadow @Final
private DirectionalLayoutWidget grid;
@Inject(method = "init", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/widget/DirectionalLayoutWidget;add(Lnet/minecraft/client/gui/widget/Widget;)Lnet/minecraft/client/gui/widget/Widget;", ordinal = 2, shift = At.Shift.AFTER))
private void addReconnectButton(CallbackInfo ci) {
Reconnect reconnect = ModuleManager.INSTANCE.getModuleByClass(Reconnect.class);
if (reconnect == null || !reconnect.isEnabled()) return;
grid.add(ButtonWidget.builder(
Text.literal("reconectarse"),
button -> reconnect.reconnect()
).build());
}
}
@@ -25,29 +25,16 @@ import static me.retucio.camtweaks.CameraTweaks.mc;
@Mixin(Entity.class) @Mixin(Entity.class)
public abstract class EntityMixin { public abstract class EntityMixin {
@Shadow @Shadow public abstract Text getName();
public abstract Text getName(); @Shadow public abstract EntityType<?> getType();
@Shadow @Shadow private float yaw;
public abstract EntityType<?> getType(); @Shadow private float pitch;
@Shadow @Unique Freecam freecam;
private float yaw; @Unique Freelook freelook;
@Unique Nametags nametags;
@Shadow @Unique Rotations rotations;
private float pitch;
@Unique
Freecam freecam;
@Unique
Freelook freelook;
@Unique
Nametags nametags;
@Unique
Rotations rotations;
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
@Inject(method = "<init>", at = @At("TAIL")) @Inject(method = "<init>", at = @At("TAIL"))
@@ -1,20 +1,28 @@
package me.retucio.camtweaks.mixin; package me.retucio.camtweaks.mixin;
import me.retucio.camtweaks.event.events.DamageItemEvent; import me.retucio.camtweaks.event.events.DamageItemEvent;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.server.network.ServerPlayerEntity;
import org.spongepowered.asm.mixin.Mixin; 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.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.function.Consumer;
import static me.retucio.camtweaks.CameraTweaks.EVENT_BUS; import static me.retucio.camtweaks.CameraTweaks.EVENT_BUS;
@Mixin(ItemStack.class) @Mixin(ItemStack.class)
public abstract class ItemStackMixin { public abstract class ItemStackMixin {
@Inject(method = "setDamage", at = @At("HEAD")) @Shadow
private void onDamage(int damage, CallbackInfo ci) { public abstract int getDamage();
@Inject(method = "onDurabilityChange", at = @At("TAIL"))
private void onDamage(int damage, ServerPlayerEntity player, Consumer<Item> breakCallback, CallbackInfo ci) {
ItemStack stack = (ItemStack) (Object) this; ItemStack stack = (ItemStack) (Object) this;
EVENT_BUS.post(new DamageItemEvent(damage, stack)); EVENT_BUS.post(new DamageItemEvent(getDamage(), stack));
} }
} }
@@ -43,10 +43,10 @@ public abstract class LightmapTextureManagerMixin {
private void update(float tickProgress, CallbackInfo ci, @Local Profiler profiler) { private void update(float tickProgress, CallbackInfo ci, @Local Profiler profiler) {
if (fullbright.isEnabled() && fullbright.mode.is(Fullbright.Modes.GAMMA)) { if (fullbright.isEnabled() && fullbright.mode.is(Fullbright.Modes.GAMMA)) {
RenderSystem.getDevice().createCommandEncoder().clearColorTexture(glTexture, ColorHelper.getArgb( RenderSystem.getDevice().createCommandEncoder().clearColorTexture(glTexture, ColorHelper.getArgb(
fullbright.alpha.getIntValue(), fullbright.color.getA(),
fullbright.red.getIntValue(), fullbright.color.getR(),
fullbright.green.getIntValue(), fullbright.color.getG(),
fullbright.blue.getIntValue() fullbright.color.getB()
)); ));
profiler.pop(); profiler.pop();
ci.cancel(); ci.cancel();
@@ -37,11 +37,7 @@ public class ScreenMixin {
if (watermark == null || watermark.isEmpty()) return; if (watermark == null || watermark.isEmpty()) return;
context.drawText(mc.textRenderer, watermark, context.drawText(mc.textRenderer, watermark,
mc.getWindow().getScaledWidth() - mc.textRenderer.getWidth(watermark) - 2, 2, mc.getWindow().getScaledWidth() - mc.textRenderer.getWidth(watermark) - 2, 2,
new Color((int) ClientSettingsFrame.guiSettings.red.getDefaultValue(), ClientSettingsFrame.guiSettings.color.getRGB(), false
(int) ClientSettingsFrame.guiSettings.green.getDefaultValue(),
(int) ClientSettingsFrame.guiSettings.blue.getDefaultValue(),
(int) ClientSettingsFrame.guiSettings.alpha.getDefaultValue()
).getRGB(), false
); );
} }
} }
@@ -77,15 +77,6 @@ public abstract class WorldRendererMixin {
BlockOutline outline = ModuleManager.INSTANCE.getModuleByClass(BlockOutline.class); BlockOutline outline = ModuleManager.INSTANCE.getModuleByClass(BlockOutline.class);
if (!outline.isEnabled()) return ColorHelper.withAlpha(alpha, rgb); if (!outline.isEnabled()) return ColorHelper.withAlpha(alpha, rgb);
if (outline.rainbow.isEnabled()) { return outline.color.getRGB();
return Colors.rainbowInt(outline.rainbowSpeed.getIntValue(), outline.alpha.getIntValue());
} else {
return new Color(
outline.red.getIntValue(),
outline.green.getIntValue(),
outline.blue.getIntValue(),
outline.alpha.getIntValue()
).getRGB();
}
} }
} }
@@ -0,0 +1,16 @@
package me.retucio.camtweaks.mixin.accessor;
import net.minecraft.client.gui.screen.ingame.AnvilScreen;
import net.minecraft.client.gui.widget.TextFieldWidget;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(AnvilScreen.class)
public interface AnvilScreenAccessor {
@Accessor("nameField")
TextFieldWidget getNameField();
@Accessor("nameField")
void setNameField(TextFieldWidget nameField);
}
@@ -23,6 +23,7 @@ public class Module {
private String description; private String description;
private boolean enabled; private boolean enabled;
private boolean saveSettings = true; private boolean saveSettings = true;
private boolean searchMatch = 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 // 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 EnumSetting<KeyModes> keyMode = new EnumSetting<>("modo de tecla", "cómo interpretar la tecla configurada", KeyModes.class, KeyModes.TOGGLE);
@@ -39,6 +40,13 @@ public class Module {
addSettings(bind, keyMode, notify); addSettings(bind, keyMode, notify);
} }
public Module(String name, String description, int key) {
this.name = name;
this.description = description;
addSettings(bind, keyMode, notify);
this.bind.setDefaultKey(key);
this.bind.setKey(key);
}
// ajustes // ajustes
public List<AbstractSetting> getSettings() { public List<AbstractSetting> getSettings() {
@@ -49,7 +57,7 @@ public class Module {
public <S extends AbstractSetting> S addSetting(AbstractSetting setting) { public <S extends AbstractSetting> S addSetting(AbstractSetting setting) {
settings.add(setting); settings.add(setting);
setting.setModule(this); setting.setModule(this);
return (S) setting; // por convenciencia return (S) setting; // por conveniencia
} }
public void addSettings(AbstractSetting... settings) { public void addSettings(AbstractSetting... settings) {
@@ -141,6 +149,14 @@ public class Module {
return bind; return bind;
} }
public boolean isSearchMatch() {
return searchMatch;
}
public void setSearchMatch(boolean searchMatch) {
this.searchMatch = searchMatch;
}
public enum KeyModes { public enum KeyModes {
HOLD("mantener"), HOLD("mantener"),
TOGGLE("alternar"); TOGGLE("alternar");
@@ -26,6 +26,7 @@ public class ModuleManager {
// por orden alfabético y todo, flipas // por orden alfabético y todo, flipas
private void addModules() { private void addModules() {
modules.add(new AntiInvis()); modules.add(new AntiInvis());
modules.add(new AnvilFont());
modules.add(new AttributeSwapper()); modules.add(new AttributeSwapper());
modules.add(new AutoSign()); modules.add(new AutoSign());
modules.add(new BlockOutline()); modules.add(new BlockOutline());
@@ -44,12 +45,14 @@ public class ModuleManager {
modules.add(new HandView()); modules.add(new HandView());
modules.add(new Headhitters()); modules.add(new Headhitters());
modules.add(new HUD()); modules.add(new HUD());
modules.add(new LightOverlay());
modules.add(new LogoutSpots()); modules.add(new LogoutSpots());
modules.add(new Nametags()); modules.add(new Nametags());
modules.add(new NoMiningInterruptions()); modules.add(new NoMiningInterruptions());
modules.add(new NoRender()); modules.add(new NoRender());
modules.add(new PerspectivePlus()); modules.add(new PerspectivePlus());
modules.add(new PortalGUI()); modules.add(new PortalGUI());
modules.add(new Reconnect());
modules.add(new Rotations()); modules.add(new Rotations());
modules.add(new RPackBypass()); modules.add(new RPackBypass());
modules.add(new ScreenshotPlus()); modules.add(new ScreenshotPlus());
@@ -0,0 +1,147 @@
package me.retucio.camtweaks.module.modules;
import me.retucio.camtweaks.mixin.accessor.AnvilScreenAccessor;
import me.retucio.camtweaks.module.Module;
import me.retucio.camtweaks.module.settings.EnumSetting;
import net.minecraft.client.gui.screen.ingame.AnvilScreen;
import net.minecraft.client.gui.widget.TextFieldWidget;
import me.retucio.camtweaks.module.modules.AnvilFont.CustomFont.CharMap;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class AnvilFont extends Module {
public EnumSetting<FontMode> fontMode = addSetting(new EnumSetting<>("tipografía", "qué tipografía utilizar",
FontMode.class, FontMode.NORMAL));
String text;
private static final List<CustomFont> fonts = Arrays.asList(
new CustomFont( // normal
CharMap.range('!', 65281, 95)),
new CustomFont( // mayúsculas
CharMap.single('a', 'ᴀ'), CharMap.single('b', 'ʙ'), CharMap.range('c', 0x1d04, 2), CharMap.single('e', 'ᴇ'),
CharMap.single('f', 'ꜰ'), CharMap.single('g', 'ɢ'), CharMap.single('h', 'ʜ'), CharMap.single('i', 'ɪ'),
CharMap.range('j', 0x1D0a, 2), CharMap.single('l', 'ʟ'), CharMap.single('m', 'ᴍ'), CharMap.single('n', 'ɴ'),
CharMap.single('o', 'ᴏ'), CharMap.single('p', 'ᴩ'), CharMap.single('r', 'ʀ'), CharMap.single('s', 'ꜱ'),
CharMap.range('t', 0x1D1b, 2), CharMap.range('v', 0x1d20, 2), CharMap.single('z', 'ᴢ'),
CharMap.single('A', 'ᴀ'), CharMap.single('B', 'ʙ'), CharMap.range('C', 0x1d04, 2), CharMap.single('E', 'ᴇ'),
CharMap.single('F', 'ꜰ'), CharMap.single('G', 'ɢ'), CharMap.single('H', 'ʜ'), CharMap.single('I', 'ɪ'),
CharMap.range('J', 0x1D0a, 2), CharMap.single('L', 'ʟ'), CharMap.single('M', 'ᴍ'), CharMap.single('N', 'ɴ'),
CharMap.single('O', 'ᴏ'), CharMap.single('P', 'ᴩ'), CharMap.single('R', 'ʀ'), CharMap.single('S', 'ꜱ'),
CharMap.range('T', 0x1D1b, 2), CharMap.range('V', 0x1d20, 2), CharMap.single('z', 'ᴢ')),
new CustomFont( // redondo
CharMap.range('1', 9313, 9),
CharMap.range('A', 9398, 26),
CharMap.range('a', 9424, 26)),
new CustomFont( // to raro
CharMap.single('a', 'Λ'), CharMap.single('c', 'ᑕ'), CharMap.single('e', 'Σ'), CharMap.single('h', 'Ή'),
CharMap.single('l', 'ᒪ'), CharMap.single('n', 'П'), CharMap.single('o', 'Ө'), CharMap.single('r', 'Я'),
CharMap.single('s', 'Ƨ'), CharMap.single('t', 'Ƭ'), CharMap.single('u', 'Ц'), CharMap.single('w', 'Щ'),
CharMap.single('A', 'Λ'), CharMap.single('C', 'ᑕ'), CharMap.single('E', 'Σ'), CharMap.single('H', 'Ή'),
CharMap.single('L', 'ᒪ'), CharMap.single('N', 'П'), CharMap.single('O', 'Ө'), CharMap.single('R', 'Я'),
CharMap.single('S', 'Ƨ'), CharMap.single('T', 'Ƭ'), CharMap.single('U', 'Ц'), CharMap.single('W', 'Щ')),
new CustomFont( // griego
CharMap.single('a', 'α'), CharMap.single('b', 'в'), CharMap.single('d', '∂'), CharMap.single('e', 'є'),
CharMap.single('f', 'ƒ'), CharMap.single('h', 'н'), CharMap.single('i', 'ι'), CharMap.single('j', 'נ'),
CharMap.single('k', 'к'), CharMap.single('l', 'ℓ'), CharMap.single('m', 'м'), CharMap.single('n', 'η'),
CharMap.single('o', 'σ'), CharMap.single('p', 'ρ'), CharMap.single('r', 'я'), CharMap.single('s', 'ѕ'),
CharMap.single('t', 'т'), CharMap.single('u', 'υ'), CharMap.single('v', 'ν'), CharMap.single('w', 'ω'),
CharMap.single('x', 'χ'), CharMap.single('y', 'у'),
CharMap.single('A', 'α'), CharMap.single('B', 'в'), CharMap.single('D', '∂'), CharMap.single('E', 'є'),
CharMap.single('F', 'ƒ'), CharMap.single('H', 'н'), CharMap.single('I', 'ι'), CharMap.single('J', 'נ'),
CharMap.single('K', 'к'), CharMap.single('L', 'ℓ'), CharMap.single('M', 'м'), CharMap.single('N', 'η'),
CharMap.single('O', 'σ'), CharMap.single('P', 'ρ'), CharMap.single('R', 'я'), CharMap.single('S', 'ѕ'),
CharMap.single('T', 'т'), CharMap.single('U', 'υ'), CharMap.single('V', 'ν'), CharMap.single('W', 'ω'),
CharMap.single('X', 'χ'), CharMap.single('Y', 'у'))
);
public AnvilFont() {
super("yunques con pluma", "te permite tipografías distintas al renombrar items en un yunque");
}
@Override
public void onTick() {
if (mc.currentScreen == null) return;
if (mc.currentScreen instanceof AnvilScreen) {
TextFieldWidget nameField = ((AnvilScreenAccessor) mc.currentScreen).getNameField();
if (fontMode.getValue() != FontMode.NORMAL)
text = fonts.get(fontMode.getIndex()).replace(nameField.getText());
else
text = nameField.getText();
if (!text.equals(nameField.getText()))
nameField.setText(text);
((AnvilScreenAccessor) mc.currentScreen).setNameField(nameField);
}
}
static class CustomFont {
private final HashMap<Character, Character> allMaps = new HashMap<>();
public CustomFont(CharMap... maps) {
for (CharMap map : maps)
allMaps.putAll(map.getMap());
}
public String replace(String startString) {
for (Map.Entry<Character, Character> e : allMaps.entrySet())
startString = startString.replace(e.getKey(), e.getValue());
return startString;
}
static class CharMap {
private final HashMap<Character, Character> map = new HashMap<>();
private CharMap(char... mappings) {
for (int i = 0; i < mappings.length - 1; i += 2)
map.put(mappings[i], mappings[i + 1]);
}
public static CharMap single(char from, char to) {
return new CharMap(from, to);
}
public static CharMap range(char start, int start1, int amount) {
char[] chars = new char[amount * 2];
for (int i = 0; i < amount; i++) {
chars[i * 2] = (char) (start + i);
chars[i * 2 + 1] = (char) (start1 + i);
}
return new CharMap(chars);
}
public HashMap<Character, Character> getMap() {
return map;
}
}
}
public enum FontMode {
NORMAL("normal"),
UPPERCASE("mayúsculas"),
CIRCLED("redondo"),
CURSED("to raro"),
GREEK("griego");
private final String name;
FontMode(String name) { this.name = name; }
@Override public String toString() { return name; }
}
}
@@ -2,30 +2,21 @@ package me.retucio.camtweaks.module.modules;
import me.retucio.camtweaks.module.Module; import me.retucio.camtweaks.module.Module;
import me.retucio.camtweaks.module.settings.BooleanSetting; import me.retucio.camtweaks.module.settings.BooleanSetting;
import me.retucio.camtweaks.module.settings.ColorSetting;
import me.retucio.camtweaks.module.settings.NumberSetting; import me.retucio.camtweaks.module.settings.NumberSetting;
import java.awt.*;
/** continúa en: /** continúa en:
* @see me.retucio.camtweaks.mixin.WorldRendererMixin * @see me.retucio.camtweaks.mixin.WorldRendererMixin
*/ */
public class BlockOutline extends Module { public class BlockOutline extends Module {
public BooleanSetting rainbow = addSetting(new BooleanSetting("RGB", "erre ge be gueiming", false)); public ColorSetting color = addSetting(new ColorSetting("color", "color del contorno de los bloques",
public NumberSetting rainbowSpeed = addSetting(new NumberSetting("velocidad", "velocidad de la bandera gay", 2000, 0, 10000, 2)); new Color(0, 0, 0, 102), true));
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() { public BlockOutline() {
super("contorno", "customiza el contorno de los bloques"); super("contorno", "customiza el contorno de los bloques");
rainbow.onUpdate(v -> {
rainbowSpeed.setVisible(v);
red.setVisible(!v);
green.setVisible(!v);
blue.setVisible(!v);
});
} }
} }
@@ -2,8 +2,11 @@ package me.retucio.camtweaks.module.modules;
import me.retucio.camtweaks.module.Module; import me.retucio.camtweaks.module.Module;
import me.retucio.camtweaks.module.settings.BooleanSetting; import me.retucio.camtweaks.module.settings.BooleanSetting;
import me.retucio.camtweaks.module.settings.ColorSetting;
import me.retucio.camtweaks.module.settings.NumberSetting; import me.retucio.camtweaks.module.settings.NumberSetting;
import java.awt.*;
/** continúa en: /** continúa en:
* @see me.retucio.camtweaks.mixin.DamageParticleMixin * @see me.retucio.camtweaks.mixin.DamageParticleMixin
* @see me.retucio.camtweaks.mixin.DamageParticleFactoryMixin * @see me.retucio.camtweaks.mixin.DamageParticleFactoryMixin
@@ -11,13 +14,7 @@ import me.retucio.camtweaks.module.settings.NumberSetting;
public class CritsPlus extends Module { public class CritsPlus extends Module {
public BooleanSetting rainbow = addSetting(new BooleanSetting("LUCES GAMING", "PARTÍCULAS GAMING", false)); public ColorSetting color = addSetting(new ColorSetting("color", "color de las partículas", new Color(0, 0, 255, 255), 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 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 multiplier; // no sé dónde se calcula cuántas partículas aparecen :/
@@ -28,11 +25,5 @@ public class CritsPlus extends Module {
public CritsPlus() { public CritsPlus() {
super("críticos", "cambia la apariencia de los críticos al gusto"); 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);
});
} }
} }
@@ -3,6 +3,7 @@ package me.retucio.camtweaks.module.modules;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.textures.GpuTextureView; import com.mojang.blaze3d.textures.GpuTextureView;
import me.retucio.camtweaks.module.Module; import me.retucio.camtweaks.module.Module;
import me.retucio.camtweaks.module.settings.ColorSetting;
import me.retucio.camtweaks.module.settings.NumberSetting; import me.retucio.camtweaks.module.settings.NumberSetting;
import net.minecraft.client.texture.NativeImage; import net.minecraft.client.texture.NativeImage;
import net.minecraft.client.texture.NativeImageBackedTexture; import net.minecraft.client.texture.NativeImageBackedTexture;
@@ -15,19 +16,13 @@ import java.awt.*;
public class DamageOverlay extends Module { public class DamageOverlay extends Module {
public NumberSetting red = addSetting(new NumberSetting("rojo", "r o j o", 255, 0, 255, 1)); public ColorSetting colorSetting = addSetting(new ColorSetting("color", "color", new Color(255, 0, 0, 77), false));
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; private NativeImageBackedTexture texture = null;
public DamageOverlay() { public DamageOverlay() {
super("superposición de daño", "modifica el color en el que se renderiza la superposición de recibir daño"); super("superposición de daño", "modifica el color en el que se renderiza la superposición de recibir daño");
colorSetting.onUpdate(v -> reloadOverlayIfReady());
NumberSetting[] settings = {red, green, blue, alpha};
for (NumberSetting setting : settings)
setting.onUpdate(v -> reloadOverlayIfReady());
} }
@Override @Override
@@ -42,6 +37,11 @@ public class DamageOverlay extends Module {
super.onDisable(); super.onDisable();
} }
@Override
public void onTick() {
if (colorSetting.isRainbow()) reloadOverlayIfReady();
}
private void reloadOverlayIfReady() { private void reloadOverlayIfReady() {
if (texture != null && texture.getImage() != null) reloadOverlay(texture); if (texture != null && texture.getImage() != null) reloadOverlay(texture);
} }
@@ -50,8 +50,13 @@ public class DamageOverlay extends Module {
public void reloadOverlay(NativeImageBackedTexture texture) { public void reloadOverlay(NativeImageBackedTexture texture) {
if (this.texture == null) this.texture = texture; if (this.texture == null) this.texture = texture;
int color = isEnabled() ? int color = isEnabled()
new Color(red.getIntValue(), green.getIntValue(), blue.getIntValue(), 255 - alpha.getIntValue()).getRGB() ? new Color(
colorSetting.getR(),
colorSetting.getG(),
colorSetting.getB(),
255 - colorSetting.getA()
).getRGB()
: new Color(255, 0, 0, 178).getRGB(); : new Color(255, 0, 0, 178).getRGB();
NativeImage image = texture.getImage(); NativeImage image = texture.getImage();
@@ -33,10 +33,17 @@ public class FakePlayer extends Module {
super.onDisable(); super.onDisable();
} }
// intento miserable de hacer que no colisione con jugadores
public OtherClientPlayerEntity addPlayer(PlayerEntity playerToCopy, String dummyName) { public OtherClientPlayerEntity addPlayer(PlayerEntity playerToCopy, String dummyName) {
player = new OtherClientPlayerEntity(mc.world, new GameProfile(UUID.randomUUID(), dummyName)); player = new OtherClientPlayerEntity(mc.world, new GameProfile(UUID.randomUUID(), dummyName)) {
@Override public void onPlayerCollision(PlayerEntity player) {}
};
player.copyFrom(playerToCopy); player.copyFrom(playerToCopy);
player.setCustomNameVisible(true); player.setCustomNameVisible(true);
player.noClip = true;
player.horizontalCollision = false;
player.verticalCollision = false;
mc.world.addEntity(player); mc.world.addEntity(player);
return player; return player;
} }
@@ -21,7 +21,6 @@ import net.minecraft.network.packet.c2s.play.PlayerInteractBlockC2SPacket;
import net.minecraft.network.packet.c2s.play.PlayerInteractItemC2SPacket; import net.minecraft.network.packet.c2s.play.PlayerInteractItemC2SPacket;
import net.minecraft.network.packet.s2c.play.DeathMessageS2CPacket; import net.minecraft.network.packet.s2c.play.DeathMessageS2CPacket;
import net.minecraft.network.packet.s2c.play.HealthUpdateS2CPacket; import net.minecraft.network.packet.s2c.play.HealthUpdateS2CPacket;
import net.minecraft.util.ActionResult;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import org.joml.Vector3d; import org.joml.Vector3d;
@@ -70,8 +69,7 @@ public class Freecam extends Module {
private float yaw, pitch; private float yaw, pitch;
public Freecam() { public Freecam() {
super("cámara libre", "permite 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", GLFW.GLFW_KEY_V);
assignKey(GLFW.GLFW_KEY_V);
speedSetting.onUpdate(newSpeed -> speed = newSpeed); speedSetting.onUpdate(newSpeed -> speed = newSpeed);
} }
@@ -115,6 +113,7 @@ public class Freecam extends Module {
unpress(); unpress();
if (reloadChunks.isEnabled()) mc.worldRenderer.reload(); if (reloadChunks.isEnabled()) mc.worldRenderer.reload();
super.onEnable(); super.onEnable();
} }
@@ -207,7 +206,6 @@ public class Freecam extends Module {
@SubscribeEvent @SubscribeEvent
public void onKey(KeyEvent event) { 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;
KeyInput key = new KeyInput(event.getKey(), event.getScancode(), 0); KeyInput key = new KeyInput(event.getKey(), event.getScancode(), 0);
@@ -239,7 +237,6 @@ public class Freecam extends Module {
@SubscribeEvent @SubscribeEvent
public void onMouseClick(MouseClickEvent event) { // por si el restrasado del usuario usa el ratón para moverse public void onMouseClick(MouseClickEvent event) { // por si el restrasado del usuario usa el ratón para moverse
if (mc.currentScreen != null) return;
Click click = new Click(0, 0, new MouseInput(event.getButton(), 0)); Click click = new Click(0, 0, new MouseInput(event.getButton(), 0));
boolean shouldCancel = true; boolean shouldCancel = true;
@@ -305,6 +302,7 @@ public class Freecam extends Module {
@SubscribeEvent @SubscribeEvent
public void onOpenScreen(OpenScreenEvent event) { public void onOpenScreen(OpenScreenEvent event) {
unpress(); unpress();
stopMoving();
prevPos.set(pos); prevPos.set(pos);
prevYaw = yaw; prevYaw = yaw;
prevPitch = pitch; prevPitch = pitch;
@@ -351,6 +349,15 @@ public class Freecam extends Module {
mc.options.sneakKey.setPressed(false); mc.options.sneakKey.setPressed(false);
} }
private void stopMoving() {
forward = false;
backward = false;
left = false;
right = false;
up = false;
down = false;
}
// getters // getters
@@ -29,8 +29,7 @@ public class Freelook extends Module {
private Perspective prevPerspective; private Perspective prevPerspective;
public Freelook() { public Freelook() {
super("perspectiva libre", "te permite mover la cámara de la perspectiva sin mover la del jugador, o vice versa"); super("perspectiva libre", "te permite mover la cámara de la perspectiva sin mover la del jugador, o vice versa", GLFW.GLFW_KEY_B);
assignKey(GLFW.GLFW_KEY_B);
keyMode.setDefaultValue(KeyModes.HOLD); keyMode.setDefaultValue(KeyModes.HOLD);
keyMode.setValue(KeyModes.HOLD); keyMode.setValue(KeyModes.HOLD);
@@ -2,6 +2,7 @@ package me.retucio.camtweaks.module.modules;
import me.retucio.camtweaks.mixin.accessor.StatusEffectInstanceAccessor; import me.retucio.camtweaks.mixin.accessor.StatusEffectInstanceAccessor;
import me.retucio.camtweaks.module.Module; import me.retucio.camtweaks.module.Module;
import me.retucio.camtweaks.module.settings.ColorSetting;
import me.retucio.camtweaks.module.settings.EnumSetting; import me.retucio.camtweaks.module.settings.EnumSetting;
import me.retucio.camtweaks.module.settings.NumberSetting; import me.retucio.camtweaks.module.settings.NumberSetting;
import net.minecraft.entity.effect.StatusEffectInstance; import net.minecraft.entity.effect.StatusEffectInstance;
@@ -9,6 +10,8 @@ import net.minecraft.entity.effect.StatusEffects;
import net.minecraft.registry.Registries; import net.minecraft.registry.Registries;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
import java.awt.*;
/** continúa en: /** continúa en:
* @see me.retucio.camtweaks.mixin.LightmapTextureManagerMixin * @see me.retucio.camtweaks.mixin.LightmapTextureManagerMixin
*/ */
@@ -17,28 +20,14 @@ 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 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", public ColorSetting color = addSetting(new ColorSetting("filtro", "filtro de color", new Color(255, 255, 255, 255), false));
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() { public Fullbright() {
super("brilli brilli", "deshabilita la oscuridad (y aplica colores a los shaders)"); super("brilli brilli", "deshabilita la oscuridad (y aplica colores a los shaders)", GLFW.GLFW_KEY_K);
assignKey(GLFW.GLFW_KEY_K);
mode.onUpdate(mode -> { if (mode != Modes.POTION) disableNightVision(); }); mode.onUpdate(mode -> { if (mode != Modes.POTION) disableNightVision(); });
mode.onUpdate(mode -> { mode.onUpdate(mode -> {
boolean v = mode.equals(Modes.GAMMA); boolean v = mode.equals(Modes.GAMMA);
red.setVisible(v); color.setVisible(v);
green.setVisible(v);
blue.setVisible(v);
alpha.setVisible(v);
if (v) disableNightVision(); if (v) disableNightVision();
}); });
@@ -9,6 +9,7 @@ import me.retucio.camtweaks.event.events.camtweaks.LoadCommandManagerEvent;
import me.retucio.camtweaks.module.Module; import me.retucio.camtweaks.module.Module;
import me.retucio.camtweaks.module.ModuleManager; import me.retucio.camtweaks.module.ModuleManager;
import me.retucio.camtweaks.module.settings.BooleanSetting; import me.retucio.camtweaks.module.settings.BooleanSetting;
import me.retucio.camtweaks.module.settings.ColorSetting;
import me.retucio.camtweaks.module.settings.NumberSetting; import me.retucio.camtweaks.module.settings.NumberSetting;
import me.retucio.camtweaks.module.settings.StringSetting; import me.retucio.camtweaks.module.settings.StringSetting;
import me.retucio.camtweaks.util.ChatUtil; import me.retucio.camtweaks.util.ChatUtil;
@@ -20,18 +21,8 @@ import java.awt.*;
// módulo no visible solo para los ajustes de la interfaz (y del cliente en general) // módulo no visible solo para los ajustes de la interfaz (y del cliente en general)
public class GUI extends Module { public class GUI extends Module {
public BooleanSetting rainbow = addSetting(new BooleanSetting("gaming", "gaming", false)); public ColorSetting color = addSetting(new ColorSetting("color", "color principal de la interfaz y el mod",
public NumberSetting rainbowSpeed = addSetting(new NumberSetting("velocidad del gaming", "velocidad, del gaming.", new Color(70, 20, 210, 230), false));
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 // 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", public NumberSetting scrollSens = addSetting(new NumberSetting("sensibilidad del scroll", "qué tan sensible es la interfaz a la rueda del ratón",
@@ -50,24 +41,18 @@ public class GUI extends Module {
public BooleanSetting multipleKeybinds = addSetting(new BooleanSetting("teclas multimódulo", "permitir asignar la misma tecla a más de un módulo", false)); 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() { public GUI() {
super("interfaz", "ajustes de la interfaz, y otros misceláneos"); super("interfaz", "ajustes de la interfaz, y otros misceláneos", GLFW.GLFW_KEY_RIGHT_SHIFT);
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); CameraTweaks.EVENT_BUS.register(this);
keyMode.setVisible(false); keyMode.setVisible(false);
notify.setVisible(false); notify.setVisible(false);
searchBar.onUpdate(v -> matchCase.setVisible(v)); searchBar.onUpdate(v -> matchCase.setVisible(v));
} }
@SubscribeEvent @SubscribeEvent
public void onLoadCommandManager(LoadCommandManagerEvent event) { public void onLoadCommandManager(LoadCommandManagerEvent event) {
commandPrefix.onUpdate(prefix -> CommandManager.INSTANCE.setPrefix(prefix)); commandPrefix.onUpdate(CommandManager.INSTANCE::setPrefix);
commandPrefix.setDefaultValue(CommandManager.INSTANCE.getPrefix()); commandPrefix.setDefaultValue(CommandManager.INSTANCE.getPrefix());
chatName.onUpdate(name -> { chatName.onUpdate(name -> {
@@ -76,69 +61,24 @@ public class GUI extends Module {
}); });
} }
// lógica un poco prolija pero bueno
@SubscribeEvent @SubscribeEvent
public void onLoadClickGUI(LoadClickGUIEvent event) { public void onLoadClickGUI(LoadClickGUIEvent event) {
rainbow.onUpdate(v -> { color.onUpdate(v -> {
if (v) { Colors.red = color.getR();
prevRed = red.getIntValue(); Colors.green = color.getG();
prevGreen = green.getIntValue(); Colors.blue = color.getB();
prevBlue = blue.getIntValue(); Colors.alpha = color.getA();
} else { Colors.updateAllColors(new Color(Colors.red, Colors.green, Colors.blue, Colors.alpha));
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());
// muy mierdas la solución pero funciona
red.reset();
green.reset();
blue.reset();
alpha.reset();
} }
@SubscribeEvent @SubscribeEvent
public void onTick(TickEvent.Post event) { public void onTick(TickEvent.Post event) {
if (rainbow.isEnabled()) { if (color.isRainbow()) {
Color color = Colors.rainbowColor(rainbowSpeed.getIntValue(), alpha.getIntValue(), saturation.getFloatValue(), brightness.getFloatValue()); Colors.red = color.getR();
Colors.green = color.getG();
Colors.red = color.getRed(); Colors.blue = color.getB();
Colors.green = color.getGreen(); Colors.updateAllColors(new Color(Colors.red, Colors.green, Colors.blue, Colors.alpha));
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
));
}
} }
@@ -5,6 +5,8 @@ import me.retucio.camtweaks.module.settings.*;
import me.retucio.camtweaks.ui.screen.HudEditorScreen; import me.retucio.camtweaks.ui.screen.HudEditorScreen;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
import java.awt.*;
/** lógica del HUD manejada en: /** lógica del HUD manejada en:
* @see me.retucio.camtweaks.ui.HudRenderer * @see me.retucio.camtweaks.ui.HudRenderer
* @see me.retucio.camtweaks.ui.widgets.HudElement * @see me.retucio.camtweaks.ui.widgets.HudElement
@@ -16,17 +18,9 @@ public class HUD extends Module {
// editor // editor
public KeySetting editorKey = addSetting(new KeySetting("tecla del editor", "tecla asignada al editor de elementos del hud", GLFW.GLFW_KEY_PAGE_UP)); public KeySetting editorKey = addSetting(new KeySetting("tecla del editor", "tecla asignada al editor de elementos del hud", GLFW.GLFW_KEY_PAGE_UP));
// colores
public NumberSetting red = addSetting(new NumberSetting("rojo", "cantidad de rojo", 255, 0, 255, 1));
public NumberSetting green = addSetting(new NumberSetting("verde", "cantidad de verde", 255, 0, 255, 1));
public NumberSetting blue = addSetting(new NumberSetting("azul", "cantidad de azul", 255, 0, 255, 1));
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));
// ajustes // ajustes
public ColorSetting color = addSetting(new ColorSetting("color", "color del texto de los elementos del HUD",
new Color(255, 255, 255, 255), false));
public BooleanSetting showOnF3 = addSetting(new BooleanSetting("mostrar en F3", "renderizar HUD en el menú de debug", false)); public BooleanSetting showOnF3 = addSetting(new BooleanSetting("mostrar en F3", "renderizar HUD en el menú de debug", false));
public BooleanSetting showOnChat = addSetting(new BooleanSetting("mostrar en chat", "renderizar HUD en la pantalla del chat", false)); public BooleanSetting showOnChat = addSetting(new BooleanSetting("mostrar en chat", "renderizar HUD en la pantalla del chat", false));
@@ -37,13 +31,6 @@ public class HUD extends Module {
public HUD() { public HUD() {
super("HUD", "superposición de la pantalla con info. adicional"); 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);
});
} }
public enum TimeFormat { public enum TimeFormat {
@@ -0,0 +1,95 @@
package me.retucio.camtweaks.module.modules;
import me.retucio.camtweaks.event.SubscribeEvent;
import me.retucio.camtweaks.event.events.RenderWorldEvent;
import me.retucio.camtweaks.module.Module;
import me.retucio.camtweaks.module.settings.BooleanSetting;
import me.retucio.camtweaks.module.settings.ColorSetting;
import me.retucio.camtweaks.module.settings.NumberSetting;
import me.retucio.camtweaks.util.render.RenderUtil;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.BlockView;
import net.minecraft.world.LightType;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
public class LightOverlay extends Module {
public NumberSetting radius = addSetting(new NumberSetting("radio", "radio a tener en cuenta al renderizar superposición",
16, 5, 128, 1));
public NumberSetting yRadius = addSetting(new NumberSetting("rango vertical", "distancia vertical a tener en cuenta",
4, 1, 16, 1));
public NumberSetting interval = addSetting(new NumberSetting("intervalo", "cada cuántos ticks comprobar el nivel de luz",
10, 1, 80, 1));
public ColorSetting lightColor = addSetting(new ColorSetting("color de la luz", "color de los bloques con luz",
new Color(0, 255, 0, 67), false));
public ColorSetting darknessColor = addSetting(new ColorSetting("color de oscuridad", "color de bloques con 0 luz",
new Color(255, 0, 0, 67), false));
public BooleanSetting onWater = addSetting(new BooleanSetting("en agua", "mostrar también bloques cubiertos en agua", true));
List<BlockPos> blocks = new ArrayList<>();
public LightOverlay() {
super("superposición de luz", "te muestra el nivel de luz en bloques, para prevenir mob spawns");
}
@SubscribeEvent
public void onRenderWorld(RenderWorldEvent event) {
if (mc.player == null || mc.world == null) return;
if (mc.player.age % interval.getIntValue() == 0) {
blocks = findExposedBlocks(
radius.getIntValue(),
yRadius.getIntValue()
);
}
for (BlockPos block : blocks) {
if (!mc.world.isTopSolid(block, mc.player) || !mc.world.getBlockState(block).isOpaque()) continue;
int light = mc.world.getLightLevel(LightType.BLOCK, block.up());
Color color = light == 0 ? darknessColor.getColor()
: new Color(
(lightColor.getR() / 15) * light,
(lightColor.getG() / 15) * light,
(lightColor.getB() / 15) * light,
lightColor.getA());
RenderUtil.drawBlockFaceFilled(event.getMatrices(), block, Direction.UP, color, 0.001f);
}
}
private List<BlockPos> findExposedBlocks(int radius, int yRadius) {
List<BlockPos> results = new ArrayList<>();
BlockPos pos = mc.player.getBlockPos();
int minX = pos.getX() - radius;
int maxX = pos.getX() + radius;
int minY = Math.max(mc.world.getDimension().minY(), pos.getY() - yRadius);
int maxY = Math.min(mc.world.getDimension().height() - 1, pos.getY() + yRadius);
int minZ = pos.getZ() - radius;
int maxZ = pos.getZ() + radius;
maxY = Math.min(maxY, mc.world.getDimension().height() - 2);
for (int x = minX; x <= maxX; x++) {
for (int z = minZ; z <= maxZ; z++) {
for (int y = minY; y <= maxY; y++) {
BlockPos current = new BlockPos(x, y, z);
BlockPos above = current.up();
if (!mc.world.isAir(current) && (mc.world.isAir(above) || (mc.world.isWater(above) && onWater.isEnabled())))
results.add(current);
}
}
}
return results;
}
}
@@ -1,22 +1,22 @@
package me.retucio.camtweaks.module.modules; package me.retucio.camtweaks.module.modules;
import me.retucio.camtweaks.event.SubscribeEvent; import me.retucio.camtweaks.event.SubscribeEvent;
import me.retucio.camtweaks.event.events.AddEntityEvent;
import me.retucio.camtweaks.event.events.RenderWorldEvent; import me.retucio.camtweaks.event.events.RenderWorldEvent;
import me.retucio.camtweaks.event.events.camtweaks.AddEntityEvent; import me.retucio.camtweaks.event.events.TickEvent;
import me.retucio.camtweaks.event.events.camtweaks.RemoveEntityEvent;
import me.retucio.camtweaks.module.Module; import me.retucio.camtweaks.module.Module;
import me.retucio.camtweaks.module.ModuleManager; import me.retucio.camtweaks.module.ModuleManager;
import me.retucio.camtweaks.module.settings.BooleanSetting; import me.retucio.camtweaks.module.settings.BooleanSetting;
import me.retucio.camtweaks.module.settings.NumberSetting; import me.retucio.camtweaks.module.settings.ColorSetting;
import me.retucio.camtweaks.module.settings.EnumSetting;
import me.retucio.camtweaks.util.render.RenderUtil; import me.retucio.camtweaks.util.render.RenderUtil;
import net.minecraft.client.network.OtherClientPlayerEntity; import net.minecraft.client.network.OtherClientPlayerEntity;
import net.minecraft.client.render.*; import net.minecraft.client.network.PlayerListEntry;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.math.Box;
import org.joml.*; import net.minecraft.world.dimension.DimensionType;
import java.awt.*; import java.awt.*;
import java.time.Instant; import java.time.Instant;
@@ -25,91 +25,261 @@ import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.UUID;
// lógica sutilmente robada de MeteorClient porque la mía era una mierda
public class LogoutSpots extends Module { public class LogoutSpots extends Module {
public BooleanSetting filledBox = addSetting(new BooleanSetting("caja rellena", "rellenar caja", true)); public BooleanSetting outlines = addSetting(new BooleanSetting("contorno", "renderizar contorno de la caja (lados)", true));
public BooleanSetting outlineBox = addSetting(new BooleanSetting("caja de esquinas", "contorno de caja", true)); public ColorSetting outlineColor = addSetting(new ColorSetting("color del contorno", "Color de las líneas", new Color(255, 0, 0, 230), false));
public NumberSetting red = addSetting(new NumberSetting("rojo", "cantidad de rojo", 200, 0, 255, 1)); public BooleanSetting filling = addSetting(new BooleanSetting("relleno", "renderizar relleno de la caja (caras)", true));
public NumberSetting green = addSetting(new NumberSetting("verde", "cantidad de verde", 90, 0, 255, 1)); public ColorSetting fillingColor = addSetting(new ColorSetting("color del relleno", "Color de los lados", new Color(230, 0, 0, 55), false));
public NumberSetting blue = addSetting(new NumberSetting("azul", "cantidad de azul", 255, 0, 255, 1));
public NumberSetting alpha = addSetting(new NumberSetting("opacidad", "antitransparencia", 50, 0, 255, 1));
public NumberSetting lineWidth = addSetting(new NumberSetting("grosor", "grosor de las líneas a dibujar", public BooleanSetting fullHeight = addSetting(new BooleanSetting("hitbox completa", "renderizar la caja completa de la hitbox, o solo marcar la posición", true));
2, 1, 10, 0.5f));
private final List<LogoutBox> boxes = new ArrayList<>(); public BooleanSetting dummy = addSetting(new BooleanSetting("monigote", "spawnear un monigote para marcar la posición", true));
public EnumSetting<Nametags.HealthMode> healthMode = addSetting(new EnumSetting<>("formato de vida", "en qué formato mostrar la vida del jugador",
Nametags.HealthMode.class, Nametags.HealthMode.POINTS));
private final List<LogoutEntry> players = new ArrayList<>();
private final List<PlayerListEntry> lastPlayerList = new ArrayList<>();
private final List<PlayerEntity> lastPlayers = new ArrayList<>();
private int timer;
private DimensionType lastDimension;
public LogoutSpots() { public LogoutSpots() {
super("puntos de desconexión", "te muestra los puntos donde se desconectan los jugadores"); super("puntos de desconexión", "te muestra los puntos donde otros jugadores se desconectan");
outlines.onUpdate(v -> {
outlineColor.setVisible(v);
fullHeight.setVisible(v || filling.isEnabled());
});
filling.onUpdate(v -> {
fillingColor.setVisible(v);
fullHeight.setVisible(v || outlines.isEnabled());
});
dummy.onUpdate(v -> {
if (!v) removeDummies();
healthMode.setVisible(v);
});
}
@Override
public void onEnable() {
if (mc.getNetworkHandler() != null) {
lastPlayerList.clear();
lastPlayerList.addAll(mc.getNetworkHandler().getPlayerList());
}
updateLastPlayers();
timer = 10;
if (mc.world != null) lastDimension = mc.world.getDimension();
super.onEnable();
}
@Override
public void onDisable() {
removeDummies();
players.clear();
lastPlayerList.clear();
lastPlayers.clear();
super.onDisable();
}
@Override
public void onTick() {
if (mc.world == null || mc.getNetworkHandler() == null) return;
if (mc.getNetworkHandler().getPlayerList().size() != lastPlayerList.size()) {
for (PlayerListEntry entry : lastPlayerList) {
boolean stillOnline = mc.getNetworkHandler().getPlayerList().stream()
.anyMatch(playerEntry -> playerEntry.getProfile().id().equals(entry.getProfile().id()));
if (stillOnline) continue;
// encontrar al jugador que se ha desconectado
for (PlayerEntity player : lastPlayers) {
if (player.getUuid().equals(entry.getProfile().id())) {
LogoutEntry logoutEntry = new LogoutEntry(player);
if (mc.world != null && !mc.world.hasEntity(logoutEntry.dummy) && dummy.isEnabled())
mc.world.addEntity(logoutEntry.dummy);
addLogoutSpot(logoutEntry);
break;
}
}
}
lastPlayerList.clear();
lastPlayerList.addAll(mc.getNetworkHandler().getPlayerList());
updateLastPlayers();
}
if (timer <= 0) {
updateLastPlayers();
timer = 10;
} else {
timer--;
}
// borrar todos los logout spots al cambiar de dimensión
DimensionType currentDimension = mc.world.getDimension();
if (currentDimension != lastDimension) {
for (LogoutEntry entry : players) {
if (entry.dummy != null) {
entry.dummy.remove(Entity.RemovalReason.KILLED);
entry.dummy.onRemoved();
}
}
players.clear();
}
lastDimension = currentDimension;
}
@SubscribeEvent
public void onEntityAdded(AddEntityEvent event) {
if (event.getEntity() instanceof PlayerEntity player) {
for (LogoutEntry entry : players) {
if (entry.uuid.equals(player.getUuid())) {
if (entry.dummy != null && mc.world != null) {
if (mc.world.getEntityById(entry.dummy.getId()) != null) {
entry.dummy.remove(Entity.RemovalReason.KILLED);
entry.dummy.onRemoved();
}
}
players.remove(entry);
break;
}
}
}
} }
@SubscribeEvent @SubscribeEvent
public void onWorldRender(RenderWorldEvent event) { public void onWorldRender(RenderWorldEvent event) {
if (mc.player == null || mc.world == null) return; if (mc.player == null || mc.world == null) return;
int r = red.getIntValue(); for (LogoutEntry entry : players)
int g = green.getIntValue(); entry.renderBox(event.getMatrices());
int b = blue.getIntValue(); }
int a = alpha.getIntValue();
MatrixStack matrices = event.getMatrices(); private void addLogoutSpot(LogoutEntry entry) {
for (LogoutEntry e : players) {
if (e.uuid.equals(entry.uuid)) {
if (e.dummy != null && mc.world != null) {
if (mc.world.getEntityById(e.dummy.getId()) != null) {
e.dummy.remove(Entity.RemovalReason.KILLED);
e.dummy.onRemoved();
}
}
players.remove(e);
break;
}
}
for (LogoutBox box : boxes) { players.add(entry);
if (filledBox.isEnabled()) }
RenderUtil.drawFilledBox(matrices, box.dummy.getBoundingBox(), new Color(r, g, b, a));
if (outlineBox.isEnabled()) private void updateLastPlayers() {
RenderUtil.drawOutlineBox(matrices, box.dummy.getBoundingBox(), new Color(r, g, b, a), lineWidth.getFloatValue()); if (mc.world == null) return;
lastPlayers.clear();
for (Entity entity : mc.world.getEntities())
if (entity instanceof PlayerEntity player && player != mc.player)
lastPlayers.add(player);
}
private void removeDummies() {
for (LogoutEntry entry : players) {
if (entry.dummy != null) {
entry.dummy.remove(Entity.RemovalReason.KILLED);
entry.dummy.onRemoved();
}
} }
} }
@SubscribeEvent
public void onEntityRemoved(RemoveEntityEvent event) {
if (event.getEntity() instanceof PlayerEntity player && player != mc.player) {
if (mc.world != null && mc.world.hasEntity(player)) return; // asegurarse de que salirse de la distancia de renderizado no cuenta como "desconectarse"
String playerName = player.getName().getString() + " (" + getLogoutTime(System.currentTimeMillis()) + ")";
boxes.add(new LogoutBox( private class LogoutEntry {
ModuleManager.INSTANCE.getModuleByClass(FakePlayer.class).addPlayer(player, playerName),
System.currentTimeMillis() public final double x, y, z;
)); public final double xWidth, zWidth, halfWidth, height;
public final UUID uuid;
public final String name;
public final int health;
public final String logoutTime;
public final String dummyName;
public final OtherClientPlayerEntity dummy;
public LogoutEntry(PlayerEntity player) {
this.halfWidth = player.getWidth() / 2;
this.x = player.getX() - halfWidth;
this.y = player.getY();
this.z = player.getZ() - halfWidth;
Box box = player.getBoundingBox();
this.xWidth = box.getLengthX();
this.zWidth = box.getLengthZ();
this.height = box.getLengthY();
this.uuid = player.getUuid();
this.name = player.getName().getString();
this.health = Math.round(player.getHealth() + player.getAbsorptionAmount());
this.logoutTime = getLogoutTime();
String healthText = healthMode.is(Nametags.HealthMode.HEARTS)
? String.format("%.2f", (float) health / 2)
: health + "hp";
this.dummyName = name + " [" + healthText + "] (" + logoutTime + ")";
this.dummy = ModuleManager.INSTANCE.getModuleByClass(FakePlayer.class).addPlayer(player, dummyName);
this.dummy.updatePositionAndAngles(x + halfWidth, y, z + halfWidth,
player.getYaw(), player.getPitch());
}
private String getLogoutTime() {
try {
HUD hud = ModuleManager.INSTANCE.getModuleByClass(HUD.class);
Instant instant = Instant.now();
ZoneOffset offset = ZoneOffset.ofHours(hud.timezone.getIntValue());
LocalTime logoutTime = LocalTime.from(instant.atOffset(offset));
boolean is24 = hud.timeFormat.is(HUD.TimeFormat.TWENTY_FOUR_HOUR);
DateTimeFormatter format = DateTimeFormatter.ofPattern(is24 ? "HH:mm" : "hh:mm a");
return logoutTime.format(format);
} catch (Exception e) {
return "??:??";
}
}
public void renderBox(MatrixStack matrices) {
if (fullHeight.isEnabled()) {
if (outlines.isEnabled())
RenderUtil.drawOutlineBox(matrices, new Box(x, y, z, x + xWidth, y + height, z + zWidth), outlineColor.getColor(), 1.5);
if (filling.isEnabled())
RenderUtil.drawFilledBox(matrices, new Box(x, y, z, x + xWidth, y + height, z + zWidth), fillingColor.getColor());
} else {
if (outlines.isEnabled()) {
Box bottomBox = new Box(x, y, z, x + xWidth, y + 0.01, z + zWidth);
RenderUtil.drawOutlineBox(matrices, bottomBox, outlineColor.getColor(), 1.5);
}
if (filling.isEnabled()) {
RenderUtil.drawBlockFaceFilled(matrices,
net.minecraft.util.math.BlockPos.ofFloored(x + halfWidth, y, z + halfWidth),
net.minecraft.util.math.Direction.UP, fillingColor.getColor(), 0.001f);
}
}
} }
} }
@SubscribeEvent
public void onEntityAdded(AddEntityEvent event) {
boxes.removeIf(box -> event.getEntity().getUuid().equals(box.dummy.getUuid()));
}
@Override
public void onDisable() {
boxes.forEach(box -> {
box.dummy.setRemoved(Entity.RemovalReason.KILLED);
box.dummy.onRemoved();
});
boxes.clear();
super.onDisable();
}
private String getLogoutTime(long logoutTimeMillis) {
HUD hud = ModuleManager.INSTANCE.getModuleByClass(HUD.class);
Instant instant = Instant.ofEpochMilli(logoutTimeMillis);
ZoneOffset offset = ZoneOffset.ofHours(hud.timezone.getIntValue());
LocalTime logoutTime = LocalTime.from(instant.atOffset(offset));
boolean is24 = hud.timeFormat.is(HUD.TimeFormat.TWENTY_FOUR_HOUR);
DateTimeFormatter format = DateTimeFormatter.ofPattern(is24 ? "HH:mm" : "hh:mm a");
return logoutTime.format(format);
}
public record LogoutBox(
OtherClientPlayerEntity dummy,
long logoutTime
) {}
} }
@@ -0,0 +1,34 @@
package me.retucio.camtweaks.module.modules;
import me.retucio.camtweaks.event.SubscribeEvent;
import me.retucio.camtweaks.event.events.DisconnectEvent;
import me.retucio.camtweaks.module.Module;
import net.minecraft.client.gui.screen.multiplayer.ConnectScreen;
import net.minecraft.client.network.ServerAddress;
import net.minecraft.client.network.ServerInfo;
public class Reconnect extends Module {
private ServerInfo lastServer = null;
public Reconnect() {
super("reconectar", "añade un botón para reconectarse a un servidor tras ser desconectado");
}
@SubscribeEvent
public void onDisconnect(DisconnectEvent event) {
lastServer = event.getServer();
}
public void reconnect() {
if (lastServer == null) return;
ConnectScreen.connect(
null,
mc,
ServerAddress.parse(lastServer.address),
lastServer,
false,
null
);
}
}
@@ -6,6 +6,7 @@ import me.retucio.camtweaks.module.Module;
import me.retucio.camtweaks.module.settings.BooleanSetting; import me.retucio.camtweaks.module.settings.BooleanSetting;
import me.retucio.camtweaks.module.settings.EnumSetting; import me.retucio.camtweaks.module.settings.EnumSetting;
import me.retucio.camtweaks.module.settings.NumberSetting; import me.retucio.camtweaks.module.settings.NumberSetting;
import me.retucio.camtweaks.util.ChatUtil;
import net.minecraft.network.packet.s2c.play.WorldTimeUpdateS2CPacket; import net.minecraft.network.packet.s2c.play.WorldTimeUpdateS2CPacket;
// continúa en ClientWorldPropertiesMixin, DimensionTypeMixin, // continúa en ClientWorldPropertiesMixin, DimensionTypeMixin,
@@ -29,12 +30,14 @@ public class TimeChanger extends Module {
public void onEnable() { public void onEnable() {
if (mc.world == null) return; if (mc.world == null) return;
realTime = mc.world.getTime(); realTime = mc.world.getTime();
super.onEnable();
} }
@Override @Override
public void onDisable() { public void onDisable() {
if (mc.world == null) return; if (mc.world == null) return;
mc.world.getLevelProperties().setTimeOfDay(realTime); mc.world.getLevelProperties().setTimeOfDay(realTime);
super.onDisable();
} }
@SubscribeEvent @SubscribeEvent
@@ -55,7 +58,7 @@ public class TimeChanger extends Module {
if (mc.world == null) return -1; if (mc.world == null) return -1;
return switch (moonPhase.getValue()) { return switch (moonPhase.getValue()) {
case DEFAULT -> (int) (mc.world.getLunarTime() / 24000L) % 8; case DEFAULT -> -1;
case FULL_MOON -> 0; case FULL_MOON -> 0;
case WANING_GIBBOUS -> 1; case WANING_GIBBOUS -> 1;
case LAST_QUARTER -> 2; case LAST_QUARTER -> 2;
@@ -1,7 +1,5 @@
package me.retucio.camtweaks.module.modules; package me.retucio.camtweaks.module.modules;
import me.retucio.camtweaks.event.SubscribeEvent;
import me.retucio.camtweaks.event.events.DamageItemEvent;
import me.retucio.camtweaks.module.Module; import me.retucio.camtweaks.module.Module;
import me.retucio.camtweaks.module.settings.BooleanSetting; import me.retucio.camtweaks.module.settings.BooleanSetting;
import me.retucio.camtweaks.module.settings.NumberSetting; import me.retucio.camtweaks.module.settings.NumberSetting;
@@ -11,7 +9,13 @@ import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvents; import net.minecraft.sound.SoundEvents;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.util.Formatting; import net.minecraft.util.Formatting;
import net.minecraft.util.Hand;
import java.util.ArrayList;
import java.util.List;
// al parecer DamageItemEvent no se lanza si estás en un server de Paper, o sea que ahora se usa onTick()
public class WarnLowDurability extends Module { public class WarnLowDurability extends Module {
public NumberSetting limitPercentage = addSetting(new NumberSetting("porcentaje", "porcentaje de durabilidad restante a la que se te avisa", public NumberSetting limitPercentage = addSetting(new NumberSetting("porcentaje", "porcentaje de durabilidad restante a la que se te avisa",
@@ -20,18 +24,21 @@ public class WarnLowDurability extends Module {
public BooleanSetting message = addSetting(new BooleanSetting("mensaje", "enviar un mensaje para alertar al usuario", true)); public BooleanSetting message = addSetting(new BooleanSetting("mensaje", "enviar un mensaje para alertar al usuario", true));
public BooleanSetting sound = addSetting(new BooleanSetting("sonido", "reproducir un sonido para alertar al usuario", true)); public BooleanSetting sound = addSetting(new BooleanSetting("sonido", "reproducir un sonido para alertar al usuario", true));
private final List<ItemStack> warned = new ArrayList<>();
public WarnLowDurability() { public WarnLowDurability() {
super("aviso de baja dur.", "te avisa cuando la herramienta que sostengas sobrepase un límite de durabilidad"); super("aviso de baja dur.", "te avisa cuando la herramienta que sostengas sobrepase un límite de durabilidad");
} }
@SubscribeEvent @Override
public void onDecreaseDurability(DamageItemEvent event) { public void onTick() {
if (mc.player == null || mc.world == null) return; if (mc.player == null || mc.world == null) return;
ItemStack stack = event.getStack(); ItemStack stack = mc.player.getStackInHand(Hand.MAIN_HAND);
if (warned.contains(stack)) return;
float percentage = (1 - (float) stack.getDamage() / stack.getMaxDamage()) * 100;
double percentage = 100 * (1 - ((double) stack.getDamage() / stack.getMaxDamage()));
if (percentage <= limitPercentage.getValue()) { if (percentage <= limitPercentage.getValue()) {
if (sound.isEnabled()) if (sound.isEnabled())
mc.world.playSound(mc.player, mc.player.getBlockPos(), mc.world.playSound(mc.player, mc.player.getBlockPos(),
SoundEvents.BLOCK_BELL_USE, SoundCategory.AMBIENT, 1, 1); SoundEvents.BLOCK_BELL_USE, SoundCategory.AMBIENT, 1, 1);
@@ -42,8 +49,16 @@ public class WarnLowDurability extends Module {
+ Formatting.GREEN + customName + Formatting.RESET + Formatting.GREEN + customName + Formatting.RESET
+ " a " + Formatting.GOLD + ((int) percentage + "") + "%" + " a " + Formatting.GOLD + ((int) percentage + "") + "%"
+ Formatting.RESET + " de durabilidad"); + Formatting.RESET + " de durabilidad");
mc.execute(() -> ChatUtil.warn(text)); // en mc.execute porque si lo llamo directamente, lo hago desde el thread del server que causa un error ChatUtil.warn(text);
} }
warned.add(stack);
} }
} }
@Override
public void onDisable() {
warned.clear();
super.onDisable();
}
} }
@@ -1,6 +1,5 @@
package me.retucio.camtweaks.module.modules; package me.retucio.camtweaks.module.modules;
import me.retucio.camtweaks.CameraTweaks;
import me.retucio.camtweaks.event.SubscribeEvent; import me.retucio.camtweaks.event.SubscribeEvent;
import me.retucio.camtweaks.event.events.GetFOVEvent; import me.retucio.camtweaks.event.events.GetFOVEvent;
import me.retucio.camtweaks.event.events.MouseScrollEvent; import me.retucio.camtweaks.event.events.MouseScrollEvent;
@@ -37,8 +36,7 @@ public class Zoom extends Module {
private double value; private double value;
public Zoom() { public Zoom() {
super("zoom", "lupa"); super("zoom", "lupa", GLFW.GLFW_KEY_F);
assignKey(GLFW.GLFW_KEY_F);
keyMode.setDefaultValue(KeyModes.HOLD); keyMode.setDefaultValue(KeyModes.HOLD);
keyMode.setValue(KeyModes.HOLD); keyMode.setValue(KeyModes.HOLD);
@@ -0,0 +1,278 @@
package me.retucio.camtweaks.module.settings;
import me.retucio.camtweaks.util.Colors;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import java.awt.*;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;
public class ColorSetting extends AbstractSetting {
private Color color;
private Consumer<Color> updateListener;
private Color defaultColor;
private boolean defaultRainbow;
private int defaultRainbowSpeed;
private int r, g, b, a;
private boolean rainbow;
private int rainbowSpeed;
private float saturation;
private float brightness;
public ColorSetting(String name, String description, Color defaultColor, boolean rainbow) {
super(name, description);
this.color = this.defaultColor = defaultColor;
this.r = defaultColor.getRed();
this.g = defaultColor.getGreen();
this.b = defaultColor.getBlue();
this.a = defaultColor.getAlpha();
this.rainbow = rainbow;
this.defaultRainbow = rainbow;
this.rainbowSpeed = 1000;
this.defaultRainbowSpeed = rainbowSpeed;
this.saturation = 1f;
this.brightness = 1f;
}
public Color getColor() {
if (rainbow) return Colors.rainbowColor(rainbowSpeed, a, saturation, brightness);
return color;
}
public int getR() {
return getColor().getRed();
}
public void setR(int r) {
if (this.r != r) {
this.r = Math.clamp(r, 0, 255);
updateColorFromRGB();
fireUpdateEvent();
if (updateListener != null) updateListener.accept(color);
}
}
public int getG() {
return getColor().getGreen();
}
public void setG(int g) {
if (this.g != g) {
this.g = Math.clamp(g, 0, 255);
updateColorFromRGB();
fireUpdateEvent();
if (updateListener != null) updateListener.accept(color);
}
}
public int getB() {
return getColor().getBlue();
}
public void setB(int b) {
if (this.b != b) {
this.b = Math.clamp(b, 0, 255);
updateColorFromRGB();
fireUpdateEvent();
if (updateListener != null) updateListener.accept(color);
}
}
public int getA() {
return a;
}
public void setA(int a) {
if (this.a != a) {
this.a = Math.clamp(a, 0, 255);
updateColorFromRGB();
fireUpdateEvent();
if (updateListener != null) updateListener.accept(color);
}
}
private void updateColorFromRGB() {
this.color = new Color(r, g, b, a);
}
public void setColor(Color color) {
if (!this.color.equals(color)) {
this.color = color;
this.r = color.getRed();
this.g = color.getGreen();
this.b = color.getBlue();
this.a = color.getAlpha();
fireUpdateEvent();
if (updateListener != null) updateListener.accept(color);
}
}
public void setRGB(int r, int g, int b) {
setRGB(r, g, b, this.a);
}
public void setRGB(int r, int g, int b, int a) {
boolean changed = false;
if (this.r != r) {
this.r = Math.clamp(r, 0, 255);
changed = true;
}
if (this.g != g) {
this.g = Math.clamp(g, 0, 255);
changed = true;
}
if (this.b != b) {
this.b = Math.clamp(b, 0, 255);
changed = true;
}
if (this.a != a) {
this.a = Math.clamp(a, 0, 255);
changed = true;
}
if (changed) {
updateColorFromRGB();
fireUpdateEvent();
if (updateListener != null) updateListener.accept(color);
}
}
public boolean isRainbow() {
return rainbow;
}
public void setRainbow(boolean rainbow) {
if (this.rainbow != rainbow) {
this.rainbow = rainbow;
fireUpdateEvent();
if (updateListener != null) updateListener.accept(getColor());
}
}
public int getRainbowSpeed() {
return rainbowSpeed;
}
public void setRainbowSpeed(int rainbowSpeed) {
if (this.rainbowSpeed != rainbowSpeed) {
this.rainbowSpeed = rainbowSpeed;
fireUpdateEvent();
if (updateListener != null && rainbow) updateListener.accept(getColor());
}
}
public float getSaturation() {
return saturation;
}
public void setSaturation(float saturation) {
if (this.saturation != saturation) {
this.saturation = Math.clamp(saturation, 0f, 1f);
fireUpdateEvent();
if (updateListener != null && rainbow) updateListener.accept(getColor());
}
}
public float getBrightness() {
return brightness;
}
public void setBrightness(float brightness) {
if (this.brightness != brightness) {
this.brightness = Math.clamp(brightness, 0f, 1f);
fireUpdateEvent();
if (updateListener != null && rainbow) updateListener.accept(getColor());
}
}
public Color getDefaultColor() {
return defaultColor;
}
public void setDefaultColor(Color defaultColor) {
this.defaultColor = defaultColor;
}
public int getDefaultR() {
return defaultColor.getRed();
}
public int getDefaultG() {
return defaultColor.getGreen();
}
public int getDefaultB() {
return defaultColor.getBlue();
}
public int getDefaultA() {
return defaultColor.getAlpha();
}
public float getDefaultSaturation() {
return 1.0f;
}
public float getDefaultBrightness() {
return 1.0f;
}
public boolean getDefaultRainbow() {
return defaultRainbow;
}
public int getDefaultRainbowSpeed() {
return defaultRainbowSpeed;
}
public int getRGB() {
return getColor().getRGB();
}
public Text getTooltipText() {
if (rainbow) return Text.literal("arcoíris");
return Text.literal(Colors.getFormatting(color) + Colors.ARGBtoHex(a, r, g, b));
}
public void reset() {
this.color = defaultColor;
this.r = defaultColor.getRed();
this.g = defaultColor.getGreen();
this.b = defaultColor.getBlue();
this.a = defaultColor.getAlpha();
this.rainbow = false;
this.rainbowSpeed = 2;
this.saturation = 1f;
this.brightness = 1f;
fireUpdateEvent();
if (updateListener != null) updateListener.accept(color);
}
public void onUpdate(Consumer<Color> listener) {
this.updateListener = listener;
if (updateListener != null) updateListener.accept(getColor());
}
public Map<String, ?> getConfigValue() {
Map<String, Object> map = new HashMap<>();
map.put("r", r);
map.put("g", g);
map.put("b", b);
map.put("a", a);
map.put("rb", rainbow);
map.put("rs", rainbowSpeed);
map.put("sat", saturation);
map.put("bri", brightness);
return map;
}
}
@@ -10,6 +10,7 @@ public class NumberSetting extends AbstractSetting {
private double value; private double value;
private double defaultValue; private double defaultValue;
private boolean locked;
private final double min; private final double min;
private final double max; private final double max;
@@ -33,6 +34,7 @@ public class NumberSetting extends AbstractSetting {
// como decía, el valor crece o decrece por el "increment" definido // como decía, el valor crece o decrece por el "increment" definido
public void increment(boolean positive) { public void increment(boolean positive) {
if (locked) return;
if (positive) value += increment; if (positive) value += increment;
else value -= increment; else value -= increment;
value = clamp(value, min, max); value = clamp(value, min, max);
@@ -57,7 +59,7 @@ public class NumberSetting extends AbstractSetting {
} }
public void setValue(double value) { public void setValue(double value) {
if (this.value == value) return; if (this.value == value || this.locked) return;
double clamped = clamp(value, min, max); double clamped = clamp(value, min, max);
this.value = Math.round(clamped / increment) * increment; this.value = Math.round(clamped / increment) * increment;
fireUpdateEvent(); fireUpdateEvent();
@@ -88,6 +90,14 @@ public class NumberSetting extends AbstractSetting {
return increment; return increment;
} }
public boolean isLocked() {
return locked;
}
public void setLocked(boolean locked) {
this.locked = locked;
}
public void onUpdate(Consumer<Double> listener) { public void onUpdate(Consumer<Double> listener) {
this.updateListener = listener; this.updateListener = listener;
if (updateListener != null) updateListener.accept(value); if (updateListener != null) updateListener.accept(value);
@@ -15,7 +15,9 @@ import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.ChatScreen; import net.minecraft.client.gui.screen.ChatScreen;
import net.minecraft.client.gui.screen.TitleScreen; import net.minecraft.client.gui.screen.TitleScreen;
import net.minecraft.client.network.PlayerListEntry;
import net.minecraft.client.render.RenderTickCounter; import net.minecraft.client.render.RenderTickCounter;
import net.minecraft.network.packet.s2c.play.WorldTimeUpdateS2CPacket;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import java.awt.*; import java.awt.*;
@@ -23,6 +25,7 @@ import java.time.LocalTime;
import java.time.ZoneOffset; import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -31,8 +34,11 @@ public class HudRenderer {
private static final MinecraftClient mc = MinecraftClient.getInstance(); private static final MinecraftClient mc = MinecraftClient.getInstance();
// tps
private static float estimatedTPS = 20f; private static float estimatedTPS = 20f;
private long lastPacketTime = 0; private static final List<Float> tpsHistory = new ArrayList<>();
private long lastWorldTime = -1L;
private long lastRealTime = -1L;
private static final Map<String, int[]> positions = ConfigManager.getConfig().hudPositions; private static final Map<String, int[]> positions = ConfigManager.getConfig().hudPositions;
private static final Map<String, Boolean> visibilities = ConfigManager.getConfig().hudVisibilities; private static final Map<String, Boolean> visibilities = ConfigManager.getConfig().hudVisibilities;
@@ -77,6 +83,11 @@ public class HudRenderer {
drawSnappedText(ctx, getElementText("time", delta, hud), mx, my, getColor(hud).getRGB(), hud.shadow.isEnabled()); drawSnappedText(ctx, getElementText("time", delta, hud), mx, my, getColor(hud).getRGB(), hud.shadow.isEnabled());
}); });
// ping
addElement("ping", 2, 2 * (mc.textRenderer.fontHeight + 4), (ctx, mx, my, delta) -> {
drawSnappedText(ctx, getElementText("ping", delta, hud), mx, my, getColor(hud).getRGB(), hud.shadow.isEnabled());
});
HudEditorScreen.INSTANCE.setElements(getElements()); HudEditorScreen.INSTANCE.setElements(getElements());
} }
@@ -96,10 +107,7 @@ public class HudRenderer {
} }
public static Color getColor(HUD hud) { public static Color getColor(HUD hud) {
if (hud.rainbow.isEnabled()) return hud.color.getColor();
return Colors.rainbowColor(hud.rainbowSpeed.getIntValue(), hud.alpha.getIntValue());
return new Color(hud.red.getIntValue(), hud.green.getIntValue(), hud.blue.getIntValue(), hud.alpha.getIntValue());
} }
public static void drawSnappedText(DrawContext ctx, String text, int x, int y, int color, boolean shadow) { public static void drawSnappedText(DrawContext ctx, String text, int x, int y, int color, boolean shadow) {
@@ -160,7 +168,7 @@ public class HudRenderer {
return "FPS: " + mc.getCurrentFps(); return "FPS: " + mc.getCurrentFps();
} }
case "tps" -> { case "tps" -> {
return "TPS: " + estimatedTPS; return String.format("TPS: %.1f", estimatedTPS);
} }
case "customText" -> { case "customText" -> {
return ModuleManager.INSTANCE.getModuleByClass(HUD.class).customText.getValue(); return ModuleManager.INSTANCE.getModuleByClass(HUD.class).customText.getValue();
@@ -173,25 +181,56 @@ public class HudRenderer {
DateTimeFormatter format = DateTimeFormatter.ofPattern(is24 ? "HH:mm" : "hh:mm a"); DateTimeFormatter format = DateTimeFormatter.ofPattern(is24 ? "HH:mm" : "hh:mm a");
return now.format(format); return now.format(format);
} }
case "ping" -> {
if (mc.getNetworkHandler() == null || mc.player == null) return "? ms";
if (mc.isInSingleplayer()) return "-1 ms";
PlayerListEntry playerListEntry = mc.getNetworkHandler().getPlayerListEntry(mc.player.getUuid());
return playerListEntry != null ? playerListEntry.getLatency() + " ms" : "? ms";
}
default -> { return id; } default -> { return id; }
} }
} }
@SubscribeEvent @SubscribeEvent
public void onReceivePacket(PacketEvent.Receive event) { public void onReceivePacket(PacketEvent.Receive event) {
long now = System.currentTimeMillis(); if (event.getPacket() instanceof WorldTimeUpdateS2CPacket packet) {
if (lastPacketTime > 0) { long currentWorldTime = packet.time();
float tps = 1000f / (now - lastPacketTime); long currentRealTime = System.currentTimeMillis();
estimatedTPS = Math.min(20f, tps);
if (lastWorldTime != -1L && lastRealTime != -1L) {
long elapsedRealTime = currentRealTime - lastRealTime;
long elapsedWorldTicks = currentWorldTime - lastWorldTime;
if (elapsedRealTime > 0) {
// TPS = (ticks passed) / (seconds passed)
float tps = (float) elapsedWorldTicks / (elapsedRealTime / 1000.0f);
// clampear
tps = Math.max(0.1f, Math.min(20.0f, tps));
// usar historial para suavizar resultados
tpsHistory.add(tps);
if (tpsHistory.size() > 10)
tpsHistory.removeFirst();
// calcular media de tps
float sum = 0;
for (float t : tpsHistory) sum += t;
estimatedTPS = sum / tpsHistory.size();
}
}
lastWorldTime = currentWorldTime;
lastRealTime = currentRealTime;
} }
lastPacketTime = now;
} }
/** para cuando se cambie el valor del texto custom */ /** para cuando se cambie el valor del texto custom */
@SubscribeEvent @SubscribeEvent
public void onUpdateSetting(UpdateSettingEvent event) { public void onUpdateSetting(UpdateSettingEvent event) {
if (ModuleManager.INSTANCE == null) return;
HUD hud = ModuleManager.INSTANCE.getModuleByClass(HUD.class); HUD hud = ModuleManager.INSTANCE.getModuleByClass(HUD.class);
if (event.getSetting() == hud.customText) { if (event.getSetting() == hud.customText) {
if (customTextElement != null) { if (customTextElement != null) {
int newX = mc.getWindow().getScaledWidth() / 2 - mc.textRenderer.getWidth(hud.customText.getValue()) / 2; int newX = mc.getWindow().getScaledWidth() / 2 - mc.textRenderer.getWidth(hud.customText.getValue()) / 2;
@@ -84,4 +84,7 @@ public class BindButton extends SettingButton {
public void mouseReleased(double mouseX, double mouseY, int button) { public void mouseReleased(double mouseX, double mouseY, int button) {
ClickGUI.INSTANCE.unselect(this); ClickGUI.INSTANCE.unselect(this);
} }
@Override
public void mouseDragged(double mouseX, double mouseY) {}
} }
@@ -0,0 +1,96 @@
package me.retucio.camtweaks.ui.buttons;
import me.retucio.camtweaks.module.Module;
import me.retucio.camtweaks.module.settings.ColorSetting;
import me.retucio.camtweaks.ui.screen.ClickGUI;
import me.retucio.camtweaks.ui.frames.SettingsFrame;
import me.retucio.camtweaks.util.ChatUtil;
import me.retucio.camtweaks.util.Colors;
import me.retucio.camtweaks.util.render.DrawUtil;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.text.Text;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
import static me.retucio.camtweaks.CameraTweaks.mc;
public class ColorButton extends SettingButton {
private final ColorSetting setting;
public ColorButton(ColorSetting setting, SettingsFrame parent, int offset) {
super(setting, parent, offset);
this.setting = setting;
}
@Override
public void render(DrawContext ctx, double mouseX, double mouseY, float delta) {
// fondo
Color bgColor = isHovered((int) mouseX, (int) mouseY)
? Colors.buttonColor.brighter()
: Colors.buttonColor;
ctx.fill(x, y, x + w, y + h, bgColor.getRGB());
// prev. del color
int previewSize = h - 6;
int previewX = x + 5;
int previewY = y + 3;
DrawUtil.drawBorder(ctx, previewX - 1, previewY - 1, previewSize + 2, previewSize + 2, setting.isRainbow() ? Colors.mainColor.getRGB() : -1);
ctx.fill(previewX, previewY, previewX + previewSize, previewY + previewSize, setting.getColor().getRGB());
// texto
String label = setting.getName();
int textX = previewX + previewSize + 5;
ctx.drawText(parent.mc.textRenderer, label, textX, y + 3, -1, true);
// valor actual
String valueText = setting.isRainbow() ? "gay." : Colors.ARGBtoHex(setting.getA(), setting.getR(), setting.getG(), setting.getB());
int valueWidth = parent.mc.textRenderer.getWidth(valueText);
ctx.drawText(parent.mc.textRenderer, valueText, x + w - valueWidth - 5, y + 3, -1, true);
}
@Override
public void drawTooltip(DrawContext ctx, double mouseX, double mouseY) {
if (isHovered((int) mouseX, (int) mouseY)) {
List<Text> tooltip = new ArrayList<>();
tooltip.add(Text.of(setting.getDescription()));
tooltip.add(setting.getTooltipText());
ctx.drawTooltip(mc.textRenderer, tooltip, (int) mouseX, (int) mouseY + 20);
}
}
@Override
public void mouseClicked(double mouseX, double mouseY, int button) {
if (isHovered((int) mouseX, (int) mouseY) && ClickGUI.INSTANCE.trySelect(this)) {
if (button == 0) {
// click izq.: abrir selector de colores
ClickGUI.INSTANCE.openColorPickerFrame(setting.getModule(), setting, parent.x + parent.w + 120, parent.renderY + offset);
} else if (button == 1 && mc.isShiftPressed()) {
// shift + clic dcho.: restablecer color
setting.reset();
}
}
}
@Override
public void mouseReleased(double mouseX, double mouseY, int button) {
ClickGUI.INSTANCE.unselect(this);
}
@Override
public void mouseDragged(double mouseX, double mouseY) {}
public ColorSetting getSetting() {
return setting;
}
public void refreshDummy() {
// This is called when the color picker frame needs to be refreshed
// We'll update any linked dummy module in the color picker frame
}
}
@@ -84,4 +84,7 @@ public class CycleButton<E extends Enum<E>> extends SettingButton {
public void mouseReleased(double mouseX, double mouseY, int button) { public void mouseReleased(double mouseX, double mouseY, int button) {
ClickGUI.INSTANCE.unselect(this); ClickGUI.INSTANCE.unselect(this);
} }
@Override
public void mouseDragged(double mouseX, double mouseY) {}
} }
@@ -116,4 +116,7 @@ public class ListButton<T> extends SettingButton {
public void mouseReleased(double mouseX, double mouseY, int button) { public void mouseReleased(double mouseX, double mouseY, int button) {
ClickGUI.INSTANCE.unselect(this); ClickGUI.INSTANCE.unselect(this);
} }
@Override
public void mouseDragged(double mouseX, double mouseY) {}
} }
@@ -10,7 +10,7 @@ import net.minecraft.text.Text;
// clase para el botón para cada módulo // clase para el botón para cada módulo
public class ModuleButton { public class ModuleButton {
public Module module; private final Module module;
public ModuleFrame parent; public ModuleFrame parent;
public int offset; public int offset;
public final int height = 18; public final int height = 18;
@@ -70,4 +70,8 @@ public class ModuleButton {
return isHovered((int) mouseX, (int) mouseY) ? Colors.mainColor.brighter().getRGB() : Colors.mainColor.getRGB(); 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(); return isHovered((int) mouseX, (int) mouseY) ? Colors.buttonColor.brighter().getRGB() : Colors.buttonColor.getRGB();
} }
public Module getModule() {
return module;
}
} }
@@ -24,6 +24,7 @@ public abstract class SettingButton {
public abstract void render(DrawContext ctx, double mouseX, double mouseY, float delta); public abstract void render(DrawContext ctx, double mouseX, double mouseY, float delta);
public abstract void mouseClicked(double mouseX, double mouseY, int button); public abstract void mouseClicked(double mouseX, double mouseY, int button);
public abstract void mouseReleased(double mouseX, double mouseY, int button); public abstract void mouseReleased(double mouseX, double mouseY, int button);
public abstract void mouseDragged(double mouseX, double mouseY);
// 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 // 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) { public void drawTooltip(DrawContext ctx, double mouseX, double mouseY) {
@@ -74,6 +74,9 @@ public class SliderButton extends SettingButton {
if (button == 0) dragging = false; if (button == 0) dragging = false;
} }
@Override
public void mouseDragged(double mouseX, double mouseY) {}
@SubscribeEvent @SubscribeEvent
public void onKey(KeyEvent event) { public void onKey(KeyEvent event) {
// de no ser de esto, si se cierra la interfaz sin haber soltado el ratón mientras se arrastraba el valor, al reabrir la interfaz se seguía arrastrando, aún habiendo soltado ya el clic // de no ser de esto, si se cierra la interfaz sin haber soltado el ratón mientras se arrastraba el valor, al reabrir la interfaz se seguía arrastrando, aún habiendo soltado ya el clic
@@ -55,6 +55,9 @@ public class TextButton extends SettingButton {
ClickGUI.INSTANCE.unselect(this); ClickGUI.INSTANCE.unselect(this);
} }
@Override
public void mouseDragged(double mouseX, double mouseY) {}
public void onKey(int key, int action) { public void onKey(int key, int action) {
if (!typing || action == GLFW.GLFW_RELEASE) return; if (!typing || action == GLFW.GLFW_RELEASE) return;
@@ -47,6 +47,9 @@ public class ToggleButton extends SettingButton {
ClickGUI.INSTANCE.unselect(this); ClickGUI.INSTANCE.unselect(this);
} }
@Override
public void mouseDragged(double mouseX, double mouseY) {}
public BooleanSetting getSetting() { public BooleanSetting getSetting() {
return setting; return setting;
} }
@@ -75,11 +75,17 @@ public class ClientSettingsFrame extends SettingsFrame {
} }
@Override @Override
public void mouseRelease(double mouseX, double mouseY, int button) { public void mouseReleased(double mouseX, double mouseY, int button) {
ClickGUI.INSTANCE.unselect(this); ClickGUI.INSTANCE.unselect(this);
if (button == 0 && dragging) if (button == 0 && dragging)
CameraTweaks.EVENT_BUS.post(new GUISettingsFrameEvent.Move()); CameraTweaks.EVENT_BUS.post(new GUISettingsFrameEvent.Move());
super.mouseRelease(mouseX, mouseY, button); super.mouseReleased(mouseX, mouseY, button);
}
@Override
public void drawTooltips(DrawContext ctx, double mouseX, double mouseY) {
if (!extended) return;
super.drawTooltips(ctx, mouseX, mouseY);
} }
} }
@@ -0,0 +1,493 @@
package me.retucio.camtweaks.ui.frames;
import me.retucio.camtweaks.module.Module;
import me.retucio.camtweaks.module.settings.AbstractSetting;
import me.retucio.camtweaks.module.settings.BooleanSetting;
import me.retucio.camtweaks.module.settings.ColorSetting;
import me.retucio.camtweaks.module.settings.NumberSetting;
import me.retucio.camtweaks.ui.buttons.*;
import me.retucio.camtweaks.ui.screen.ClickGUI;
import me.retucio.camtweaks.util.ChatUtil;
import me.retucio.camtweaks.util.Colors;
import me.retucio.camtweaks.util.render.DrawUtil;
import net.minecraft.client.gui.DrawContext;
import java.awt.*;
public class ColorPickerFrame extends SettingsFrame {
private final ColorSetting colorSetting;
private Color currentColor;
// Color picker state
private boolean pickingHue = false;
private boolean pickingSaturationBrightness = false;
private boolean pickingAlpha = false;
// Picker areas
private int huePickerX, huePickerY, huePickerWidth, huePickerHeight;
private int saturationBrightnessPickerX, saturationBrightnessPickerY, saturationBrightnessPickerWidth, saturationBrightnessPickerHeight;
private int alphaPickerX, alphaPickerY, alphaPickerWidth, alphaPickerHeight;
// ajustes
NumberSetting redSetting, greenSetting, blueSetting;
BooleanSetting rainbowSetting;
NumberSetting rainbowSpeedSetting;
NumberSetting saturationSetting, brightnessSetting;
public final Module dummyModule;
public ColorPickerFrame(Module module, ColorSetting colorSetting, int x, int y, int w, int h) {
super(module, x, y, w, h);
this.colorSetting = colorSetting;
this.currentColor = colorSetting.getColor();
dummyModule = new Module("selector de colores", "elige colores") {
@Override public void onEnable() {}
@Override public void onDisable() {}
};
// ocultar ajustes innecesarios
dummyModule.getSettings().forEach(s -> s.setVisible(false));
dummyModule.shouldSaveSettings(false);
// ajustes de color
redSetting = new NumberSetting("rojo", "cantidad de rojo", colorSetting.getR(), 0, 255, 1);
redSetting.setDefaultValue(colorSetting.getDefaultR());
greenSetting = new NumberSetting("verde", "cantidad de verde", colorSetting.getG(), 0, 255, 1);
greenSetting.setDefaultValue(colorSetting.getDefaultG());
blueSetting = new NumberSetting("azul", "cantidad de azul", colorSetting.getB(), 0, 255, 1);
blueSetting.setDefaultValue(colorSetting.getDefaultB());
// ajustes de arcoíris
rainbowSetting = new BooleanSetting("arcoíris", "gay.", colorSetting.isRainbow());
rainbowSetting.setDefaultValue(colorSetting.getDefaultRainbow());
rainbowSpeedSetting = new NumberSetting("velocidad del arcoíris", "velocidad de gaming", colorSetting.getRainbowSpeed(), 1, 10000, 2);
rainbowSpeedSetting.setDefaultValue(colorSetting.getDefaultRainbowSpeed());
saturationSetting = new NumberSetting("saturación", "intensidad de la homosexualidad", colorSetting.getSaturation(), 0, 1, 0.01f);
saturationSetting.setDefaultValue(colorSetting.getDefaultSaturation());
brightnessSetting = new NumberSetting("brillo", "brillo de la homosexualidad", colorSetting.getBrightness(), 0, 1, 0.01f);
brightnessSetting.setDefaultValue(colorSetting.getDefaultBrightness());
// añadir ajustes y tal
dummyModule.addSettings(redSetting, greenSetting, blueSetting, rainbowSpeedSetting, saturationSetting, brightnessSetting, rainbowSetting);
for (AbstractSetting setting : dummyModule.getSettings()) {
if (setting instanceof NumberSetting n) n.onUpdate(v -> updateColorFromSettings());
if (setting instanceof BooleanSetting b) b.onUpdate(v -> updateColorFromSettings());
rainbowSetting.onUpdate(v -> {
updateColorFromSettings();
redSetting.setVisible(!v);
greenSetting.setVisible(!v);
blueSetting.setVisible(!v);
rainbowSpeedSetting.setVisible(v);
saturationSetting.setVisible(v);
brightnessSetting.setVisible(v);
});
}
settingButtons.clear();
Module originalModule = this.module;
this.module = dummyModule;
// añadir botones
int offset = h;
for (var setting : dummyModule.getSettings()) {
switch (setting) {
case BooleanSetting b -> {
addButton(new ToggleButton(b, this, offset));
offset += 18;
}
case NumberSetting n -> {
addButton(new SliderButton(n, this, offset));
offset += 18;
}
default -> {}
}
}
this.module = originalModule;
}
// RENDERIZADO
@Override
public void render(DrawContext ctx, int mouseX, int mouseY, float delta) {
if (colorSetting == null) return;
updateWidth();
// al parecer este era el problema :/
for (AbstractSetting setting : dummyModule.getSettings())
if (setting instanceof NumberSetting ns) ns.setLocked(
pickingAlpha || pickingHue || pickingSaturationBrightness);
currentColor = colorSetting.getColor();
int padding = 5;
// cabezal
int centerY = renderY + h / 2;
int titleX = x + 8;
int titleY = centerY - mc.textRenderer.fontHeight / 2;
String title = colorSetting.getName();
ctx.fill(x, renderY, x + w, renderY + h, Colors.mainColor.getRGB());
ctx.drawText(mc.textRenderer, title, titleX, titleY, -1, true);
// botón de cerrar
int closeButtonColor = isCloseButtonHovered(mouseX, mouseY)
? Color.RED.getRGB()
: -1;
ctx.drawText(mc.textRenderer, "×", x + w - mc.textRenderer.getWidth("×") - 8, titleY, closeButtonColor, true);
int previewX = x + padding;
int previewY = renderY + h + padding;
int previewWidth = w - 2 * padding;
int previewHeight = 30;
// dimensiones
saturationBrightnessPickerX = x + padding;
saturationBrightnessPickerY = previewY + previewHeight + padding;
saturationBrightnessPickerWidth = w - 2 * padding - 20;
saturationBrightnessPickerHeight = 80;
huePickerX = saturationBrightnessPickerX + saturationBrightnessPickerWidth + 5;
huePickerY = saturationBrightnessPickerY;
huePickerWidth = 15;
huePickerHeight = saturationBrightnessPickerHeight;
alphaPickerX = x + padding;
alphaPickerY = saturationBrightnessPickerY + saturationBrightnessPickerHeight + padding;
alphaPickerWidth = w - 2 * padding;
alphaPickerHeight = 15;
int buttonAreaHeight = visibleButtons.size() * h;
int bgX1 = x;
int bgY1 = renderY + h + 1;
int bgX2 = x + w;
int bgY2 = bgY1 + previewHeight + saturationBrightnessPickerHeight + alphaPickerHeight
+ buttonAreaHeight + (padding * 6) - 11;
ctx.fill(bgX1, bgY1, bgX2, bgY2, Colors.frameBGColor.getRGB());
DrawUtil.drawBorder(ctx, previewX, previewY, previewWidth, previewHeight, -1);
if (colorSetting.isRainbow()) {
float hueStep = 1f / previewWidth;
int stripWidth = 2;
for (int i = 0; i < previewWidth; i += stripWidth) {
float hue = i * hueStep;
Color rainbowColor = Color.getHSBColor(hue, colorSetting.getSaturation(), colorSetting.getBrightness());
int endX = Math.min(i + stripWidth, previewWidth);
ctx.fill(previewX + i, previewY, previewX + endX, previewY + previewHeight,
(colorSetting.getA() << 24) | (rainbowColor.getRGB() & 0x00FFFFFF));
}
} else {
ctx.fill(previewX, previewY, previewX + previewWidth, previewY + previewHeight, currentColor.getRGB());
}
// hex del color actual
String hexText = colorSetting.isRainbow() ? "gay." : Colors.ARGBtoHex(colorSetting.getA(), colorSetting.getR(), colorSetting.getG(), colorSetting.getB());
int hexWidth = mc.textRenderer.getWidth(hexText);
ctx.drawText(mc.textRenderer, hexText, x + w / 2 - hexWidth / 2, previewY + previewHeight / 2 - mc.textRenderer.fontHeight / 2, -1, true);
// utilizar un gradiente combinado, para mejorar la optimización
renderSaturationBrightnessGradient(ctx);
DrawUtil.drawBorder(ctx, saturationBrightnessPickerX, saturationBrightnessPickerY,
saturationBrightnessPickerWidth, saturationBrightnessPickerHeight, -1);
float[] hsb1;
if (colorSetting.isRainbow()) {
float hue = (System.currentTimeMillis() % (colorSetting.getRainbowSpeed() * 1000L))
/ (float) (colorSetting.getRainbowSpeed() * 1000L);
hsb1 = new float[]{hue, colorSetting.getSaturation(), colorSetting.getBrightness()};
} else {
hsb1 = Color.RGBtoHSB(colorSetting.getR(), colorSetting.getG(), colorSetting.getB(), null);
}
int indicatorX = saturationBrightnessPickerX + (int)(hsb1[1] * saturationBrightnessPickerWidth);
int indicatorY = saturationBrightnessPickerY + (int)((1 - hsb1[2]) * saturationBrightnessPickerHeight);
DrawUtil.drawCircle(ctx, indicatorX, indicatorY, 3, -1);
// gradiente del "hue" (no sé cómo se dice en castellano)
for (int hy = 0; hy < huePickerHeight; hy += 2) {
float hue = 1.0f - (hy / (float) huePickerHeight);
Color hueColor = Color.getHSBColor(hue, 1.0f, 1.0f);
ctx.fill(huePickerX, huePickerY + hy, huePickerX + huePickerWidth,
huePickerY + Math.min(hy + 2, huePickerHeight), hueColor.getRGB());
}
DrawUtil.drawBorder(ctx, huePickerX, huePickerY, huePickerWidth, huePickerHeight, -1);
if (!colorSetting.isRainbow()) {
float[] hsb2 = Color.RGBtoHSB(colorSetting.getR(), colorSetting.getG(), colorSetting.getB(), null);
int hueIndicatorY = huePickerY + (int)((1 - hsb2[0]) * huePickerHeight);
DrawUtil.drawCircle(ctx, huePickerX + huePickerWidth / 2, hueIndicatorY, 3, -1);
}
renderAlphaGradient(ctx);
DrawUtil.drawBorder(ctx, alphaPickerX, alphaPickerY, alphaPickerWidth, alphaPickerHeight, -1);
int alphaIndicatorX = alphaPickerX + (int)((colorSetting.getA() / 255f) * alphaPickerWidth);
DrawUtil.drawCircle(ctx, alphaIndicatorX, alphaPickerY + alphaPickerHeight / 2, 3, -1);
totalHeight = previewHeight + saturationBrightnessPickerHeight + alphaPickerHeight + (padding * 4) + h;
// botones de ajustes
int startButtonY = alphaPickerY + alphaPickerHeight + padding;
visibleButtons = settingButtons.stream()
.filter(sb -> sb.getSetting().isVisible() && sb.getSetting().isSearchMatch())
.toList();
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;
}
totalHeight += (visibleButtons.size() * h) + padding;
}
private void renderSaturationBrightnessGradient(DrawContext ctx) {
float hue;
if (colorSetting.isRainbow()) {
hue = (System.currentTimeMillis() % (colorSetting.getRainbowSpeed() * 1000L))
/ (float) (colorSetting.getRainbowSpeed() * 1000L);
} else {
float[] hsb = Color.RGBtoHSB(colorSetting.getR(), colorSetting.getG(), colorSetting.getB(), null);
hue = hsb[0];
}
// gradiente horizontal
for (int sx = 0; sx < saturationBrightnessPickerWidth; sx++) {
float saturation = sx / (float) saturationBrightnessPickerWidth;
Color colorAtX = Color.getHSBColor(hue, saturation, 1);
ctx.fill(saturationBrightnessPickerX + sx, saturationBrightnessPickerY,
saturationBrightnessPickerX + sx + 1, saturationBrightnessPickerY + saturationBrightnessPickerHeight,
colorAtX.getRGB());
}
// gradiente vertical
for (int sy = 0; sy < saturationBrightnessPickerHeight; sy++) {
float brightness = 1 - (sy / (float) saturationBrightnessPickerHeight);
int alpha = (int)(brightness * 255);
Color overlay = new Color(0, 0, 0, alpha);
ctx.fill(saturationBrightnessPickerX, saturationBrightnessPickerY + sy,
saturationBrightnessPickerX + saturationBrightnessPickerWidth, saturationBrightnessPickerY + sy + 1,
overlay.getRGB());
}
}
private void renderAlphaGradient(DrawContext ctx) {
// dibujar casilleros alternando el tono de gris para el slider de la opacidad
DrawUtil.drawCheckerBoard(ctx, alphaPickerX + 1, alphaPickerY, alphaPickerWidth, alphaPickerHeight, 3, 0xFF333333, 0xFF666666);
if (colorSetting != null) {
int alphaWidth = (int)(alphaPickerWidth * (colorSetting.getA() / 255f));
int stripWidth = 2;
for (int ax = 0; ax < alphaWidth; ax += stripWidth) {
float alphaPos = (ax + (float) stripWidth / 2) / (float) alphaPickerWidth;
int alphaValue = (int)(alphaPos * 255);
Color overlayColor = !colorSetting.isRainbow() ?
new Color(colorSetting.getR(), colorSetting.getG(), colorSetting.getB(), alphaValue) :
new Color(255, 255, 255, alphaValue);
int stripEndX = Math.min(ax + stripWidth, alphaWidth);
ctx.fill(alphaPickerX + ax, alphaPickerY,
alphaPickerX + stripEndX, alphaPickerY + alphaPickerHeight, overlayColor.getRGB());
}
}
}
// DETECCIÓN DE INPUTS
@Override
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.dummyModule);
return;
}
if (button == 0) {
dragging = true;
dragX = (int) (mouseX - x);
dragY = (int) (mouseY - y);
} else if (button == 1) {
ClickGUI.INSTANCE.closeSettingsFrame(dummyModule);
}
}
// manejar interacciones del selector de colores
if (colorSetting != null) {
if (isSBPickerHovered(mouseX, mouseY)) {
pickingSaturationBrightness = true;
updateColorFromPicker((int) mouseX, (int) mouseY);
}
if (!colorSetting.isRainbow() && isHuePickerHovered(mouseX, mouseY)) {
pickingHue = true;
updateColorFromPicker((int) mouseX, (int) mouseY);
}
}
// opacidad
if (isAlphaPickerHovered(mouseX, mouseY)) {
pickingAlpha = true;
updateColorFromPicker((int) mouseX, (int) mouseY);
}
for (SettingButton sb : visibleButtons)
sb.mouseClicked(mouseX, mouseY, button);
}
@Override
public void mouseReleased(double mouseX, double mouseY, int button) {
ClickGUI.INSTANCE.unselect(this);
if (button == 0) { // soltar todo
dragging = false;
pickingHue = false;
pickingSaturationBrightness = false;
pickingAlpha = false;
}
for (SettingButton sb : visibleButtons)
sb.mouseReleased(mouseX, mouseY, button);
}
@Override
public void mouseDragged(double mouseX, double mouseY) {
if (pickingHue || pickingSaturationBrightness || pickingAlpha)
updateColorFromPicker((int) mouseX, (int) mouseY);
for (SettingButton sb : visibleButtons)
sb.mouseDragged(mouseX, mouseY);
}
private boolean isSBPickerHovered(double mouseX, double mouseY) {
return (mouseX >= saturationBrightnessPickerX && mouseX <= saturationBrightnessPickerX + saturationBrightnessPickerWidth &&
mouseY >= saturationBrightnessPickerY && mouseY <= saturationBrightnessPickerY + saturationBrightnessPickerHeight);
}
private boolean isHuePickerHovered(double mouseX, double mouseY) {
return (mouseX >= huePickerX && mouseX <= huePickerX + huePickerWidth &&
mouseY >= huePickerY && mouseY <= huePickerY + huePickerHeight);
}
private boolean isAlphaPickerHovered(double mouseX, double mouseY) {
return (mouseX >= alphaPickerX && mouseX <= alphaPickerX + alphaPickerWidth &&
mouseY >= alphaPickerY && mouseY <= alphaPickerY + alphaPickerHeight);
}
// ACTUALIZAR VALORES
private void updateColorFromPicker(int mouseX, int mouseY) {
if (colorSetting == null) return;
if (pickingSaturationBrightness) {
int x = Math.max(saturationBrightnessPickerX,
Math.min(mouseX, saturationBrightnessPickerX + saturationBrightnessPickerWidth));
int y = Math.max(saturationBrightnessPickerY,
Math.min(mouseY, saturationBrightnessPickerY + saturationBrightnessPickerHeight));
float saturation = (x - saturationBrightnessPickerX) / (float) saturationBrightnessPickerWidth;
float brightness = 1 - (y - saturationBrightnessPickerY) / (float) saturationBrightnessPickerHeight;
saturation = Math.max(0, Math.min(1, saturation));
brightness = Math.max(0, Math.min(1, brightness));
if (colorSetting.isRainbow()) { // gaming
float hue = (System.currentTimeMillis() % (colorSetting.getRainbowSpeed() * 1000L))
/ (float) (colorSetting.getRainbowSpeed() * 1000L);
Color newColor = Color.getHSBColor(hue, saturation, brightness);
colorSetting.setRGB(newColor.getRed(), newColor.getGreen(), newColor.getBlue());
} else { // non gaming
float[] currentHSB = Color.RGBtoHSB(colorSetting.getR(), colorSetting.getG(), colorSetting.getB(), null);
Color newColor = Color.getHSBColor(currentHSB[0], saturation, brightness);
colorSetting.setRGB(newColor.getRed(), newColor.getGreen(), newColor.getBlue());
}
updateSettingsFromColor();
return;
}
if (pickingHue && !colorSetting.isRainbow()) {
int y = Math.max(huePickerY,
Math.min(mouseY, huePickerY + huePickerHeight));
float hue = 1 - (y - huePickerY) / (float) huePickerHeight;
hue = Math.max(0, Math.min(1, hue));
float[] currentHSB = Color.RGBtoHSB(colorSetting.getR(), colorSetting.getG(), colorSetting.getB(), null);
Color newColor = Color.getHSBColor(hue, currentHSB[1], currentHSB[2]);
colorSetting.setRGB(newColor.getRed(), newColor.getGreen(), newColor.getBlue());
updateSettingsFromColor();
return;
}
if (pickingAlpha) {
int clampedX = Math.max(alphaPickerX,
Math.min(mouseX, alphaPickerX + alphaPickerWidth));
int alpha = (int) (255 * (clampedX - alphaPickerX) / (float) alphaPickerWidth);
alpha = Math.max(0, Math.min(255, alpha));
colorSetting.setA(alpha);
}
}
private void updateColorFromSettings() {
if (colorSetting == null) return;
int red, green, blue, alpha;
boolean rainbow;
int rainbowSpeed;
float saturation, brightness;
red = redSetting.getIntValue();
green = greenSetting.getIntValue();
blue = blueSetting.getIntValue();
alpha = colorSetting.getA();
rainbow = rainbowSetting.isEnabled();
rainbowSpeed = rainbowSpeedSetting.getIntValue();
saturation = saturationSetting.getFloatValue();
brightness = brightnessSetting.getFloatValue();
if (!rainbow) colorSetting.setRGB(red, green, blue, alpha);
colorSetting.setRainbow(rainbow);
colorSetting.setRainbowSpeed(rainbowSpeed);
colorSetting.setSaturation(saturation);
colorSetting.setBrightness(brightness);
}
private void updateSettingsFromColor() {
if (colorSetting == null) return;
for (AbstractSetting setting : dummyModule.getSettings()) {
switch (setting.getName()) {
case "rojo" -> ((NumberSetting) setting).setValue(colorSetting.getR());
case "verde" -> ((NumberSetting) setting).setValue(colorSetting.getG());
case "azul" -> ((NumberSetting) setting).setValue(colorSetting.getB());
case "opacidad" -> ((NumberSetting) setting).setValue(colorSetting.getA());
case "arcoíris" -> ((BooleanSetting) setting).setEnabled(colorSetting.isRainbow());
case "velocidad del arcoíris" -> ((NumberSetting) setting).setValue(colorSetting.getRainbowSpeed());
case "saturación" -> ((NumberSetting) setting).setValue(colorSetting.getSaturation());
case "brillo" -> ((NumberSetting) setting).setValue(colorSetting.getBrightness());
}
}
}
public ColorSetting getColorSetting() {
return colorSetting;
}
}
@@ -56,7 +56,7 @@ public class ModuleFrame {
int maxWidth = mc.textRenderer.getWidth(title); int maxWidth = mc.textRenderer.getWidth(title);
for (ModuleButton button : moduleButtons) { for (ModuleButton button : moduleButtons) {
String text = button.module.getName(); String text = button.getModule().getName();
int textWidth = mc.textRenderer.getWidth(text); int textWidth = mc.textRenderer.getWidth(text);
maxWidth = Math.max(maxWidth, textWidth); maxWidth = Math.max(maxWidth, textWidth);
} }
@@ -66,6 +66,7 @@ public class ModuleFrame {
public void render(DrawContext ctx, int mouseX, int mouseY, float delta) { public void render(DrawContext ctx, int mouseX, int mouseY, float delta) {
updateWidth(); updateWidth();
ctx.fill(x, renderY, x + w, renderY + h, Colors.mainColor.getRGB()); // cabeza del marco ctx.fill(x, renderY, x + w, renderY + h, Colors.mainColor.getRGB()); // cabeza del marco
// título del marco // título del marco
ctx.drawText(mc.textRenderer, Text.literal(Formatting.BOLD + title), ctx.drawText(mc.textRenderer, Text.literal(Formatting.BOLD + title),
x + 8, x + 8,
@@ -77,18 +78,28 @@ public class ModuleFrame {
renderY + (h / 2) - (mc.textRenderer.fontHeight / 2), renderY + (h / 2) - (mc.textRenderer.fontHeight / 2),
-1, true); -1, true);
List<ModuleButton> visibleButtons = moduleButtons.stream()
.filter(mb -> mb.getModule().isSearchMatch())
.toList();
// dibujar sus módulos solo si está extendido // dibujar sus módulos solo si está extendido
if (extended) { if (extended) {
totalHeight = moduleButtons.size() * h + 3; totalHeight = visibleButtons.size() * h + 3;
ctx.fill( // fondo para los botones ctx.fill( // fondo para los botones
x, renderY + h + 1, x, renderY + h + 1,
x + w, renderY + h + totalHeight, x + w, renderY + h + totalHeight,
Colors.frameBGColor.getRGB()); Colors.frameBGColor.getRGB());
// dibujar los botones para cada módulo // dibujar los botones para cada módulo
for (ModuleButton moduleButton : moduleButtons) int buttonY = renderY + h + 1;
for (ModuleButton moduleButton : visibleButtons) {
moduleButton.offset = buttonY - renderY;
moduleButton.render(ctx, mouseX, mouseY, delta); moduleButton.render(ctx, mouseX, mouseY, delta);
} else totalHeight = 0; buttonY += h;
}
} else {
totalHeight = 0;
}
} }
public void mouseClicked(double mouseX, double mouseY, int button) { public void mouseClicked(double mouseX, double mouseY, int button) {
@@ -105,8 +116,13 @@ public class ModuleFrame {
} }
if (!extended) return; // solo dejar clicar en los módulos si el marco está extendido if (!extended) return; // solo dejar clicar en los módulos si el marco está extendido
for (ModuleButton moduleButton : moduleButtons)
moduleButton.mouseClicked(mouseX, mouseY, button); List<ModuleButton> visibleModuleButtons = moduleButtons.stream()
.filter(mb -> mb.getModule().isSearchMatch())
.toList();
for (ModuleButton moduleButton : visibleModuleButtons)
moduleButton.mouseClicked(mouseX, mouseY, button);
} }
// detectar cuándo se suelta el clic // detectar cuándo se suelta el clic
@@ -115,7 +131,11 @@ public class ModuleFrame {
if (button == 0 && dragging) if (button == 0 && dragging)
dragging = false; dragging = false;
for (ModuleButton moduleButton : moduleButtons) { List<ModuleButton> visibleModuleButtons = moduleButtons.stream()
.filter(mb -> mb.getModule().isSearchMatch())
.toList();
for (ModuleButton moduleButton : visibleModuleButtons) {
if (moduleButton.isHovered((int) mouseX, (int) mouseY)) if (moduleButton.isHovered((int) mouseX, (int) mouseY))
moduleButton.mouseReleased(mouseX, mouseY, button); moduleButton.mouseReleased(mouseX, mouseY, button);
} }
@@ -136,4 +156,8 @@ public class ModuleFrame {
y = (int) (mouseY - dragY); y = (int) (mouseY - dragY);
} }
} }
public List<ModuleButton> getButtons() {
return moduleButtons;
}
} }
@@ -20,8 +20,8 @@ import java.util.List;
// marco para los botones de los ajustes de cada módulo // marco para los botones de los ajustes de cada módulo
public class SettingsFrame { public class SettingsFrame {
private final String title; final String title;
public final Module module; public Module module;
final List<SettingButton> settingButtons = new ArrayList<>(); final List<SettingButton> settingButtons = new ArrayList<>();
public List<SettingButton> visibleButtons = new ArrayList<>(); public List<SettingButton> visibleButtons = new ArrayList<>();
@@ -37,7 +37,13 @@ public class SettingsFrame {
@SuppressWarnings({"rawtypes", "unchecked"}) @SuppressWarnings({"rawtypes", "unchecked"})
public SettingsFrame(Module module, int x, int y, int w, int h) { public SettingsFrame(Module module, int x, int y, int w, int h) {
this.module = module; this.module = module;
this.x = x;
// asegurarse de que no se sale de la pantalla
if (mc.getWindow() != null && x + w > mc.getWindow().getScaledWidth())
this.x = mc.getWindow().getScaledWidth() - w;
else
this.x = x;
this.y = y; this.y = y;
this.w = w; this.w = w;
this.h = h; this.h = h;
@@ -45,7 +51,6 @@ public class SettingsFrame {
// añadir el respectivo tipo de botón de cada ajuste a la lista de botones // añadir el respectivo tipo de botón de cada ajuste a la lista de botones
int offset = h; int offset = h;
for (AbstractSetting setting : module.getSettings()) { for (AbstractSetting setting : module.getSettings()) {
if (!setting.isVisible()) continue;
switch (setting) { switch (setting) {
case BooleanSetting b -> { case BooleanSetting b -> {
addButton(new ToggleButton(b, this, offset)); addButton(new ToggleButton(b, this, offset));
@@ -65,7 +70,11 @@ public class SettingsFrame {
} case ListSetting l -> { } case ListSetting l -> {
addButton(new ListButton<>(l, this, offset)); addButton(new ListButton<>(l, this, offset));
offset += 18; offset += 18;
} default -> {} } case ColorSetting c -> {
addButton(new ColorButton(c, this, offset));
offset += 18;
}
default -> {}
} }
} }
title = "ajustes de " + module.getName(); title = "ajustes de " + module.getName();
@@ -105,11 +114,11 @@ public class SettingsFrame {
ctx.drawText(mc.textRenderer, title, titleX, titleY, -1, true); ctx.drawText(mc.textRenderer, title, titleX, titleY, -1, true);
ctx.drawText(mc.textRenderer, "×", x + w - mc.textRenderer.getWidth("×") - 8, titleY, closeButtonColor, true); ctx.drawText(mc.textRenderer, "×", x + w - mc.textRenderer.getWidth("×") - 8, titleY, closeButtonColor, true);
// descripción
visibleButtons = settingButtons.stream() visibleButtons = settingButtons.stream()
.filter(sb -> sb.getSetting().isVisible() && sb.getSetting().isSearchMatch()) .filter(sb -> sb.getSetting().isVisible() && sb.getSetting().isSearchMatch())
.toList(); .toList();
// descripción
List<String> descLines = wrapDescription(module.getDescription(), w - 8); List<String> descLines = wrapDescription(module.getDescription(), w - 8);
int lineSpacing = 2; int lineSpacing = 2;
@@ -161,19 +170,24 @@ public class SettingsFrame {
} }
} }
for (SettingButton sb : settingButtons) for (SettingButton sb : visibleButtons)
if (sb.getSetting().isVisible()) sb.mouseClicked(mouseX, mouseY, button);
sb.mouseClicked(mouseX, mouseY, button);
} }
public void mouseRelease(double mouseX, double mouseY, int button) { public void mouseReleased(double mouseX, double mouseY, int button) {
ClickGUI.INSTANCE.unselect(this); ClickGUI.INSTANCE.unselect(this);
if (button == 0) { if (button == 0) {
dragging = false; dragging = false;
CameraTweaks.EVENT_BUS.post(new SettingsFrameEvent.Move(this)); CameraTweaks.EVENT_BUS.post(new SettingsFrameEvent.Move(this));
} }
for (SettingButton sb : settingButtons)
if (sb.getSetting().isVisible()) sb.mouseReleased(mouseX, mouseY, button); for (SettingButton sb : visibleButtons)
sb.mouseReleased(mouseX, mouseY, button);
}
public void mouseDragged(double mouseX, double mouseY) {
for (SettingButton sb : visibleButtons)
sb.mouseDragged(mouseX, mouseY);
} }
public void updatePosition(double mouseX, double mouseY) { public void updatePosition(double mouseX, double mouseY) {
@@ -7,14 +7,20 @@ import me.retucio.camtweaks.event.events.MouseClickEvent;
import me.retucio.camtweaks.event.events.MouseScrollEvent; import me.retucio.camtweaks.event.events.MouseScrollEvent;
import me.retucio.camtweaks.event.events.camtweaks.SettingsFrameEvent; import me.retucio.camtweaks.event.events.camtweaks.SettingsFrameEvent;
import me.retucio.camtweaks.module.Module; import me.retucio.camtweaks.module.Module;
import me.retucio.camtweaks.module.ModuleManager;
import me.retucio.camtweaks.module.settings.AbstractSetting; import me.retucio.camtweaks.module.settings.AbstractSetting;
import me.retucio.camtweaks.module.settings.ColorSetting;
import me.retucio.camtweaks.ui.buttons.ColorButton;
import me.retucio.camtweaks.ui.buttons.ListButton; import me.retucio.camtweaks.ui.buttons.ListButton;
import me.retucio.camtweaks.ui.buttons.ModuleButton;
import me.retucio.camtweaks.ui.buttons.SettingButton; import me.retucio.camtweaks.ui.buttons.SettingButton;
import me.retucio.camtweaks.ui.frames.ClientSettingsFrame; import me.retucio.camtweaks.ui.frames.ClientSettingsFrame;
import me.retucio.camtweaks.ui.frames.ColorPickerFrame;
import me.retucio.camtweaks.ui.frames.ModuleFrame; import me.retucio.camtweaks.ui.frames.ModuleFrame;
import me.retucio.camtweaks.ui.frames.SettingsFrame; import me.retucio.camtweaks.ui.frames.SettingsFrame;
import me.retucio.camtweaks.ui.widgets.ScrollBarWidget; import me.retucio.camtweaks.ui.widgets.ScrollBarWidget;
import me.retucio.camtweaks.ui.widgets.SearchBarWidget; import me.retucio.camtweaks.ui.widgets.SearchBarWidget;
import me.retucio.camtweaks.util.ChatUtil;
import me.retucio.camtweaks.util.KeyUtil; import me.retucio.camtweaks.util.KeyUtil;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
@@ -136,13 +142,15 @@ public class ClickGUI extends Screen {
// registrar cuándo se suelta el clic, en cada marco respectivamente // registrar cuándo se suelta el clic, en cada marco respectivamente
modulesFrame.mouseReleased(click.x(), click.y(), click.button()); modulesFrame.mouseReleased(click.x(), click.y(), click.button());
for (SettingsFrame sf : new ArrayList<>(settingsFrames)) for (SettingsFrame sf : new ArrayList<>(settingsFrames))
sf.mouseRelease(click.x(), click.y(), click.button()); sf.mouseReleased(click.x(), click.y(), click.button());
return super.mouseReleased(click); return super.mouseReleased(click);
} }
@Override @Override
public boolean mouseDragged(Click click, double deltaX, double deltaY) { public boolean mouseDragged(Click click, double deltaX, double deltaY) {
scrollBar.mouseDragged(click.y()); scrollBar.mouseDragged(click.y());
for (SettingsFrame sf : new ArrayList<>(settingsFrames))
sf.mouseDragged(click.x(), click.y());
return super.mouseDragged(click, deltaX, deltaY); return super.mouseDragged(click, deltaX, deltaY);
} }
@@ -178,6 +186,25 @@ public class ClickGUI extends Screen {
String searchInput = searchBar.getSearchInput().trim(); String searchInput = searchBar.getSearchInput().trim();
if (!guiSettings.matchCase.isEnabled()) searchInput = searchInput.toLowerCase(); if (!guiSettings.matchCase.isEnabled()) searchInput = searchInput.toLowerCase();
for (ModuleButton mb : modulesFrame.getButtons()) {
Module module = mb.getModule();
if (searchInput.isEmpty()) {
module.setSearchMatch(true);
continue;
}
String name = module.getName();
String description = module.getDescription();
if (!guiSettings.matchCase.isEnabled()) {
name = name.toLowerCase();
description = description.toLowerCase();
}
module.setSearchMatch(name.contains(searchInput) || description.contains(searchInput));
}
for (SettingsFrame sf : settingsFrames) { for (SettingsFrame sf : settingsFrames) {
for (SettingButton sb : sf.getButtons()) { for (SettingButton sb : sf.getButtons()) {
AbstractSetting setting = sb.getSetting(); AbstractSetting setting = sb.getSetting();
@@ -219,7 +246,8 @@ public class ClickGUI extends Screen {
// porque java.util.ConcurrentModificationException o algo no sé es lo único que se me ha ocurrido hacer // porque java.util.ConcurrentModificationException o algo no sé es lo único que se me ha ocurrido hacer
List<SettingsFrame> toRemove = new ArrayList<>(); List<SettingsFrame> toRemove = new ArrayList<>();
for (SettingsFrame sf : settingsFrames) { for (SettingsFrame sf : settingsFrames) {
if (sf.module == module) { if ((sf instanceof ColorPickerFrame cpf && cpf.dummyModule == module) // para los selectores de colores
|| (!(sf instanceof ColorPickerFrame) && sf.module == module)) { // lógica muy mierdas, lo sé, pero paso de hacerlo bien
CameraTweaks.EVENT_BUS.post(new SettingsFrameEvent.Close(sf)); CameraTweaks.EVENT_BUS.post(new SettingsFrameEvent.Close(sf));
toRemove.add(sf); toRemove.add(sf);
unselect(sf); unselect(sf);
@@ -234,8 +262,6 @@ public class ClickGUI extends Screen {
.anyMatch(sf -> sf.module.getName().equals(module.getName())); .anyMatch(sf -> sf.module.getName().equals(module.getName()));
} }
public void refreshListButtons() { public void refreshListButtons() {
for (SettingsFrame frame : settingsFrames) for (SettingsFrame frame : settingsFrames)
for (SettingButton button : frame.getButtons()) for (SettingButton button : frame.getButtons())
@@ -243,13 +269,38 @@ public class ClickGUI extends Screen {
lb.refreshDummy(); lb.refreshDummy();
} }
public boolean isColorPickerFrameOpen(ColorSetting setting) {
for (SettingsFrame sf : getSettingsFrames()) {
if (sf instanceof ColorPickerFrame cpf)
if (cpf.getColorSetting().equals(setting)) return true;
}
return false;
}
public void openColorPickerFrame(Module module, ColorSetting colorSetting, int x, int y) {
ColorPickerFrame frame = new ColorPickerFrame(module, colorSetting, x + 80, y + 5, 153, 20);
if (isColorPickerFrameOpen(frame.getColorSetting())) {
closeColorPickerFrame(frame.getColorSetting());
return;
};
settingsFrames.add(frame);
}
public void closeColorPickerFrame(ColorSetting setting) {
for (SettingsFrame sf : getSettingsFrames()) {
if (sf instanceof ColorPickerFrame cpf && cpf.getColorSetting().equals(setting)) {
settingsFrames.remove(cpf);
break;
}
}
}
// métodos del súper // métodos del súper
@Override @Override
public void close() { // evitar que al reabrir la interfaz sin previamente haber soltado el clic, se sigan arrastrando objetos public void close() { // evitar que al reabrir la interfaz sin previamente haber soltado el clic, se sigan arrastrando objetos
modulesFrame.mouseReleased(0, 0, 0); modulesFrame.mouseReleased(0, 0, 0);
settingsFrames.forEach(sf -> sf.mouseRelease(0, 0, 0)); settingsFrames.forEach(sf -> sf.mouseReleased(0, 0, 0));
scrollBar.mouseReleased(0, 0, 0); scrollBar.mouseReleased(0, 0, 0);
searchBar.mouseReleased(0, 0, 0); searchBar.mouseReleased(0, 0, 0);
@@ -201,6 +201,10 @@ public class HudEditorScreen extends Screen {
list.add(Text.literal("hora")); list.add(Text.literal("hora"));
list.add(Text.literal("te muestra la hora y los minutos de la zona horaria escogida")); list.add(Text.literal("te muestra la hora y los minutos de la zona horaria escogida"));
} }
case "ping" -> {
list.add(Text.literal("ping"));
list.add(Text.literal("tiempo entre que se envía un paquete y este llega a su destino, en milisegundos"));
}
default -> { default -> {
list.add(Text.literal(element.getId())); list.add(Text.literal(element.getId()));
list.add(Text.literal(".")); list.add(Text.literal("."));
@@ -85,6 +85,12 @@ public class HudElement {
return "4:20 PM"; return "4:20 PM";
} }
if ("ping".equals(id)) {
if (mc.getCurrentServerEntry() != null)
return HudRenderer.getElementText(id, delta, hud);
return "67 ms";
}
return id; // fallback: id del elemento return id; // fallback: id del elemento
} }
@@ -1,5 +1,6 @@
package me.retucio.camtweaks.ui.widgets; package me.retucio.camtweaks.ui.widgets;
import me.retucio.camtweaks.config.ConfigManager;
import me.retucio.camtweaks.ui.screen.ClickGUI; import me.retucio.camtweaks.ui.screen.ClickGUI;
import me.retucio.camtweaks.ui.frames.ClientSettingsFrame; import me.retucio.camtweaks.ui.frames.ClientSettingsFrame;
import me.retucio.camtweaks.util.Colors; import me.retucio.camtweaks.util.Colors;
@@ -80,7 +81,10 @@ public class SearchBarWidget {
public void mouseReleased(double mouseX, double mouseY, int button) { public void mouseReleased(double mouseX, double mouseY, int button) {
if (!ClientSettingsFrame.guiSettings.searchBar.isEnabled()) return; if (!ClientSettingsFrame.guiSettings.searchBar.isEnabled()) return;
ClickGUI.INSTANCE.unselect(this); ClickGUI.INSTANCE.unselect(this);
if (button == 0 && dragging) dragging = false; if (button == 0 && dragging) {
dragging = false;
savePosition();
}
} }
public void onKey(int key, int action) { public void onKey(int key, int action) {
@@ -152,4 +156,26 @@ public class SearchBarWidget {
y = (int) (mouseY - dragY); y = (int) (mouseY - dragY);
} }
} }
public void savePosition() {
if (ConfigManager.getConfig() != null) {
ConfigManager.setSearchBarPosition(x, y);
}
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
} }
@@ -3,9 +3,6 @@ package me.retucio.camtweaks.util;
import net.minecraft.util.Formatting; import net.minecraft.util.Formatting;
import java.awt.Color; import java.awt.Color;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static me.retucio.camtweaks.ui.frames.ClientSettingsFrame.guiSettings; import static me.retucio.camtweaks.ui.frames.ClientSettingsFrame.guiSettings;
@@ -14,10 +11,10 @@ import static me.retucio.camtweaks.ui.frames.ClientSettingsFrame.guiSettings;
// si se ve especificado como color en algún lado "-1", significa blanco // si se ve especificado como color en algún lado "-1", significa blanco
public class Colors { public class Colors {
public static int red = guiSettings.red.getIntValue(); public static int red = guiSettings.color.getR();
public static int green = guiSettings.green.getIntValue(); public static int green = guiSettings.color.getG();
public static int blue = guiSettings.blue.getIntValue(); public static int blue = guiSettings.color.getB();
public static int alpha = guiSettings.alpha.getIntValue(); public static int alpha = guiSettings.color.getA();
public static Color mainColor; public static Color mainColor;
public static Color frameBGColor = new Color(40, 40, 40, 75); public static Color frameBGColor = new Color(40, 40, 40, 75);
@@ -53,30 +50,16 @@ public class Colors {
updateAllColors(new Color(red, green, blue, alpha)); updateAllColors(new Color(red, green, blue, alpha));
} }
public static int rainbowInt(int rainbowSpeed, int alpha) { public static int rainbowInt(int rainbowSpeed, int alpha, float saturation, float brightness) {
float speed = 10001 - rainbowSpeed; // 10001 para evitar divisiones por cero return rainbowColor(rainbowSpeed, alpha, saturation, brightness).getRGB();
float hue = (System.currentTimeMillis() % (int) speed) / speed; }
Color gamingProMax = Color.getHSBColor(hue, 1, 1);
return new Color( public static int rainbowInt(int rainbowSpeed, int alpha) {
gamingProMax.getRed(), return rainbowColor(rainbowSpeed, alpha, 1f, 1f).getRGB();
gamingProMax.getGreen(),
gamingProMax.getBlue(),
alpha
).getRGB();
} }
public static Color rainbowColor(int rainbowSpeed, int alpha) { public static Color rainbowColor(int rainbowSpeed, int alpha) {
float speed = 10001 - rainbowSpeed; // 10001 para evitar divisiones por cero return rainbowColor(rainbowSpeed, alpha, 1f, 1f);
float hue = (System.currentTimeMillis() % (int) speed) / speed;
Color gamingProMax = Color.getHSBColor(hue, 1, 1);
return new Color(
gamingProMax.getRed(),
gamingProMax.getGreen(),
gamingProMax.getBlue(),
alpha
);
} }
public static Color rainbowColor(int rainbowSpeed, int alpha, float saturation, float brightness) { public static Color rainbowColor(int rainbowSpeed, int alpha, float saturation, float brightness) {
@@ -150,6 +133,14 @@ public class Colors {
return nearest; return nearest;
} }
public static String ARGBtoHex(int a, int r, int g, int b) {
return "#"
+ String.format("%02x", a)
+ String.format("%02x", r)
+ String.format("%02x", g)
+ String.format("%02x", b);
}
private static double colorDistance(Color c1, Color c2) { private static double colorDistance(Color c1, Color c2) {
int rDiff = c1.getRed() - c2.getRed(); int rDiff = c1.getRed() - c2.getRed();
int gDiff = c1.getGreen() - c2.getGreen(); int gDiff = c1.getGreen() - c2.getGreen();
Loaded 100 of 104 files, more files were not shown because too many files have changed in this diff. Show more