v2.0
This commit is contained in:
1 parent
a9cf6dd924
commit
347ec658bb
67 files changed
+2522
-849
No files matched your search
+3
-1
@@ -43,4 +43,6 @@ replay_*.log
|
||||
|
||||
todo.txt
|
||||
cambios.md
|
||||
remappedSrc/
|
||||
remappedSrc/
|
||||
src/main/java/me/retucio/camtweaks/ui/widgets/Frame.java
|
||||
src/main/java/me/retucio/camtweaks/ui/widgets/Button.java
|
||||
+16
-3
@@ -1,15 +1,28 @@
|
||||
# v1.9.1
|
||||
# v2.0
|
||||
|
||||
## novedades
|
||||
|
||||
- ARREGLADO EL SELECTOR DE COLORES
|
||||
|
||||
### adiciones
|
||||
|
||||
- ajuste de opción: similar a enumsetting, pero abre un marco de selección, igual que listsetting.
|
||||
|
||||
#### módulos nuevos:
|
||||
|
||||
- resaltado de bloques: resalta bloques de cierto tipo renderizando una caja con su forma, visible a través de paredes
|
||||
- delay de paquetes: simula un ping alto añadiendo delay a los paquetes
|
||||
- inventario plus: te permite mover items a cualquier slot del inventario mediante teclas (ej.: d + tecla para slot 4);
|
||||
- progreso de minado: muestra el progreso de minado de un bloque de una manera más visual, mediante cajas de color
|
||||
- mano secundaria: equipa de manera automática un ítem en tu mano secundaria
|
||||
- moverse en interfaz: te permite utilizar las teclas de movimiento con ciertas interfaces abiertas (configurable)
|
||||
|
||||
### arreglos / mejoras
|
||||
|
||||
- ahora se pueden mostrar también las coordenadas del nether en el elemento del hud para coordenadas
|
||||
- ahora ChatPlus utilizará los corchetes [] para mostrar la hora (antes era <>), además de también detectar cuando un jugador se une a la hora de dibujar las cabezas
|
||||
- ahora puedes elegir el sonido en aviso de baja dur., junto a la altura y volumen de este
|
||||
- ya no se pueden abrir interfaces del mod estando en pantallas donde se suele escribir (chat, carteles, etc.)
|
||||
- arreglado algunos problemas con las configuraciones
|
||||
|
||||
## problemas reconocidos
|
||||
|
||||
- muchos, pero repórtalos en la página de problemas si quieres para que queden bien registrados
|
||||
+1
-1
@@ -6,7 +6,7 @@ yarn_mappings=1.21.10+build.2
|
||||
loader_version=0.17.3
|
||||
loom_version=1.11-SNAPSHOT
|
||||
|
||||
mod_version=1.9
|
||||
mod_version=2.0
|
||||
maven_group=me.retucio
|
||||
archives_base_name=camtweaks
|
||||
|
||||
|
||||
@@ -18,27 +18,30 @@ import me.retucio.camtweaks.module.ModuleManager;
|
||||
|
||||
import me.retucio.camtweaks.module.modules.HUD;
|
||||
import me.retucio.camtweaks.ui.screen.ClickGUI;
|
||||
import me.retucio.camtweaks.ui.screen.HudEditorScreen;
|
||||
import me.retucio.camtweaks.ui.HudRenderer;
|
||||
import me.retucio.camtweaks.ui.hud.HudEditorScreen;
|
||||
import me.retucio.camtweaks.ui.hud.HudRenderer;
|
||||
import me.retucio.camtweaks.ui.buttons.BindButton;
|
||||
import me.retucio.camtweaks.ui.buttons.SettingButton;
|
||||
import me.retucio.camtweaks.ui.buttons.TextButton;
|
||||
import me.retucio.camtweaks.ui.frames.ClientSettingsFrame;
|
||||
import me.retucio.camtweaks.ui.frames.SettingsFrame;
|
||||
|
||||
import me.retucio.camtweaks.util.ChatUtil;
|
||||
import me.retucio.camtweaks.util.KeyUtil;
|
||||
import me.retucio.camtweaks.util.Lists;
|
||||
import me.retucio.camtweaks.util.MiscUtil;
|
||||
import me.retucio.camtweaks.util.*;
|
||||
|
||||
|
||||
import me.retucio.camtweaks.util.render.DrawUtil;
|
||||
import me.retucio.camtweaks.util.render.RenderUtil;
|
||||
import net.fabricmc.api.ClientModInitializer;
|
||||
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.minecraft.SharedConstants;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.screen.ChatScreen;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
|
||||
import net.minecraft.client.gui.screen.ingame.AbstractCommandBlockScreen;
|
||||
import net.minecraft.client.gui.screen.ingame.AbstractSignEditScreen;
|
||||
import net.minecraft.client.gui.screen.ingame.AnvilScreen;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
@@ -68,7 +71,7 @@ public class CameraTweaks implements ClientModInitializer {
|
||||
|
||||
|
||||
private Screen prevScreen;
|
||||
public boolean settingsApplied = false;
|
||||
public static boolean settingsApplied = false;
|
||||
|
||||
|
||||
@Override
|
||||
@@ -80,14 +83,20 @@ public class CameraTweaks implements ClientModInitializer {
|
||||
ConfigManager.load();
|
||||
|
||||
EVENT_BUS.register(this);
|
||||
|
||||
EVENT_BUS.register(new HudRenderer());
|
||||
|
||||
EVENT_BUS.register(MiscUtil.class);
|
||||
EVENT_BUS.register(ChatUtil.class);
|
||||
EVENT_BUS.register(DrawUtil.class);
|
||||
EVENT_BUS.register(EntityUtil.class);
|
||||
EVENT_BUS.register(InventoryUtil.class);
|
||||
EVENT_BUS.register(MiscUtil.class);
|
||||
EVENT_BUS.register(NetworkUtil.class);
|
||||
EVENT_BUS.register(RenderUtil.class);
|
||||
|
||||
Lists.init();
|
||||
|
||||
ModuleManager.INSTANCE = new ModuleManager(EVENT_BUS);
|
||||
ModuleManager.INSTANCE = new ModuleManager();
|
||||
EVENT_BUS.post(new LoadModuleManagerEvent());
|
||||
|
||||
CommandManager.INSTANCE = new CommandManager();
|
||||
@@ -172,7 +181,8 @@ public class CameraTweaks implements ClientModInitializer {
|
||||
|
||||
// maneja la lógica de apertura de la interfaz
|
||||
private void handleClickGUIKey(int key, boolean anyFocused) {
|
||||
if (key != ClientSettingsFrame.guiSettings.getKey() || anyFocused) return;
|
||||
if (key != ClientSettingsFrame.guiSettings.getKey() || anyFocused || isOnTypingScreen())
|
||||
return;
|
||||
|
||||
// al parecer esto hace que con la tecla de la interfaz puedas ir cambiando de splash text en la pantalla del título
|
||||
// pero me ha hecho gracia así que así se queda
|
||||
@@ -188,13 +198,13 @@ public class CameraTweaks implements ClientModInitializer {
|
||||
// manejar la lógica de apertura del editor de elementos del hud, con la misma lógica que handleClickGUIKey()
|
||||
private void handleHudEditorKey(int key, boolean anyFocused) {
|
||||
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 (key != hud.editorKey.getKey() || anyFocused || isOnTypingScreen()) return;
|
||||
|
||||
if (mc.currentScreen != HudEditorScreen.INSTANCE) {
|
||||
if (!hud.isEnabled()) {
|
||||
ChatUtil.warn("HUD está desactivado, lumbreras");
|
||||
return;
|
||||
}
|
||||
prevScreen = mc.currentScreen;
|
||||
mc.setScreen(HudEditorScreen.INSTANCE);
|
||||
} else {
|
||||
@@ -212,6 +222,13 @@ public class CameraTweaks implements ClientModInitializer {
|
||||
module.setEnabled(false);
|
||||
}
|
||||
|
||||
private boolean isOnTypingScreen() {
|
||||
return mc.currentScreen instanceof ChatScreen
|
||||
|| mc.currentScreen instanceof AnvilScreen
|
||||
|| mc.currentScreen instanceof AbstractSignEditScreen
|
||||
|| mc.currentScreen instanceof AbstractCommandBlockScreen;
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onStop(ShutdownEvent event) {
|
||||
ConfigManager.save();
|
||||
|
||||
@@ -8,7 +8,7 @@ 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 me.retucio.camtweaks.util.EntityUtil;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.text.Text;
|
||||
@@ -190,7 +190,7 @@ public class EntityArgumentType implements ArgumentType<Entity> {
|
||||
builder.suggest("@r");
|
||||
builder.suggest("@s");
|
||||
|
||||
Entity lookingAt = MiscUtil.getEntityPlayerIsLookingAt();
|
||||
Entity lookingAt = EntityUtil.getEntityPlayerIsLookingAt();
|
||||
if (lookingAt != null)
|
||||
builder.suggest(lookingAt.getUuid().toString());
|
||||
|
||||
|
||||
@@ -4,23 +4,11 @@ import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||
import me.retucio.camtweaks.CameraTweaks;
|
||||
import me.retucio.camtweaks.command.Command;
|
||||
import me.retucio.camtweaks.event.SubscribeEvent;
|
||||
import me.retucio.camtweaks.event.events.DisconnectEvent;
|
||||
import me.retucio.camtweaks.event.events.OpenScreenEvent;
|
||||
import me.retucio.camtweaks.event.events.PacketEvent;
|
||||
import me.retucio.camtweaks.event.events.TickEvent;
|
||||
import me.retucio.camtweaks.ui.screen.PreviewScreen;
|
||||
import me.retucio.camtweaks.util.ChatUtil;
|
||||
import me.retucio.camtweaks.util.MiscUtil;
|
||||
import net.minecraft.client.gui.screen.ingame.GenericContainerScreen;
|
||||
import me.retucio.camtweaks.util.InventoryUtil;
|
||||
import net.minecraft.command.CommandSource;
|
||||
import net.minecraft.inventory.EnderChestInventory;
|
||||
import net.minecraft.inventory.Inventories;
|
||||
import net.minecraft.inventory.Inventory;
|
||||
import net.minecraft.inventory.SimpleInventory;
|
||||
import net.minecraft.network.packet.s2c.play.CloseScreenS2CPacket;
|
||||
import net.minecraft.screen.GenericContainerScreenHandler;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.ActionResult;
|
||||
|
||||
// accede a los contenidos de tu enderchest
|
||||
public class EnderChestCommand extends Command {
|
||||
@@ -36,7 +24,7 @@ public class EnderChestCommand extends Command {
|
||||
builder.executes(ctx -> {
|
||||
mc.execute(() -> {
|
||||
if (mc.player == null) return;
|
||||
if (MiscUtil.getEchestInv() == null) {
|
||||
if (InventoryUtil.getEchestInv() == null) {
|
||||
ChatUtil.warn("necesitas abrir un enderchest una vez primero");
|
||||
return;
|
||||
}
|
||||
@@ -52,8 +40,8 @@ public class EnderChestCommand extends Command {
|
||||
public void onTick(TickEvent.Post event) {
|
||||
if (shouldOpenEchest) {
|
||||
shouldOpenEchest = false;
|
||||
if (MiscUtil.getEchestInv() != null)
|
||||
mc.setScreen(new PreviewScreen(MiscUtil.getEchestInv(), null));
|
||||
if (InventoryUtil.getEchestInv() != null)
|
||||
mc.setScreen(new PreviewScreen(InventoryUtil.getEchestInv(), null));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ 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.EntityUtil;
|
||||
import me.retucio.camtweaks.util.MiscUtil;
|
||||
import net.minecraft.command.CommandSource;
|
||||
import net.minecraft.entity.Entity;
|
||||
@@ -21,7 +22,7 @@ public class SpectateCommand extends Command {
|
||||
builder
|
||||
.executes(ctx -> { // If no argument, use the entity player is looking at
|
||||
mc.execute(() -> {
|
||||
Entity target = MiscUtil.getEntityPlayerIsLookingAt();
|
||||
Entity target = EntityUtil.getEntityPlayerIsLookingAt();
|
||||
if (target != null)
|
||||
mc.setCameraEntity(target);
|
||||
});
|
||||
|
||||
@@ -57,8 +57,9 @@ public class ClientConfig {
|
||||
case KeySetting k: value = k.getKey(); break;
|
||||
case NumberSetting n: value = n.getValue(); break;
|
||||
case StringSetting s: value = s.getValue(); break;
|
||||
case ListSetting l: value = l.getValues(); break;
|
||||
case ListSetting l: value = l.getConfigValues(); break;
|
||||
case ColorSetting c: value = c.getConfigValue(); break;
|
||||
case OptionSetting o: value = o.getIndex(); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import me.retucio.camtweaks.CameraTweaks;
|
||||
import me.retucio.camtweaks.module.Module;
|
||||
import me.retucio.camtweaks.module.ModuleManager;
|
||||
import me.retucio.camtweaks.module.settings.*;
|
||||
import me.retucio.camtweaks.ui.frames.ModuleFrame;
|
||||
import me.retucio.camtweaks.ui.screen.ClickGUI;
|
||||
import me.retucio.camtweaks.ui.frames.ClientSettingsFrame;
|
||||
import me.retucio.camtweaks.ui.frames.SettingsFrame;
|
||||
@@ -23,24 +24,29 @@ public class ConfigManager {
|
||||
|
||||
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
|
||||
private static final File CONFIG_FILE = new File("camera_tweaks.json");
|
||||
private static boolean loaded = false;
|
||||
|
||||
private static boolean loaded = false;
|
||||
private static ClientConfig config = null;
|
||||
|
||||
|
||||
// ------------------ MÉTODOS PRINCIPALES ------------------
|
||||
|
||||
// guardar configuraciones
|
||||
public static void save() {
|
||||
ensureConfig();
|
||||
|
||||
try (FileWriter writer = new FileWriter(CONFIG_FILE)) {
|
||||
GSON.toJson(config, writer);
|
||||
CameraTweaks.LOGGER.info("ajustes guardados");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
CameraTweaks.LOGGER.error("error al guardar ajustes", e);
|
||||
}
|
||||
}
|
||||
|
||||
// cargar configuraciones
|
||||
public static void load() {
|
||||
CameraTweaks.LOGGER.info("ajustes cargados");
|
||||
CameraTweaks.LOGGER.info("cargando ajustes...");
|
||||
|
||||
if (!CONFIG_FILE.exists()) {
|
||||
ensureConfig();
|
||||
save();
|
||||
@@ -49,79 +55,52 @@ public class ConfigManager {
|
||||
|
||||
try (FileReader reader = new FileReader(CONFIG_FILE)) {
|
||||
config = GSON.fromJson(reader, ClientConfig.class);
|
||||
CameraTweaks.LOGGER.info("ajustes cargados");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
CameraTweaks.LOGGER.error("no se pudieron cargar los ajustes, usando ajustes por defecto", e);
|
||||
ensureConfig();
|
||||
}
|
||||
}
|
||||
|
||||
// aplicar configuraciones cargadas
|
||||
public static void applyConfig() {
|
||||
if (CameraTweaks.mc == null || ModuleManager.INSTANCE == null || config == null)
|
||||
return;
|
||||
if (!shouldApply()) return;
|
||||
|
||||
ModuleManager.INSTANCE.getModules().forEach(module -> {
|
||||
if (config.moduleStates.containsKey(module.getName()))
|
||||
module.setEnabled(config.moduleStates.get(module.getName())); // estados
|
||||
|
||||
module.getSettings().forEach(setting -> applySetting(module, setting));
|
||||
|
||||
if (config.settingsFrames.containsKey(module.getName())) {
|
||||
int[] position = config.settingsFrames.get(module.getName());
|
||||
ClickGUI.INSTANCE.openSettingsFrame(module, position[0], position[1]);
|
||||
}
|
||||
});
|
||||
|
||||
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.getSettings().forEach(setting -> applySetting(ClientSettingsFrame.guiSettings, setting));
|
||||
|
||||
CameraTweaks.LOGGER.info("módulos encendidos cargados");
|
||||
CameraTweaks.LOGGER.info("ajustes de módulos cargados");
|
||||
|
||||
ClientConfig.FrameData moduleFrameData = config.extendableFrames.get("M");
|
||||
if (moduleFrameData != null) {
|
||||
ClickGUI.INSTANCE.getModulesFrame().x = moduleFrameData.x();
|
||||
ClickGUI.INSTANCE.getModulesFrame().y = moduleFrameData.y();
|
||||
ClickGUI.INSTANCE.getModulesFrame().extended = moduleFrameData.extended();
|
||||
}
|
||||
|
||||
ClientConfig.FrameData guiSettingsData = config.extendableFrames.get("S");
|
||||
if (guiSettingsData != null) {
|
||||
ClickGUI.INSTANCE.getGuiSettingsFrame().x = guiSettingsData.x();
|
||||
ClickGUI.INSTANCE.getGuiSettingsFrame().y = guiSettingsData.y();
|
||||
ClickGUI.INSTANCE.getGuiSettingsFrame().extended = guiSettingsData.extended();
|
||||
}
|
||||
|
||||
CameraTweaks.LOGGER.info("posiciones de frames cargadas");
|
||||
ClickGUI.INSTANCE.refreshListButtons();
|
||||
applyModuleStates();
|
||||
applyModuleSettings();
|
||||
applySettingsFrames();
|
||||
applySearchBarPosition();
|
||||
applyGuiSettings();
|
||||
applyExtendableFrames();
|
||||
|
||||
loaded = true;
|
||||
CameraTweaks.LOGGER.info("ajustes aplicados");
|
||||
}
|
||||
|
||||
// obtener configuración actual
|
||||
public static ClientConfig getConfig() {
|
||||
ensureConfig();
|
||||
return config;
|
||||
}
|
||||
|
||||
|
||||
// ------------------ GUARDAR VALORES INDIVIDUALES EN LA CONFIG. ------------------
|
||||
|
||||
public static void setModuleState(Module module) {
|
||||
ensureConfig();
|
||||
config.moduleStates.put(module.getName(), module.isEnabled());
|
||||
save();
|
||||
}
|
||||
|
||||
public static void setSetting(AbstractSetting setting, Object value) {
|
||||
public static void setSetting(Setting setting, Object value) {
|
||||
ensureConfig();
|
||||
config.settings.put(setting.getModule().getName() + ":" + setting.getName(), value);
|
||||
config.settings.put(getSettingKey(setting), value);
|
||||
save();
|
||||
}
|
||||
|
||||
public static void setFramePosition(SettingsFrame frame) {
|
||||
ensureConfig();
|
||||
config.settingsFrames.put(frame.module.getName(), new int[]{frame.x, frame.y});
|
||||
config.settingsFrames.put(frame.module.getName(), new int[] {frame.x, frame.y});
|
||||
save();
|
||||
}
|
||||
|
||||
@@ -133,7 +112,7 @@ public class ConfigManager {
|
||||
|
||||
public static void setHudPosition(String id, int x, int y) {
|
||||
ensureConfig();
|
||||
config.hudPositions.put(id, new int[]{x, y});
|
||||
config.hudPositions.put(id, new int[] {x, y});
|
||||
save();
|
||||
}
|
||||
|
||||
@@ -145,62 +124,197 @@ public class ConfigManager {
|
||||
|
||||
public static void setSearchBarPosition(int x, int y) {
|
||||
ensureConfig();
|
||||
config.searchBarPosition = new int[]{x, y};
|
||||
config.searchBarPosition = new int[] {x, y};
|
||||
save();
|
||||
}
|
||||
|
||||
|
||||
// ------------------ APLICAR AJUSTES ------------------
|
||||
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
public static void applySetting(Module parent, AbstractSetting setting) {
|
||||
String id = parent.getName() + ":" + setting.getName();
|
||||
if (config.settings.containsKey(id)) {
|
||||
Object value = config.settings.get(id);
|
||||
public static void applySetting(Module parent, Setting setting) {
|
||||
String key = getSettingKey(setting);
|
||||
|
||||
switch (setting) {
|
||||
case BooleanSetting b -> b.setEnabled((boolean) value);
|
||||
case EnumSetting e -> e.setIndex(value instanceof Double val ? val.intValue() : (int) value);
|
||||
case NumberSetting n -> n.setValue((double) value);
|
||||
case StringSetting s -> s.setValue((String) value);
|
||||
case KeySetting k -> k.setKey(value instanceof Double val ? val.intValue() : (int) value);
|
||||
case ListSetting l -> {
|
||||
if (value instanceof Map<?, ?> map) {
|
||||
Map<Object, Boolean> converted = new HashMap<>();
|
||||
for (Object option : l.getOptions()) {
|
||||
Object key = String.valueOf(option);
|
||||
Object bv = map.get(key);
|
||||
converted.put(option, bv instanceof Boolean b && b);
|
||||
}
|
||||
l.setValues(converted);
|
||||
}
|
||||
} 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 (!config.settings.containsKey(key)) return;
|
||||
|
||||
if (r != null && g != null && b != null && a != null)
|
||||
c.setRGB(r.intValue(), g.intValue(), b.intValue(), a.intValue());
|
||||
Object value = config.settings.get(key);
|
||||
|
||||
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 -> {}
|
||||
}
|
||||
switch (setting) {
|
||||
case BooleanSetting booleanSetting -> applyBooleanSetting(booleanSetting, value);
|
||||
case EnumSetting enumSetting -> applyEnumSetting(enumSetting, value);
|
||||
case NumberSetting numberSetting -> applyNumberSetting(numberSetting, value);
|
||||
case StringSetting stringSetting -> applyStringSetting(stringSetting, value);
|
||||
case KeySetting keySetting -> applyKeySetting(keySetting, value);
|
||||
case ListSetting listSetting -> applyListSetting(listSetting, value);
|
||||
case ColorSetting colorSetting -> applyColorSetting(colorSetting, value);
|
||||
case OptionSetting optionSetting -> applyOptionSetting(optionSetting, value);
|
||||
default -> CameraTweaks.LOGGER.warn("watafac queseso: {}", setting.getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
private static void applyModuleStates() {
|
||||
ModuleManager.INSTANCE.getModules().forEach(module -> {
|
||||
if (config.moduleStates.containsKey(module.getName())) {
|
||||
module.setEnabled(config.moduleStates.get(module.getName()));
|
||||
}
|
||||
});
|
||||
CameraTweaks.LOGGER.info("estados de módulos aplicados");
|
||||
}
|
||||
|
||||
private static void applyModuleSettings() {
|
||||
ModuleManager.INSTANCE.getModules().forEach(module -> {
|
||||
module.getSettings().forEach(setting -> applySetting(module, setting));
|
||||
});
|
||||
CameraTweaks.LOGGER.info("ajustes de módulos aplicados");
|
||||
}
|
||||
|
||||
private static void applySettingsFrames() {
|
||||
config.settingsFrames.forEach((moduleName, position) -> {
|
||||
Module module = ModuleManager.INSTANCE.getModuleByName(moduleName);
|
||||
ClickGUI.INSTANCE.openSettingsFrame(module, position[0], position[1]);
|
||||
});
|
||||
CameraTweaks.LOGGER.info("estados de marcos de ajustes aplicados");
|
||||
}
|
||||
|
||||
private static void applySearchBarPosition() {
|
||||
if (config.searchBarPosition != null && config.searchBarPosition.length == 2) {
|
||||
ClickGUI.INSTANCE.getSearchBar().setX(config.searchBarPosition[0]);
|
||||
ClickGUI.INSTANCE.getSearchBar().setY(config.searchBarPosition[1]);
|
||||
}
|
||||
CameraTweaks.LOGGER.info("posición de la barra de búsqueda aplicada");
|
||||
}
|
||||
|
||||
private static void applyGuiSettings() {
|
||||
ClientSettingsFrame.guiSettings.setEnabled(true);
|
||||
ClientSettingsFrame.guiSettings.getSettings().forEach(setting -> {
|
||||
applySetting(ClientSettingsFrame.guiSettings, setting);
|
||||
});
|
||||
CameraTweaks.LOGGER.info("ajustes del cliente aplicados");
|
||||
}
|
||||
|
||||
private static void applyExtendableFrames() {
|
||||
applyExtendableFrame(ClickGUI.INSTANCE.getModulesFrame());
|
||||
applyExtendableFrame(ClickGUI.INSTANCE.getGuiSettingsFrame());
|
||||
|
||||
CameraTweaks.LOGGER.info("posiciones de marcos extendibles aplicadasa");
|
||||
ClickGUI.INSTANCE.refreshListButtons();
|
||||
}
|
||||
|
||||
private static void applyExtendableFrame(ModuleFrame frame) {
|
||||
ClientConfig.FrameData frameData = config.extendableFrames.get("M");
|
||||
if (frameData != null) {
|
||||
frame.x = frameData.x();
|
||||
frame.y = frameData.y();
|
||||
frame.extended = frameData.extended();
|
||||
}
|
||||
}
|
||||
|
||||
private static void applyExtendableFrame(ClientSettingsFrame frame) {
|
||||
ClientConfig.FrameData frameData = config.extendableFrames.get("S");
|
||||
if (frameData != null) {
|
||||
frame.x = frameData.x();
|
||||
frame.y = frameData.y();
|
||||
frame.extended = frameData.extended();
|
||||
}
|
||||
}
|
||||
|
||||
// ajustes de módulos
|
||||
|
||||
private static void applyBooleanSetting(BooleanSetting setting, Object value) {
|
||||
if (value instanceof Boolean) {
|
||||
setting.setEnabled((Boolean) value);
|
||||
}
|
||||
}
|
||||
|
||||
private static <T extends Enum<T>> void applyEnumSetting(EnumSetting<T> setting, Object value) {
|
||||
if (value instanceof Double) {
|
||||
setting.setIndex(((Double) value).intValue());
|
||||
} else if (value instanceof Integer) {
|
||||
setting.setIndex((Integer) value);
|
||||
}
|
||||
}
|
||||
|
||||
private static void applyNumberSetting(NumberSetting setting, Object value) {
|
||||
if (value instanceof Double) {
|
||||
setting.setValue((Double) value);
|
||||
}
|
||||
}
|
||||
|
||||
private static void applyStringSetting(StringSetting setting, Object value) {
|
||||
if (value instanceof String) {
|
||||
setting.setValue((String) value);
|
||||
}
|
||||
}
|
||||
|
||||
private static void applyKeySetting(KeySetting setting, Object value) {
|
||||
if (value instanceof Double) {
|
||||
setting.setKey(((Double) value).intValue());
|
||||
} else if (value instanceof Integer) {
|
||||
setting.setKey((Integer) value);
|
||||
}
|
||||
}
|
||||
|
||||
private static <T> void applyListSetting(ListSetting<T> setting, Object value) {
|
||||
if (value instanceof Map<?, ?> map) {
|
||||
Map<T, Boolean> convertedValues = new HashMap<>();
|
||||
|
||||
for (T option : setting.getOptions()) {
|
||||
String key = setting.getDisplayName(option);
|
||||
Object booleanValue = map.get(key);
|
||||
convertedValues.put(option, booleanValue instanceof Boolean && (Boolean) booleanValue);
|
||||
}
|
||||
|
||||
setting.setValues(convertedValues);
|
||||
}
|
||||
}
|
||||
|
||||
private static void applyColorSetting(ColorSetting setting, Object value) {
|
||||
if (!(value instanceof Map<?, ?> map)) return;
|
||||
|
||||
Number r = (Number) map.get("r");
|
||||
Number g = (Number) map.get("g");
|
||||
Number b = (Number) map.get("b");
|
||||
Number a = (Number) map.get("a");
|
||||
|
||||
if (r != null && g != null && b != null && a != null)
|
||||
setting.setRGB(r.intValue(), g.intValue(), b.intValue(), a.intValue());
|
||||
|
||||
applyOptionalProperty(map, "rb", Boolean.class, setting::setRainbow);
|
||||
applyOptionalProperty(map, "rs", Number.class, val -> setting.setRainbowSpeed(val.intValue()));
|
||||
applyOptionalProperty(map, "sat", Number.class, val -> setting.setSaturation(val.floatValue()));
|
||||
applyOptionalProperty(map, "bri", Number.class, val -> setting.setBrightness(val.floatValue()));
|
||||
}
|
||||
|
||||
private static <T> void applyOptionSetting(OptionSetting<T> setting, Object value) {
|
||||
if (value instanceof Double) {
|
||||
int index = ((Double) value).intValue();
|
||||
setting.setValue(setting.getOption(index));
|
||||
}
|
||||
}
|
||||
|
||||
private static <T> void applyOptionalProperty(Map<?, ?> map, String key, Class<T> type, java.util.function.Consumer<T> setter) {
|
||||
Object value = map.get(key);
|
||||
if (type.isInstance(value)) {
|
||||
setter.accept(type.cast(value));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------ MÉTODOS DE AYUDA ------------------
|
||||
|
||||
private static boolean shouldApply() {
|
||||
return CameraTweaks.mc != null && ModuleManager.INSTANCE != null && config != null;
|
||||
}
|
||||
|
||||
|
||||
private static void ensureConfig() {
|
||||
if (config == null) config = new ClientConfig();
|
||||
}
|
||||
|
||||
private static String getSettingKey(Setting setting) {
|
||||
return setting.getModule().getName() + ":" + setting.getName();
|
||||
}
|
||||
|
||||
public static boolean hasLoaded() {
|
||||
return loaded;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package me.retucio.camtweaks.event;
|
||||
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
|
||||
/**
|
||||
* @see me.retucio.camtweaks.mixin.MinecraftClientMixin#onJoinWorld
|
||||
*/
|
||||
public class JoinWorldEvent extends Event {
|
||||
|
||||
private final ClientWorld world;
|
||||
|
||||
public JoinWorldEvent(ClientWorld world) {
|
||||
this.world = world;
|
||||
}
|
||||
|
||||
public ClientWorld getWorld() {
|
||||
return world;
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,14 @@
|
||||
package me.retucio.camtweaks.event.events;
|
||||
|
||||
import io.netty.channel.ChannelFutureListener;
|
||||
import me.retucio.camtweaks.event.Event;
|
||||
import me.retucio.camtweaks.event.Stage;
|
||||
import net.minecraft.network.packet.Packet;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
|
||||
/**
|
||||
* @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#onReceivePacket
|
||||
*/
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
package me.retucio.camtweaks.event.events.camtweaks;
|
||||
|
||||
import me.retucio.camtweaks.event.Event;
|
||||
import me.retucio.camtweaks.module.settings.AbstractSetting;
|
||||
import me.retucio.camtweaks.module.settings.Setting;
|
||||
|
||||
// se genera cada que se cambia el valor de un ajuste
|
||||
public class UpdateSettingEvent extends Event {
|
||||
|
||||
private final AbstractSetting setting;
|
||||
private final Setting setting;
|
||||
private boolean shouldSave;
|
||||
|
||||
public UpdateSettingEvent(AbstractSetting setting, boolean shouldSave) {
|
||||
public UpdateSettingEvent(Setting setting, boolean shouldSave) {
|
||||
this.setting = setting;
|
||||
this.shouldSave = shouldSave;
|
||||
}
|
||||
|
||||
public AbstractSetting getSetting() {
|
||||
public Setting getSetting() {
|
||||
return setting;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import me.retucio.camtweaks.module.ModuleManager;
|
||||
import me.retucio.camtweaks.module.modules.ChatPlus;
|
||||
import me.retucio.camtweaks.module.modules.Freecam;
|
||||
import me.retucio.camtweaks.module.modules.NoRender;
|
||||
import me.retucio.camtweaks.ui.HudRenderer;
|
||||
import me.retucio.camtweaks.ui.hud.HudRenderer;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.client.gui.hud.InGameHud;
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.ibm.icu.util.CodePointTrie;
|
||||
import com.llamalad7.mixinextras.injector.ModifyReturnValue;
|
||||
import com.llamalad7.mixinextras.sugar.Local;
|
||||
import me.retucio.camtweaks.CameraTweaks;
|
||||
import me.retucio.camtweaks.event.JoinWorldEvent;
|
||||
import me.retucio.camtweaks.event.events.OpenScreenEvent;
|
||||
import me.retucio.camtweaks.event.events.ShutdownEvent;
|
||||
import me.retucio.camtweaks.event.events.TickEvent;
|
||||
@@ -12,6 +13,7 @@ import me.retucio.camtweaks.module.ModuleManager;
|
||||
import me.retucio.camtweaks.module.modules.FastUse;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.Hand;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
@@ -70,4 +72,10 @@ public abstract class MinecraftClientMixin {
|
||||
if (!fastUse.isEnabled()) return;
|
||||
itemUseCooldown = fastUse.getCooldown(stack);
|
||||
}
|
||||
|
||||
@Inject(method = "joinWorld", at = @At("HEAD"), cancellable = true)
|
||||
private void onJoinWorld(ClientWorld world, CallbackInfo ci) {
|
||||
JoinWorldEvent event = EVENT_BUS.post(new JoinWorldEvent(world));
|
||||
if (event.isCancelled()) ci.cancel();
|
||||
}
|
||||
}
|
||||
@@ -10,4 +10,7 @@ public interface HandledScreenAccessor {
|
||||
|
||||
@Accessor("focusedSlot")
|
||||
Slot getFocusedSlot();
|
||||
|
||||
@Accessor("doubleClicking")
|
||||
void setDoubleClicking(boolean doubleClicking);
|
||||
}
|
||||
@@ -1,12 +1,14 @@
|
||||
package me.retucio.camtweaks.module;
|
||||
|
||||
import me.retucio.camtweaks.CameraTweaks;
|
||||
import me.retucio.camtweaks.config.ClientConfig;
|
||||
import me.retucio.camtweaks.config.ConfigManager;
|
||||
import me.retucio.camtweaks.event.SubscribeEvent;
|
||||
import me.retucio.camtweaks.event.events.camtweaks.ToggleModuleEvent;
|
||||
import me.retucio.camtweaks.module.settings.BooleanSetting;
|
||||
import me.retucio.camtweaks.module.settings.EnumSetting;
|
||||
import me.retucio.camtweaks.module.settings.KeySetting;
|
||||
import me.retucio.camtweaks.module.settings.AbstractSetting;
|
||||
import me.retucio.camtweaks.module.settings.Setting;
|
||||
import me.retucio.camtweaks.util.ChatUtil;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
@@ -30,7 +32,7 @@ public class Module {
|
||||
protected KeySetting bind = new KeySetting("tecla", "tecla asignada al módulo, ESC para desactivar", GLFW.GLFW_KEY_UNKNOWN);
|
||||
protected BooleanSetting notify = new BooleanSetting("notificar", "notificar en el chat al activar / desactivar", true);
|
||||
|
||||
private final List<AbstractSetting> settings = new ArrayList<>();
|
||||
private final List<Setting> settings = new ArrayList<>();
|
||||
|
||||
protected MinecraftClient mc = MinecraftClient.getInstance();
|
||||
|
||||
@@ -45,23 +47,26 @@ public class Module {
|
||||
this.description = description;
|
||||
addSettings(bind, keyMode, notify);
|
||||
this.bind.setDefaultKey(key);
|
||||
this.bind.setKey(key);
|
||||
|
||||
// puto marcos
|
||||
if (ConfigManager.getConfig().settings.get(this.getName() + ":" + bind.getName()) == null)
|
||||
this.bind.setKey(key);
|
||||
}
|
||||
|
||||
// ajustes
|
||||
public List<AbstractSetting> getSettings() {
|
||||
public List<Setting> getSettings() {
|
||||
return settings;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <S extends AbstractSetting> S addSetting(AbstractSetting setting) {
|
||||
public <S extends Setting> S addSetting(Setting setting) {
|
||||
settings.add(setting);
|
||||
setting.setModule(this);
|
||||
return (S) setting; // por conveniencia
|
||||
}
|
||||
|
||||
public void addSettings(AbstractSetting... settings) {
|
||||
for (AbstractSetting setting : settings) addSetting(setting);
|
||||
public void addSettings(Setting... settings) {
|
||||
for (Setting setting : settings) addSetting(setting);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package me.retucio.camtweaks.module;
|
||||
|
||||
import me.retucio.camtweaks.CameraTweaks;
|
||||
import me.retucio.camtweaks.event.EventBus;
|
||||
import me.retucio.camtweaks.event.SubscribeEvent;
|
||||
import me.retucio.camtweaks.module.modules.*;
|
||||
@@ -16,10 +17,8 @@ public class ModuleManager {
|
||||
public static ModuleManager INSTANCE;
|
||||
|
||||
private final List<Module> modules = new ArrayList<>();
|
||||
private final EventBus eventBus;
|
||||
|
||||
public ModuleManager(EventBus bus) {
|
||||
this.eventBus = bus;
|
||||
public ModuleManager() {
|
||||
addModules();
|
||||
}
|
||||
|
||||
@@ -29,8 +28,10 @@ public class ModuleManager {
|
||||
modules.add(new AnvilFont());
|
||||
modules.add(new AttributeSwapper());
|
||||
modules.add(new AutoSign());
|
||||
modules.add(new BlockESP());
|
||||
modules.add(new BlockOutline());
|
||||
modules.add(new BossbarStack());
|
||||
modules.add(new BreakingProgress());
|
||||
modules.add(new BungeecordSpoofer());
|
||||
modules.add(new ChatPlus());
|
||||
modules.add(new ColoredSigns());
|
||||
@@ -45,19 +46,24 @@ public class ModuleManager {
|
||||
modules.add(new HandView());
|
||||
modules.add(new Headhitters());
|
||||
modules.add(new HUD());
|
||||
modules.add(new InventoryPlus());
|
||||
modules.add(new LightOverlay());
|
||||
modules.add(new LogoutSpots());
|
||||
modules.add(new Nametags());
|
||||
modules.add(new NoMiningInterruptions());
|
||||
modules.add(new NoRender());
|
||||
modules.add(new Offhand());
|
||||
modules.add(new PacketDelay());
|
||||
modules.add(new PerspectivePlus());
|
||||
modules.add(new PortalGUI());
|
||||
modules.add(new Racist());
|
||||
modules.add(new Reconnect());
|
||||
modules.add(new Rotations());
|
||||
modules.add(new RPackBypass());
|
||||
modules.add(new ScreenshotPlus());
|
||||
modules.add(new ShulkerPeek());
|
||||
modules.add(new TimeChanger());
|
||||
modules.add(new UIMove());
|
||||
modules.add(new WarnLowDurability());
|
||||
modules.add(new Zoom());
|
||||
|
||||
@@ -67,7 +73,7 @@ public class ModuleManager {
|
||||
for (Module module : getEnabledModules()) {
|
||||
for (Method method : module.getClass().getDeclaredMethods()) {
|
||||
if (method.isAnnotationPresent(SubscribeEvent.class)) {
|
||||
eventBus.register(module);
|
||||
CameraTweaks.EVENT_BUS.register(module);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
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.ListSetting;
|
||||
import me.retucio.camtweaks.module.settings.NumberSetting;
|
||||
import me.retucio.camtweaks.util.Colors;
|
||||
import me.retucio.camtweaks.util.Lists;
|
||||
import me.retucio.camtweaks.util.render.RenderUtil;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3i;
|
||||
import net.minecraft.util.shape.VoxelShape;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class BlockESP extends Module {
|
||||
|
||||
public ListSetting<Block> blocks = addSetting(new ListSetting<>("bloques", "bloques a resaltar",
|
||||
Lists.blockList, Lists.allFalse(Lists.blockList), Lists.blockNames));
|
||||
|
||||
public NumberSetting radius = addSetting(new NumberSetting("radio", "radio de búsqueda de bloques", 24, 2, 128, 1));
|
||||
|
||||
public BooleanSetting outlines = addSetting(new BooleanSetting("contorno", "renderizar contorno de bloques", true));
|
||||
public ColorSetting outlineColor = addSetting(new ColorSetting("color del contorno", "color del contorno", Colors.CELESTE, false));
|
||||
public NumberSetting lineWidth = addSetting(new NumberSetting("grosor del contorno", "grosor de las líneas del contorno", 1, 1, 5, 0.2));
|
||||
|
||||
public BooleanSetting fillings = addSetting(new BooleanSetting("relleno", "renderizar relleno de bloques", true));
|
||||
public ColorSetting fillingColor = addSetting(new ColorSetting("color del relleno", "color del relleno", new Color(57, 177, 215, 67), false));
|
||||
|
||||
|
||||
public BlockESP() {
|
||||
super("resaltado de bloques", "te muestra la posición de cierto tipo de bloque renderizando una caja con su forma");
|
||||
|
||||
outlines.onUpdate(v -> {
|
||||
outlineColor.setVisible(v);
|
||||
lineWidth.setVisible(v);
|
||||
});
|
||||
|
||||
fillings.onUpdate(v -> fillingColor.setVisible(v));
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onRenderWorld(RenderWorldEvent event) {
|
||||
if (mc.player == null || mc.world == null) return;
|
||||
|
||||
for (Block block : blocks.getOptions()) {
|
||||
if (blocks.isEnabled(block)) {
|
||||
List<BlockPos> blocksToHighlight = getNearbyBlocks(block);
|
||||
for (BlockPos pos : blocksToHighlight) {
|
||||
if (outlines.isEnabled()) {
|
||||
RenderUtil.drawVoxelShapeOutline(
|
||||
event.getMatrices(),
|
||||
getVoxelShape(pos),
|
||||
pos,
|
||||
outlineColor.getColor(),
|
||||
lineWidth.getFloatValue());
|
||||
}
|
||||
if (fillings.isEnabled()) {
|
||||
RenderUtil.drawVoxelShapeFilled(
|
||||
event.getMatrices(),
|
||||
getVoxelShape(pos),
|
||||
pos,
|
||||
fillingColor.getColor());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<BlockPos> getNearbyBlocks(Block block) {
|
||||
List<BlockPos> blockPosList = new ArrayList<>();
|
||||
|
||||
for (int i = -radius.getIntValue(); i < radius.getIntValue(); i++) {
|
||||
for (int j = -radius.getIntValue(); j < radius.getIntValue(); j++) {
|
||||
for (int k = -radius.getIntValue(); k < radius.getIntValue(); k++) {
|
||||
BlockPos pos = mc.player.getBlockPos().add(new Vec3i(i, j, k));
|
||||
if (mc.world.getBlockState(pos).getBlock() == block) {
|
||||
blockPosList.add(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return blockPosList;
|
||||
}
|
||||
|
||||
private VoxelShape getVoxelShape(BlockPos pos) {
|
||||
return mc.world.getBlockState(pos).getOutlineShape(mc.world, pos);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
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.EnumSetting;
|
||||
import me.retucio.camtweaks.module.settings.NumberSetting;
|
||||
import me.retucio.camtweaks.util.render.RenderUtil;
|
||||
import net.minecraft.util.hit.BlockHitResult;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Box;
|
||||
import net.minecraft.util.shape.VoxelShape;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
public class BreakingProgress extends Module {
|
||||
|
||||
public EnumSetting<BreakMode> breakMode = addSetting(new EnumSetting<>("modo de minado", "elige si el cubo se encoge o se dilata",
|
||||
BreakMode.class, BreakMode.INWARDS));
|
||||
|
||||
public BooleanSetting outlines = addSetting(new BooleanSetting("contorno", "renderizar contorno", true));
|
||||
public ColorSetting outlineColor = addSetting(new ColorSetting("color del contorno", "color del contorno",
|
||||
new Color(0, 255, 0, 200), false));
|
||||
public NumberSetting lineWidth = addSetting(new NumberSetting("grosor de línea", "grosor de las líneas del contorno", 1, 1, 5, 0.1));
|
||||
|
||||
public BooleanSetting fillings = addSetting(new BooleanSetting("relleno", "renderizar relleno", true));
|
||||
public ColorSetting fillingColor = addSetting(new ColorSetting("color del relleno", "color del relleno",
|
||||
new Color(0, 255, 0, 60), false));
|
||||
|
||||
public BreakingProgress() {
|
||||
super("progreso de minado", "te muestra el progreso de minado de un bloque de manera más visible");
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onRenderWorld(RenderWorldEvent event) {
|
||||
if (mc.interactionManager == null || mc.world == null) return;
|
||||
if (!(mc.crosshairTarget instanceof BlockHitResult hitResult)) return;
|
||||
BlockPos pos = hitResult.getBlockPos();
|
||||
|
||||
int breakingProgress = mc.interactionManager.getBlockBreakingProgress();
|
||||
if (breakingProgress <= 0) return;
|
||||
float progress = breakingProgress / 10f;
|
||||
|
||||
VoxelShape shape = mc.world.getBlockState(pos).getOutlineShape(mc.world, pos);
|
||||
if (shape.isEmpty()) return;
|
||||
|
||||
Box box = shape.getBoundingBox().offset(pos);
|
||||
|
||||
float shrinkFactor = breakMode.is(BreakMode.INWARDS)
|
||||
? 1f - progress
|
||||
: progress;
|
||||
|
||||
double centerX = (box.minX + box.maxX) / 2;
|
||||
double centerY = (box.minY + box.maxY) / 2;
|
||||
double centerZ = (box.minZ + box.maxZ) / 2;
|
||||
|
||||
double shrunkX = (box.maxX - box.minX) / 2 * shrinkFactor;
|
||||
double shrunkY = (box.maxY - box.minY) / 2 * shrinkFactor;
|
||||
double shrunkZ = (box.maxZ - box.minZ) / 2 * shrinkFactor;
|
||||
|
||||
Box scaledBox = new Box(
|
||||
centerX - shrunkX, centerY - shrunkY, centerZ - shrunkZ,
|
||||
centerX + shrunkX, centerY + shrunkZ, centerZ + shrunkZ
|
||||
);
|
||||
|
||||
if (outlines.isEnabled()) RenderUtil.drawOutlineBox(event.getMatrices(), scaledBox, outlineColor.getColor(), lineWidth.getFloatValue());
|
||||
if (fillings.isEnabled()) RenderUtil.drawFilledBox(event.getMatrices(), scaledBox, fillingColor.getColor());
|
||||
}
|
||||
|
||||
public enum BreakMode {
|
||||
INWARDS("para dentro"),
|
||||
OUTWARDS("para fuera");
|
||||
|
||||
private final String name;
|
||||
BreakMode(String name) { this.name = name; }
|
||||
@Override public String toString() { return name; }
|
||||
}
|
||||
}
|
||||
@@ -68,7 +68,7 @@ public class ChatPlus extends Module {
|
||||
private SimpleDateFormat dateFormat;
|
||||
|
||||
private static final Pattern loggerRegex = Pattern.compile("\\n(\\n|\\s)+\\n");
|
||||
private static final Pattern usernameRegex = Pattern.compile("^(?:<[0-9]{2}:[0-9]{2}>\\s)?<(.*?)>.*");
|
||||
private static final Pattern usernameRegex = Pattern.compile("^(?:\\[[0-9]{2}:[0-9]{2}\\]\\s*)?(?:<([^<>\\s]+)>|([^<>\\s]+)).*");
|
||||
private static final Pattern timestampRegex = Pattern.compile("^<\\d{1,2}:\\d{1,2}>");
|
||||
private static final Pattern coordRegex = Pattern.compile("(?<x>-?\\d{3,}(?:\\.\\d*)?)(?:\\s+(?<y>-?\\d{1,3}(?:\\.\\d*)?))?\\s+(?<z>-?\\d{3,}(?:\\.\\d*)?)");
|
||||
|
||||
@@ -96,7 +96,7 @@ public class ChatPlus extends Module {
|
||||
|
||||
// agregar sellos de tiempo a los mensajes
|
||||
if (timestamps.isEnabled()) {
|
||||
Text timestamp = Text.literal("<" + dateFormat.format(new Date()) + "> ").formatted(Formatting.GRAY);
|
||||
Text timestamp = Text.literal("[" + dateFormat.format(new Date()) + "] ").formatted(Formatting.GRAY);
|
||||
message = Text.empty().append(timestamp).append(message);
|
||||
}
|
||||
|
||||
@@ -178,6 +178,8 @@ public class ChatPlus extends Module {
|
||||
|
||||
if (usernameMatcher.matches()) {
|
||||
String username = usernameMatcher.group(1);
|
||||
if (username == null)
|
||||
username = usernameMatcher.group(2);
|
||||
|
||||
PlayerListEntry entry = mc.getNetworkHandler().getPlayerListEntry(username);
|
||||
if (entry != null) sender = entry.getProfile();
|
||||
|
||||
@@ -2,14 +2,17 @@ package me.retucio.camtweaks.module.modules;
|
||||
|
||||
import me.retucio.camtweaks.module.Module;
|
||||
import me.retucio.camtweaks.module.settings.*;
|
||||
import me.retucio.camtweaks.ui.screen.HudEditorScreen;
|
||||
import me.retucio.camtweaks.ui.hud.CoordsElement;
|
||||
import me.retucio.camtweaks.ui.hud.HudElement;
|
||||
import me.retucio.camtweaks.ui.hud.HudRenderer;
|
||||
import me.retucio.camtweaks.ui.hud.HudEditorScreen;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
/** lógica del HUD manejada en:
|
||||
* @see me.retucio.camtweaks.ui.HudRenderer
|
||||
* @see me.retucio.camtweaks.ui.widgets.HudElement
|
||||
* @see HudRenderer
|
||||
* @see HudElement
|
||||
* @see HudEditorScreen
|
||||
*/
|
||||
|
||||
@@ -28,6 +31,7 @@ public class HUD extends Module {
|
||||
public NumberSetting timezone = addSetting(new NumberSetting("zona horaria", "zona horaria en UTC+n", 1, -6, 6, 1));
|
||||
public EnumSetting<TimeFormat> timeFormat = addSetting(new EnumSetting<>("formato de la hora", "12h o 24h", TimeFormat.class, TimeFormat.TWENTY_FOUR_HOUR));
|
||||
public StringSetting customText = addSetting(new StringSetting("texto custom", "marca de agua (dejar vacío para quitar)", "adolf jitler inshtagram feishbuc twiter", 40));
|
||||
public EnumSetting<CoordsMode> coordsMode = addSetting(new EnumSetting<>("modo de coordenadas", "qué coordenadas mostrar", CoordsMode.class, CoordsMode.OVERWORLD));
|
||||
|
||||
public HUD() {
|
||||
super("HUD", "superposición de la pantalla con info. adicional");
|
||||
@@ -41,4 +45,14 @@ public class HUD extends Module {
|
||||
TimeFormat(String name) { this.name = name; }
|
||||
@Override public String toString() { return name; }
|
||||
}
|
||||
|
||||
public enum CoordsMode {
|
||||
OVERWORLD("superficie"),
|
||||
NETHER("nether"),
|
||||
BOTH("ambas");
|
||||
|
||||
private final String name;
|
||||
CoordsMode(String name) { this.name = name; }
|
||||
@Override public String toString() { return name; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package me.retucio.camtweaks.module.modules;
|
||||
|
||||
import me.retucio.camtweaks.event.Event;
|
||||
import me.retucio.camtweaks.event.SubscribeEvent;
|
||||
import me.retucio.camtweaks.event.events.KeyEvent;
|
||||
import me.retucio.camtweaks.event.events.MouseClickEvent;
|
||||
import me.retucio.camtweaks.mixin.accessor.HandledScreenAccessor;
|
||||
import me.retucio.camtweaks.module.Module;
|
||||
import me.retucio.camtweaks.module.settings.KeySetting;
|
||||
import me.retucio.camtweaks.util.InventoryUtil;
|
||||
import me.retucio.camtweaks.util.KeyUtil;
|
||||
import net.minecraft.client.gui.screen.ingame.HandledScreen;
|
||||
import net.minecraft.screen.slot.Slot;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
public class InventoryPlus extends Module {
|
||||
|
||||
public KeySetting row1key = addSetting(new KeySetting("fila 1", "tecla para mover items a la primera fila", GLFW.GLFW_KEY_A));
|
||||
public KeySetting row2key = addSetting(new KeySetting("fila 2", "tecla para mover items a la segunda fila", GLFW.GLFW_KEY_S));
|
||||
public KeySetting row3key = addSetting(new KeySetting("fila 3", "tecla para mover items a la tercera fila", GLFW.GLFW_KEY_D));
|
||||
|
||||
public InventoryPlus() {
|
||||
super("inventario plus", "mueve ítems del inventario usando solo el teclado");
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onKey(KeyEvent event) {
|
||||
if (event.getAction() == GLFW.GLFW_RELEASE) return;
|
||||
processInput(event.getKey(), event);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onMouseButton(MouseClickEvent event) {
|
||||
if (event.getAction() == GLFW.GLFW_RELEASE) return;
|
||||
processInput(event.getButton(), event);
|
||||
}
|
||||
|
||||
private void processInput(int inputCode, Event event) {
|
||||
if (!(mc.currentScreen instanceof HandledScreen<?> screen) || mc.player == null) return;
|
||||
|
||||
Slot focusedSlot = ((HandledScreenAccessor) screen).getFocusedSlot();
|
||||
if (focusedSlot == null) return;
|
||||
|
||||
int containerSlot = focusedSlot.id;
|
||||
int hotbarKeyIndex = InventoryUtil.getSlotNumberFromKey(inputCode);
|
||||
if (hotbarKeyIndex == -1) return;
|
||||
|
||||
int rowOffset = InventoryUtil.getRowOffset(screen);
|
||||
|
||||
if (KeyUtil.isKeyDown(row1key.getKey())) {
|
||||
event.cancel();
|
||||
swapWithRow(screen, containerSlot, hotbarKeyIndex, rowOffset);
|
||||
}
|
||||
else if (KeyUtil.isKeyDown(row2key.getKey())) {
|
||||
event.cancel();
|
||||
swapWithRow(screen, containerSlot, hotbarKeyIndex, rowOffset + 9);
|
||||
}
|
||||
else if (KeyUtil.isKeyDown(row3key.getKey())) {
|
||||
event.cancel();
|
||||
swapWithRow(screen, containerSlot, hotbarKeyIndex, rowOffset + 18);
|
||||
}
|
||||
}
|
||||
|
||||
private void swapWithRow(HandledScreen<?> screen, int containerSlot, int column, int rowOffset) {
|
||||
int targetContainerSlot = InventoryUtil.calculateTargetSlot(screen, containerSlot, column, rowOffset);
|
||||
if (targetContainerSlot != -1) {
|
||||
InventoryUtil.swapSlots(containerSlot, targetContainerSlot, screen);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -50,6 +50,7 @@ public class LightOverlay extends Module {
|
||||
}
|
||||
|
||||
for (BlockPos block : blocks) {
|
||||
if (mc.world.getBlockState(block).isAir() || !mc.world.getBlockState(block.up()).isAir()) continue;
|
||||
if (!mc.world.isTopSolid(block, mc.player) || !mc.world.getBlockState(block).isOpaque()) continue;
|
||||
int light = mc.world.getLightLevel(LightType.BLOCK, block.up());
|
||||
|
||||
|
||||
@@ -9,6 +9,8 @@ import me.retucio.camtweaks.module.ModuleManager;
|
||||
import me.retucio.camtweaks.module.settings.BooleanSetting;
|
||||
import me.retucio.camtweaks.module.settings.ColorSetting;
|
||||
import me.retucio.camtweaks.module.settings.EnumSetting;
|
||||
import me.retucio.camtweaks.module.settings.NumberSetting;
|
||||
import me.retucio.camtweaks.util.MiscUtil;
|
||||
import me.retucio.camtweaks.util.render.RenderUtil;
|
||||
import net.minecraft.client.network.OtherClientPlayerEntity;
|
||||
import net.minecraft.client.network.PlayerListEntry;
|
||||
@@ -33,6 +35,7 @@ public class LogoutSpots extends Module {
|
||||
|
||||
public BooleanSetting outlines = addSetting(new BooleanSetting("contorno", "renderizar contorno de la caja (lados)", true));
|
||||
public ColorSetting outlineColor = addSetting(new ColorSetting("color del contorno", "Color de las líneas", new Color(255, 0, 0, 230), false));
|
||||
public NumberSetting lineWidth = addSetting(new NumberSetting("grosor de línea", "grosor de las líneas del contorno", 1.5, 0.5, 5, 0.1));
|
||||
|
||||
public BooleanSetting filling = addSetting(new BooleanSetting("relleno", "renderizar relleno de la caja (caras)", true));
|
||||
public ColorSetting fillingColor = addSetting(new ColorSetting("color del relleno", "Color de los lados", new Color(230, 0, 0, 55), false));
|
||||
@@ -40,8 +43,6 @@ public class LogoutSpots extends Module {
|
||||
public BooleanSetting fullHeight = addSetting(new BooleanSetting("hitbox completa", "renderizar la caja completa de la hitbox, o solo marcar la posición", true));
|
||||
|
||||
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<>();
|
||||
@@ -65,7 +66,6 @@ public class LogoutSpots extends Module {
|
||||
|
||||
dummy.onUpdate(v -> {
|
||||
if (!v) removeDummies();
|
||||
healthMode.setVisible(v);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -215,7 +215,6 @@ public class LogoutSpots extends Module {
|
||||
|
||||
public final UUID uuid;
|
||||
public final String name;
|
||||
public final int health;
|
||||
public final String logoutTime;
|
||||
|
||||
public final String dummyName;
|
||||
@@ -234,45 +233,25 @@ public class LogoutSpots extends Module {
|
||||
|
||||
this.uuid = player.getUuid();
|
||||
this.name = player.getName().getString();
|
||||
this.health = Math.round(player.getHealth() + player.getAbsorptionAmount());
|
||||
this.logoutTime = getLogoutTime();
|
||||
this.logoutTime = MiscUtil.getCurrentFormattedTime();
|
||||
|
||||
String healthText = healthMode.is(Nametags.HealthMode.HEARTS)
|
||||
? String.format("%.2f", (float) health / 2)
|
||||
: health + "hp";
|
||||
|
||||
this.dummyName = name + " [" + healthText + "] (" + logoutTime + ")";
|
||||
this.dummyName = name + " (" + 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);
|
||||
RenderUtil.drawOutlineBox(matrices, new Box(x, y, z, x + xWidth, y + height, z + zWidth), outlineColor.getColor(), lineWidth.getFloatValue());
|
||||
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);
|
||||
RenderUtil.drawOutlineBox(matrices, bottomBox, outlineColor.getColor(), lineWidth.getFloatValue());
|
||||
}
|
||||
if (filling.isEnabled()) {
|
||||
RenderUtil.drawBlockFaceFilled(matrices,
|
||||
|
||||
@@ -8,6 +8,7 @@ import me.retucio.camtweaks.module.settings.EnumSetting;
|
||||
import me.retucio.camtweaks.module.settings.ListSetting;
|
||||
import me.retucio.camtweaks.util.Lists;
|
||||
import net.minecraft.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.LazyEntityReference;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
@@ -24,6 +25,7 @@ import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@@ -39,8 +41,9 @@ import java.util.concurrent.Executors;
|
||||
|
||||
public class Nametags extends Module {
|
||||
|
||||
Map<EntityType<?>, Boolean> defaultEntities = Lists.allFalse(Lists.entityList);
|
||||
public ListSetting<EntityType<?>> entities = addSetting(new ListSetting<>("entidades", "entidades cuyo nametag será visible",
|
||||
Lists.entityList, Lists.allFalse(Lists.entityList), Lists.entityNames));
|
||||
Lists.entityList, defaultEntities, Lists.entityNames));
|
||||
|
||||
public BooleanSetting alwaysVisible = addSetting(new BooleanSetting("siempre mostrar nametags", "mostrar nametag cuando el jugador está agachado o es invisible", false));
|
||||
public BooleanSetting health = addSetting(new BooleanSetting("mostrar vida", "muestra la vida de una entidad en su nametag", true));
|
||||
@@ -62,17 +65,22 @@ public class Nametags extends Module {
|
||||
super("nametags", "modifica la manera en la que se renderizan los nametags");
|
||||
|
||||
// entidades activadas por defecto
|
||||
entities.setEnabled(EntityType.PLAYER, true);
|
||||
entities.setEnabled(EntityType.ITEM, true);
|
||||
entities.setEnabled(EntityType.ARROW, true);
|
||||
entities.setEnabled(EntityType.SPECTRAL_ARROW, true);
|
||||
entities.setEnabled(EntityType.TRIDENT, true);
|
||||
entities.setDefaultValues(entities.getValues());
|
||||
defaultEntities.replace(EntityType.PLAYER, true);
|
||||
defaultEntities.replace(EntityType.ITEM, true);
|
||||
defaultEntities.replace(EntityType.ARROW, true);
|
||||
defaultEntities.replace(EntityType.SPECTRAL_ARROW, true);
|
||||
defaultEntities.replace(EntityType.TRIDENT, true);
|
||||
entities.setDefaultValues(defaultEntities);
|
||||
|
||||
health.onUpdate(v -> healthMode.setVisible(v));
|
||||
|
||||
entities.onUpdate(entities -> {
|
||||
items.setVisible(entities.get(EntityType.ITEM));
|
||||
|
||||
boolean anyProjectile = entities.get(EntityType.TRIDENT)
|
||||
|| entities.get(EntityType.ARROW)
|
||||
|| entities.get(EntityType.SPECTRAL_ARROW);
|
||||
showProjectileDamage.setVisible(anyProjectile);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
package me.retucio.camtweaks.module.modules;
|
||||
|
||||
import me.retucio.camtweaks.module.Module;
|
||||
import me.retucio.camtweaks.module.settings.BooleanSetting;
|
||||
import me.retucio.camtweaks.module.settings.NumberSetting;
|
||||
import me.retucio.camtweaks.module.settings.OptionSetting;
|
||||
import me.retucio.camtweaks.util.Lists;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket;
|
||||
import net.minecraft.network.packet.c2s.play.UpdateSelectedSlotC2SPacket;
|
||||
import net.minecraft.screen.slot.SlotActionType;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
|
||||
public class Offhand extends Module {
|
||||
|
||||
public OptionSetting<Item> item = addSetting(new OptionSetting<>("ítem", "ítem a equipar",
|
||||
Lists.itemList, Items.TOTEM_OF_UNDYING, Lists.itemNames));
|
||||
public NumberSetting delaySetting = addSetting(new NumberSetting("delay", "delay del cambiazo (en ticks)", 0, 0, 20, 1));
|
||||
public BooleanSetting override = addSetting(new BooleanSetting("anular", "ignora que ya haya un ítem en la mano secundaria", true));
|
||||
|
||||
|
||||
private int delay;
|
||||
private boolean holdingItem;
|
||||
|
||||
public Offhand() {
|
||||
super("mano secundaria", "automáticamente equipa un ítem en la mano secundaria");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTick() {
|
||||
if (mc.player == null || mc.interactionManager == null) return;
|
||||
|
||||
if (holdingItem && mc.player.getOffHandStack().getItem() != item.getValue())
|
||||
delay = Math.max(delaySetting.getIntValue(), delay);
|
||||
|
||||
holdingItem = mc.player.getOffHandStack().getItem() == item.getValue();
|
||||
|
||||
if (delay > 0) {
|
||||
delay--;
|
||||
return;
|
||||
}
|
||||
|
||||
if (holdingItem || (!mc.player.getOffHandStack().isEmpty()
|
||||
&& !override.isEnabled()))
|
||||
return;
|
||||
|
||||
if (mc.player.playerScreenHandler == mc.player.currentScreenHandler) {
|
||||
for (int i = 9; i < 45; i++) {
|
||||
|
||||
if (mc.player.getInventory().getStack(i >= 36 ? i - 36 : i).getItem() == item.getValue()) {
|
||||
boolean itemInOffhand = !mc.player.getOffHandStack().isEmpty();
|
||||
|
||||
mc.interactionManager.clickSlot(mc.player.currentScreenHandler.syncId, i, 0, SlotActionType.PICKUP, mc.player);
|
||||
mc.interactionManager.clickSlot(mc.player.currentScreenHandler.syncId, 45, 0, SlotActionType.PICKUP, mc.player);
|
||||
|
||||
if (itemInOffhand)
|
||||
mc.interactionManager.clickSlot(mc.player.currentScreenHandler.syncId, i, 0, SlotActionType.PICKUP, mc.player);
|
||||
|
||||
delay = delaySetting.getIntValue();
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < 9; i++) {
|
||||
if (mc.player.getInventory().getStack(i).getItem() == item.getValue()) {
|
||||
if (i != mc.player.getInventory().getSelectedSlot()) {
|
||||
mc.player.getInventory().setSelectedSlot(i);
|
||||
mc.player.networkHandler.sendPacket(new UpdateSelectedSlotC2SPacket(i));
|
||||
}
|
||||
|
||||
mc.player.networkHandler.sendPacket(new PlayerActionC2SPacket(
|
||||
PlayerActionC2SPacket.Action.SWAP_ITEM_WITH_OFFHAND,
|
||||
BlockPos.ORIGIN,
|
||||
Direction.DOWN));
|
||||
delay = delaySetting.getIntValue();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
package me.retucio.camtweaks.module.modules;
|
||||
|
||||
import me.retucio.camtweaks.event.JoinWorldEvent;
|
||||
import me.retucio.camtweaks.event.SubscribeEvent;
|
||||
import me.retucio.camtweaks.event.events.DisconnectEvent;
|
||||
import me.retucio.camtweaks.event.events.PacketEvent;
|
||||
import me.retucio.camtweaks.module.Module;
|
||||
import me.retucio.camtweaks.module.settings.EnumSetting;
|
||||
import me.retucio.camtweaks.module.settings.NumberSetting;
|
||||
import me.retucio.camtweaks.util.ChatUtil;
|
||||
import me.retucio.camtweaks.util.NetworkUtil;
|
||||
|
||||
import net.minecraft.network.ClientConnection;
|
||||
import net.minecraft.network.listener.PacketListener;
|
||||
import net.minecraft.network.message.SentMessage;
|
||||
import net.minecraft.network.packet.Packet;
|
||||
import net.minecraft.network.packet.c2s.common.CustomPayloadC2SPacket;
|
||||
import net.minecraft.network.packet.c2s.common.KeepAliveC2SPacket;
|
||||
import net.minecraft.network.packet.s2c.common.KeepAliveS2CPacket;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
|
||||
public class PacketDelay extends Module {
|
||||
|
||||
public NumberSetting delay = addSetting(new NumberSetting("delay", "delay a añadir a los paquetes, en milisegundos", 1500, 0, 3000, 5));
|
||||
public EnumSetting<Directions> directions = addSetting(new EnumSetting<>("dirección", "dirección de los paquetes a los que añadir delay",
|
||||
Directions.class, Directions.BOTH));
|
||||
public EnumSetting<Packets> packets = addSetting(new EnumSetting<>("paquetes", "paquetes a los que aplicar el delay",
|
||||
Packets.class, Packets.ALL));
|
||||
|
||||
private final List<DelayedPacket> delayedPackets = new CopyOnWriteArrayList<>();
|
||||
private long lastProcessTime = 0;
|
||||
|
||||
public PacketDelay() {
|
||||
super("delay de paquetes", "aplica un delay a los paquetes");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
for (DelayedPacket delayedPacket : delayedPackets)
|
||||
processDelayedPacket(delayedPacket);
|
||||
delayedPackets.clear();
|
||||
super.onDisable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTick() {
|
||||
if (mc.player == null || mc.world == null || mc.getNetworkHandler() == null) {
|
||||
delayedPackets.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
long currentTime = System.currentTimeMillis();
|
||||
if (currentTime - lastProcessTime < 50) return;
|
||||
lastProcessTime = currentTime;
|
||||
|
||||
List<DelayedPacket> toProcess = new ArrayList<>();
|
||||
for (DelayedPacket packet : delayedPackets) {
|
||||
if (System.currentTimeMillis() >= packet.scheduledTime())
|
||||
toProcess.add(packet);
|
||||
}
|
||||
|
||||
for (DelayedPacket packet : toProcess) {
|
||||
processDelayedPacket(packet);
|
||||
delayedPackets.remove(packet);
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onPacketSend(PacketEvent.Send event) {
|
||||
if (directions.is(Directions.S2C)
|
||||
|| mc.player == null || mc.world == null || mc.getNetworkHandler() == null
|
||||
|| (event.getPacket() instanceof KeepAliveC2SPacket && !packets.is(Packets.OTHERS)))
|
||||
return;
|
||||
|
||||
event.cancel();
|
||||
|
||||
delayedPackets.add(new DelayedPacket(
|
||||
event.getPacket(),
|
||||
System.currentTimeMillis() + delay.getLongValue(),
|
||||
true,
|
||||
mc.getNetworkHandler().getConnection().getPacketListener()
|
||||
));
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onPacketReceive(PacketEvent.Receive event) {
|
||||
if (mc.player == null || mc.world == null
|
||||
|| mc.getNetworkHandler() == null || mc.getNetworkHandler().getConnection() == null
|
||||
|| (event.getPacket() instanceof KeepAliveS2CPacket && !packets.is(Packets.OTHERS)))
|
||||
return;
|
||||
|
||||
event.cancel();
|
||||
|
||||
ClientConnection connection = mc.getNetworkHandler().getConnection();
|
||||
|
||||
delayedPackets.add(new DelayedPacket(
|
||||
event.getPacket(),
|
||||
System.currentTimeMillis() + delay.getLongValue(),
|
||||
false,
|
||||
connection.getPacketListener()
|
||||
));
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onJoinWorld(JoinWorldEvent event) {
|
||||
ChatUtil.error("delay de paquetes no funciona en un solo jugador");
|
||||
toggle();
|
||||
}
|
||||
|
||||
private void processDelayedPacket(DelayedPacket delayedPacket) {
|
||||
if (mc.getNetworkHandler() == null) return;
|
||||
|
||||
if (delayedPacket.isOutgoing()) {
|
||||
NetworkUtil.sendPacketNoEvent(delayedPacket.packet());
|
||||
} else {
|
||||
if (delayedPacket.packetListener != null && mc.getNetworkHandler().getConnection() != null) {
|
||||
NetworkUtil.receivePacketNoEvent(delayedPacket.packet(), delayedPacket.packetListener());
|
||||
} else {
|
||||
NetworkUtil.receivePacketNoEvent(delayedPacket.packet());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private record DelayedPacket(Packet<?> packet, long scheduledTime, boolean isOutgoing, PacketListener packetListener) {}
|
||||
|
||||
public enum Directions {
|
||||
C2S("cliente a server"),
|
||||
S2C("server a cliente"),
|
||||
BOTH("ambos");
|
||||
|
||||
private final String name;
|
||||
Directions(String name) { this.name = name; }
|
||||
@Override public String toString() { return name; }
|
||||
}
|
||||
|
||||
public enum Packets {
|
||||
KEEP_ALIVE("paquetes KeepAlive"),
|
||||
OTHERS("todos menos KeepAlive"),
|
||||
ALL("todos");
|
||||
|
||||
private final String name;
|
||||
Packets(String name) { this.name = name; }
|
||||
@Override public String toString() { return name; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package me.retucio.camtweaks.module.modules;
|
||||
|
||||
import me.retucio.camtweaks.module.Module;
|
||||
import me.retucio.camtweaks.util.EntityUtil;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.mob.EndermanEntity;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Racist extends Module {
|
||||
|
||||
private int lookTimer;
|
||||
private final List<EndermanEntity> lookedEndermen = new ArrayList<>();
|
||||
|
||||
public Racist() {
|
||||
super("racismo", "amego segarro");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
lookedEndermen.clear();
|
||||
super.onDisable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTick() {
|
||||
if (mc.world == null || mc.player == null) return;
|
||||
|
||||
for (Entity entity : mc.world.getEntities()) {
|
||||
if (!(entity instanceof EndermanEntity enderman)) continue;
|
||||
|
||||
if (shouldLookAt(enderman)) {
|
||||
lookAtEnderman(enderman);
|
||||
|
||||
lookedEndermen.add(enderman);
|
||||
lookTimer = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
lookTimer++;
|
||||
}
|
||||
|
||||
private boolean shouldLookAt(EndermanEntity enderman) {
|
||||
return !(lookedEndermen.contains(enderman)) && lookTimer >= 10
|
||||
&& EntityUtil.hasLineOfSight(mc.player, enderman);
|
||||
}
|
||||
|
||||
private void lookAtEnderman(EndermanEntity enderman) {
|
||||
double yaw = EntityUtil.getYaw(enderman);
|
||||
double pitch = EntityUtil.getPitch(enderman, EntityUtil.Target.HEAD);
|
||||
|
||||
mc.player.setYaw((float) yaw);
|
||||
mc.player.setPitch((float) pitch);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -10,6 +10,7 @@ import me.retucio.camtweaks.ui.screen.PreviewScreen;
|
||||
import me.retucio.camtweaks.util.ChatUtil;
|
||||
import me.retucio.camtweaks.util.Colors;
|
||||
|
||||
import me.retucio.camtweaks.util.InventoryUtil;
|
||||
import me.retucio.camtweaks.util.MiscUtil;
|
||||
import net.minecraft.block.ShulkerBoxBlock;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
@@ -94,11 +95,11 @@ public class ShulkerPeek extends Module {
|
||||
} else return;
|
||||
|
||||
if (stack.getItem() == Items.ENDER_CHEST) {
|
||||
if (MiscUtil.getEchestInv() == null) {
|
||||
if (InventoryUtil.getEchestInv() == null) {
|
||||
ChatUtil.warn("abre un enderchest primero");
|
||||
return;
|
||||
}
|
||||
mc.setScreen(new PreviewScreen(MiscUtil.getEchestInv(), mc.currentScreen));
|
||||
mc.setScreen(new PreviewScreen(InventoryUtil.getEchestInv(), mc.currentScreen));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
package me.retucio.camtweaks.module.modules;
|
||||
|
||||
import me.retucio.camtweaks.mixin.accessor.KeyBindingAccessor;
|
||||
import me.retucio.camtweaks.module.Module;
|
||||
import me.retucio.camtweaks.module.settings.ListSetting;
|
||||
import me.retucio.camtweaks.ui.screen.ClickGUI;
|
||||
import me.retucio.camtweaks.util.KeyUtil;
|
||||
import me.retucio.camtweaks.util.Lists;
|
||||
|
||||
import net.minecraft.client.gui.screen.ingame.HandledScreen;
|
||||
import net.minecraft.client.option.KeyBinding;
|
||||
import net.minecraft.screen.GenericContainerScreenHandler;
|
||||
import net.minecraft.screen.ScreenHandlerType;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class UIMove extends Module {
|
||||
|
||||
public ListSetting<ScreenHandlerType<?>> screens = addSetting(new ListSetting<>("interfaces", "interfaces en las que te podrás mover",
|
||||
Lists.screenList, Lists.allTrue(Lists.screenList), Lists.screenNames));
|
||||
|
||||
private List<KeyBinding> movementKeys;
|
||||
|
||||
private final ScreenHandlerType<?> inventoryHandlerType = ScreenHandlerType.register(
|
||||
"player_inventory", GenericContainerScreenHandler::createGeneric9x3);
|
||||
private final ScreenHandlerType<?> clickGuiHandlerType = ScreenHandlerType.register(
|
||||
"camtweaks_clickgui", GenericContainerScreenHandler::createGeneric9x3); // 9x3 porque no importa (creo)
|
||||
|
||||
public UIMove() {
|
||||
super("moverse en interfaz", "te permite seguir usando las teclas de movimiento aún estando en ciertas interfaces");
|
||||
screens.addOption(inventoryHandlerType, true, "inventario");
|
||||
screens.addOption(clickGuiHandlerType, true, "interfaz del mod");
|
||||
|
||||
screens.onUpdate(v -> unpress());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
movementKeys = Arrays.asList(
|
||||
mc.options.forwardKey,
|
||||
mc.options.backKey,
|
||||
mc.options.leftKey,
|
||||
mc.options.rightKey,
|
||||
mc.options.jumpKey,
|
||||
mc.options.sneakKey,
|
||||
mc.options.sprintKey);
|
||||
super.onEnable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
unpress();
|
||||
super.onDisable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTick() {
|
||||
if (mc.player == null || mc.options == null || mc.currentScreen == null) return;
|
||||
|
||||
ScreenHandlerType<?> handler = null;
|
||||
if (mc.currentScreen == ClickGUI.INSTANCE)
|
||||
handler = clickGuiHandlerType;
|
||||
|
||||
if (mc.currentScreen instanceof HandledScreen<?> screen) {
|
||||
try {
|
||||
handler = screen.getScreenHandler().getType();
|
||||
} catch (UnsupportedOperationException e) {
|
||||
handler = inventoryHandlerType;
|
||||
}
|
||||
}
|
||||
|
||||
if (handler == null || !screens.isEnabled(handler)) return;
|
||||
|
||||
for (KeyBinding kb : movementKeys) {
|
||||
kb.setPressed(KeyUtil.isKeyDown((
|
||||
(KeyBindingAccessor) kb).getBoundKey().getCode()));
|
||||
}
|
||||
}
|
||||
|
||||
private void unpress() {
|
||||
if (movementKeys == null) return;
|
||||
for (KeyBinding kb : movementKeys) {
|
||||
kb.setPressed(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,9 +3,12 @@ package me.retucio.camtweaks.module.modules;
|
||||
import me.retucio.camtweaks.module.Module;
|
||||
import me.retucio.camtweaks.module.settings.BooleanSetting;
|
||||
import me.retucio.camtweaks.module.settings.NumberSetting;
|
||||
import me.retucio.camtweaks.module.settings.OptionSetting;
|
||||
import me.retucio.camtweaks.util.ChatUtil;
|
||||
import me.retucio.camtweaks.util.Lists;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.sound.SoundCategory;
|
||||
import net.minecraft.sound.SoundEvent;
|
||||
import net.minecraft.sound.SoundEvents;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Formatting;
|
||||
@@ -15,19 +18,29 @@ 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 NumberSetting limitPercentage = addSetting(new NumberSetting("porcentaje", "porcentaje de durabilidad restante a la que se te avisa",
|
||||
5, 1, 100, 1));
|
||||
|
||||
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 message = addSetting(new BooleanSetting("enviar mensaje", "enviar un mensaje para alertar al usuario", true));
|
||||
|
||||
public BooleanSetting playSound = addSetting(new BooleanSetting("reproducir sonido", "reproducir un sonido para alertar al usuario", true));
|
||||
public OptionSetting<SoundEvent> sound = addSetting(new OptionSetting<>("sonido", "qué sonido reproducir",
|
||||
Lists.soundList, SoundEvents.BLOCK_NOTE_BLOCK_BELL.value(), Lists.soundNames));
|
||||
public NumberSetting volume = addSetting(new NumberSetting("volumen", "volumen del sonido", 70, 0, 125, 1));
|
||||
public NumberSetting pitch = addSetting(new NumberSetting("frecuencia", "altura del sonido", 70, 0, 125, 1));
|
||||
|
||||
private final List<ItemStack> warned = new ArrayList<>();
|
||||
|
||||
public WarnLowDurability() {
|
||||
super("aviso de baja dur.", "te avisa cuando la herramienta que sostengas sobrepase un límite de durabilidad");
|
||||
|
||||
playSound.onUpdate(v -> {
|
||||
sound.setVisible(v);
|
||||
volume.setVisible(v);
|
||||
pitch.setVisible(v);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -39,9 +52,13 @@ public class WarnLowDurability extends Module {
|
||||
float percentage = (1 - (float) stack.getDamage() / stack.getMaxDamage()) * 100;
|
||||
|
||||
if (percentage <= limitPercentage.getValue()) {
|
||||
if (sound.isEnabled())
|
||||
if (playSound.isEnabled())
|
||||
mc.world.playSound(mc.player, mc.player.getBlockPos(),
|
||||
SoundEvents.BLOCK_BELL_USE, SoundCategory.AMBIENT, 1, 1);
|
||||
sound.getValue(),
|
||||
SoundCategory.AMBIENT,
|
||||
toExponential(volume),
|
||||
toExponential(pitch)
|
||||
);
|
||||
|
||||
if (message.isEnabled()) {
|
||||
String customName = stack.getCustomName() == null ? "" : " \"" + stack.getCustomName().getString() + "\"";
|
||||
@@ -61,4 +78,15 @@ public class WarnLowDurability extends Module {
|
||||
warned.clear();
|
||||
super.onDisable();
|
||||
}
|
||||
|
||||
// el sistema decibélico es un sistema logarítmico
|
||||
private float toExponential(NumberSetting setting) {
|
||||
double linear = setting.getValue();
|
||||
|
||||
double normalized = linear / (setting.getMax() - setting.getMax() / 4);
|
||||
double exponential = Math.pow(normalized, 3);
|
||||
|
||||
if (exponential < 0.01) exponential = 0;
|
||||
return (float) exponential;
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,9 @@
|
||||
package me.retucio.camtweaks.module.settings;
|
||||
|
||||
import me.retucio.camtweaks.CameraTweaks;
|
||||
import me.retucio.camtweaks.event.events.camtweaks.UpdateSettingEvent;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
// ajuste booleano, es decir, o se encuentra encencido o apagado (similar a un interruptor)
|
||||
public class BooleanSetting extends AbstractSetting {
|
||||
public class BooleanSetting extends Setting {
|
||||
|
||||
private boolean defaultValue;
|
||||
private boolean enabled;
|
||||
|
||||
@@ -2,14 +2,13 @@ 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 {
|
||||
public class ColorSetting extends Setting {
|
||||
|
||||
private Color color;
|
||||
private Consumer<Color> updateListener;
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
package me.retucio.camtweaks.module.settings;
|
||||
|
||||
import me.retucio.camtweaks.CameraTweaks;
|
||||
import me.retucio.camtweaks.event.events.camtweaks.UpdateSettingEvent;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
// ajuste que te deja elegir entre distintas opciones definidas, dentro de un Enum
|
||||
public class EnumSetting<E extends Enum<E>> extends AbstractSetting {
|
||||
public class EnumSetting<E extends Enum<E>> extends Setting {
|
||||
|
||||
private final List<E> values;
|
||||
private E defaultValue;
|
||||
|
||||
@@ -9,7 +9,7 @@ import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class KeySetting extends AbstractSetting {
|
||||
public class KeySetting extends Setting {
|
||||
|
||||
private int key;
|
||||
private int defaultKey;
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
package me.retucio.camtweaks.module.settings;
|
||||
|
||||
import me.retucio.camtweaks.CameraTweaks;
|
||||
import me.retucio.camtweaks.event.events.camtweaks.UpdateSettingEvent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class ListSetting<T> extends AbstractSetting {
|
||||
public class ListSetting<T> extends Setting {
|
||||
|
||||
private final List<T> options;
|
||||
private List<T> options;
|
||||
private Map<T, Boolean> values;
|
||||
private Map<T, Boolean> defaultValues;
|
||||
private Map<T, String> displayNames = null;
|
||||
@@ -19,7 +17,7 @@ public class ListSetting<T> extends AbstractSetting {
|
||||
|
||||
public ListSetting(String name, String description, List<T> options, Map<T, Boolean> initialValues) {
|
||||
super(name, description);
|
||||
this.options = options;
|
||||
this.options = new ArrayList<>(options);
|
||||
this.defaultValues = new HashMap<>();
|
||||
|
||||
for (T option : options) {
|
||||
@@ -66,6 +64,25 @@ public class ListSetting<T> extends AbstractSetting {
|
||||
defaultValues = values;
|
||||
}
|
||||
|
||||
public Map<String, Boolean> getConfigValues() {
|
||||
Map<String, Boolean> configValues = new HashMap<>();
|
||||
for (int i = 0; i < values.size(); i++)
|
||||
configValues.put(getDisplayName(options.get(i)), values.get(options.get(i)));
|
||||
return configValues;
|
||||
}
|
||||
|
||||
public void addOption(T option, boolean value, String displayName) {
|
||||
if (!(this.options instanceof ArrayList))
|
||||
this.options = new ArrayList<>(this.options);
|
||||
|
||||
this.options.add(option);
|
||||
this.values.put(option, value);
|
||||
this.defaultValues.put(option, value);
|
||||
|
||||
if (this.displayNames != null)
|
||||
this.displayNames.put(option, displayName);
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
values.clear();
|
||||
values.putAll(defaultValues);
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
package me.retucio.camtweaks.module.settings;
|
||||
|
||||
import me.retucio.camtweaks.CameraTweaks;
|
||||
import me.retucio.camtweaks.event.events.camtweaks.UpdateSettingEvent;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
// ajuste numérico, es decir, que eliges un valor númerico entre el mínimo y el máximo disponibles
|
||||
public class NumberSetting extends AbstractSetting {
|
||||
public class NumberSetting extends Setting {
|
||||
|
||||
private double value;
|
||||
private double defaultValue;
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
package me.retucio.camtweaks.module.settings;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class OptionSetting<T> extends Setting{
|
||||
|
||||
List<T> options = new ArrayList<>();
|
||||
Map<T, String> displayNames;
|
||||
T option;
|
||||
T defaultOption;
|
||||
|
||||
private Consumer<T> updateListener;
|
||||
|
||||
public OptionSetting(String name, String description, List<T> options, T defaultOption) {
|
||||
super(name, description);
|
||||
this.options = options;
|
||||
this.option = defaultOption;
|
||||
this.defaultOption = defaultOption;
|
||||
}
|
||||
|
||||
public OptionSetting(String name, String description, List<T> options, T defaultOption, Map<T, String> displayNames) {
|
||||
super(name, description);
|
||||
this.options = options;
|
||||
this.option = defaultOption;
|
||||
this.defaultOption = defaultOption;
|
||||
this.displayNames = displayNames;
|
||||
}
|
||||
|
||||
public T getValue() {
|
||||
return option;
|
||||
}
|
||||
|
||||
public void setValue(T option) {
|
||||
if (options.contains(option)) this.option = option;
|
||||
fireUpdateEvent();
|
||||
if (updateListener != null) updateListener.accept(option);
|
||||
}
|
||||
|
||||
public List<T> getOptions() {
|
||||
return options;
|
||||
}
|
||||
|
||||
public T getOption(int index) {
|
||||
return options.get(index);
|
||||
}
|
||||
|
||||
public T getDefaultValue() {
|
||||
return defaultOption;
|
||||
}
|
||||
|
||||
public int getSize() {
|
||||
return options.size();
|
||||
}
|
||||
|
||||
public int getIndex() {
|
||||
int index = 0;
|
||||
for (T option : options) {
|
||||
if (this.option == option) break;
|
||||
index += 1;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
public boolean is(T option) {
|
||||
return getValue() == option;
|
||||
}
|
||||
|
||||
public int getIndex(T option1) {
|
||||
int index = 0;
|
||||
for (T option : options) {
|
||||
if (option1 == option) break;
|
||||
index += 1;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
setValue(defaultOption);
|
||||
}
|
||||
|
||||
public void onUpdate(Consumer<T> listener) {
|
||||
this.updateListener = listener;
|
||||
if (updateListener != null) updateListener.accept(option);
|
||||
}
|
||||
|
||||
public Map<T, String> getDisplayNames() {
|
||||
return displayNames;
|
||||
}
|
||||
|
||||
public String getDisplayName(T key) {
|
||||
if (displayNames != null) return displayNames.get(key);
|
||||
return key.toString();
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -5,7 +5,7 @@ import me.retucio.camtweaks.event.events.camtweaks.UpdateSettingEvent;
|
||||
import me.retucio.camtweaks.module.Module;
|
||||
|
||||
// base para los tipos de ajustes
|
||||
public abstract class AbstractSetting {
|
||||
public abstract class Setting {
|
||||
|
||||
private final String name;
|
||||
private final String description;
|
||||
@@ -15,7 +15,7 @@ public abstract class AbstractSetting {
|
||||
|
||||
private Module module;
|
||||
|
||||
protected AbstractSetting(String name, String description) {
|
||||
protected Setting(String name, String description) {
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
}
|
||||
@@ -1,11 +1,8 @@
|
||||
package me.retucio.camtweaks.module.settings;
|
||||
|
||||
import me.retucio.camtweaks.CameraTweaks;
|
||||
import me.retucio.camtweaks.event.events.camtweaks.UpdateSettingEvent;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class StringSetting extends AbstractSetting {
|
||||
public class StringSetting extends Setting {
|
||||
|
||||
private String value;
|
||||
private String defaultValue;
|
||||
|
||||
@@ -1,241 +0,0 @@
|
||||
package me.retucio.camtweaks.ui;
|
||||
|
||||
import me.retucio.camtweaks.config.ConfigManager;
|
||||
import me.retucio.camtweaks.event.SubscribeEvent;
|
||||
import me.retucio.camtweaks.event.events.PacketEvent;
|
||||
import me.retucio.camtweaks.event.events.camtweaks.UpdateSettingEvent;
|
||||
import me.retucio.camtweaks.module.ModuleManager;
|
||||
import me.retucio.camtweaks.module.modules.Freecam;
|
||||
import me.retucio.camtweaks.module.modules.HUD;
|
||||
import me.retucio.camtweaks.ui.screen.HudEditorScreen;
|
||||
import me.retucio.camtweaks.ui.widgets.HudElement;
|
||||
|
||||
import me.retucio.camtweaks.util.Colors;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.client.gui.screen.ChatScreen;
|
||||
import net.minecraft.client.gui.screen.TitleScreen;
|
||||
import net.minecraft.client.network.PlayerListEntry;
|
||||
import net.minecraft.client.render.RenderTickCounter;
|
||||
import net.minecraft.network.packet.s2c.play.WorldTimeUpdateS2CPacket;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
import java.awt.*;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
public class HudRenderer {
|
||||
|
||||
private static final MinecraftClient mc = MinecraftClient.getInstance();
|
||||
|
||||
// tps
|
||||
private static float estimatedTPS = 20f;
|
||||
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, Boolean> visibilities = ConfigManager.getConfig().hudVisibilities;
|
||||
private static final List<HudElement> elements = new ArrayList<>();
|
||||
private static boolean initialized = false;
|
||||
|
||||
private static HudElement customTextElement = null;
|
||||
|
||||
public static void initElements() {
|
||||
if (initialized) return;
|
||||
initialized = true;
|
||||
|
||||
HUD hud = ModuleManager.INSTANCE.getModuleByClass(HUD.class);
|
||||
|
||||
// coordenadas
|
||||
addElement("coords", 2, mc.getWindow().getScaledHeight() - mc.textRenderer.fontHeight, (ctx, mx, my, delta) -> {
|
||||
drawSnappedText(ctx, getElementText("coords", delta, hud), mx, my, getColor(hud).getRGB(), hud.shadow.isEnabled());
|
||||
});
|
||||
|
||||
// FPS
|
||||
addElement("fps", 2, 2, (ctx, mx, my, delta) -> {
|
||||
drawSnappedText(ctx, getElementText("fps", 0, hud), mx, my, getColor(hud).getRGB(), hud.shadow.isEnabled());
|
||||
});
|
||||
|
||||
// TPS
|
||||
addElement("tps", 2, mc.textRenderer.fontHeight + 4, (ctx, mx, my, delta) -> {
|
||||
drawSnappedText(ctx, getElementText("tps", delta, hud), mx, my, getColor(hud).getRGB(), hud.shadow.isEnabled());
|
||||
});
|
||||
|
||||
// texto custom
|
||||
addElement("customText", mc.getWindow().getScaledWidth() / 2 - mc.textRenderer.getWidth(getElementText("customText", 0, ModuleManager.INSTANCE.getModuleByClass(HUD.class))) / 2, 2, (ctx, mx, my, delta) -> {
|
||||
drawSnappedText(ctx, getElementText("customText", delta, hud), mx, my, getColor(hud).getRGB(), hud.shadow.isEnabled());
|
||||
});
|
||||
|
||||
customTextElement = elements.stream()
|
||||
.filter(e -> e.getId().equals("customText"))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
|
||||
// hora
|
||||
addElement("time", mc.getWindow().getScaledWidth() - mc.textRenderer.getWidth("04:20"), mc.getWindow().getScaledHeight() - mc.textRenderer.fontHeight - 2, (ctx, mx, my, delta) -> {
|
||||
drawSnappedText(ctx, getElementText("time", delta, hud), mx, my, getColor(hud).getRGB(), hud.shadow.isEnabled());
|
||||
});
|
||||
|
||||
// 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());
|
||||
}
|
||||
|
||||
private static void addElement(String id, int defX, int defY, HudElement.Renderer renderer) {
|
||||
int[] saved = positions.get(id);
|
||||
Boolean visible = visibilities.get(id);
|
||||
int x = saved == null ? defX : saved[0];
|
||||
int y = saved == null ? defY : saved[1];
|
||||
boolean v = visible == null || visible;
|
||||
if (visibilities.isEmpty()) v = true;
|
||||
|
||||
elements.add(new HudElement(id, defX, defY, x, y, v) {
|
||||
@Override public void render(DrawContext ctx, int mx, int my, float delta) {
|
||||
renderer.render(ctx, x, y, delta);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static Color getColor(HUD hud) {
|
||||
return hud.color.getColor();
|
||||
}
|
||||
|
||||
public static void drawSnappedText(DrawContext ctx, String text, int x, int y, int color, boolean shadow) {
|
||||
int textWidth = mc.textRenderer.getWidth(text);
|
||||
int screenWidth = mc.getWindow().getScaledWidth();
|
||||
int screenHeight = mc.getWindow().getScaledHeight();
|
||||
|
||||
boolean snapRight = x > screenWidth / 2;
|
||||
int drawX = snapRight ? x + (textWidth + 2) - textWidth : x;
|
||||
|
||||
// clampear y
|
||||
y = Math.max(0, Math.min(y, screenHeight - mc.textRenderer.fontHeight));
|
||||
|
||||
// clampear x
|
||||
drawX = Math.max(0, Math.min(drawX, screenWidth - textWidth));
|
||||
|
||||
ctx.drawText(mc.textRenderer, text, drawX, y, color, shadow);
|
||||
}
|
||||
|
||||
public static void render(DrawContext ctx, RenderTickCounter tc) {
|
||||
if (ModuleManager.INSTANCE == null
|
||||
|| mc.player == null
|
||||
|| mc.getCameraEntity() == null
|
||||
|| mc.currentScreen instanceof TitleScreen
|
||||
|| mc.options.hudHidden)
|
||||
return;
|
||||
|
||||
HUD hud = ModuleManager.INSTANCE.getModuleByClass(HUD.class);
|
||||
if (!hud.isEnabled()) return;
|
||||
if (mc.debugHudEntryList.isF3Enabled() && !hud.showOnF3.isEnabled()) return;
|
||||
if (mc.currentScreen instanceof ChatScreen && !hud.showOnChat.isEnabled()) return;
|
||||
|
||||
initElements();
|
||||
|
||||
if (mc.currentScreen instanceof HudEditorScreen) return;
|
||||
|
||||
float deltaTime = tc.getDynamicDeltaTicks();
|
||||
for (HudElement element : elements)
|
||||
if (element.isVisible()) element.render(ctx, 0, 0, deltaTime);
|
||||
}
|
||||
|
||||
public static List<HudElement> getElements() {
|
||||
return elements;
|
||||
}
|
||||
|
||||
// texto a dibujar por elemento
|
||||
public static String getElementText(String id, float delta, HUD hud) {
|
||||
switch (id) {
|
||||
case "coords" -> {
|
||||
Freecam freecam = ModuleManager.INSTANCE.getModuleByClass(Freecam.class);
|
||||
Vec3d pos = freecam.isEnabled()
|
||||
? new Vec3d(freecam.getX(delta), freecam.getY(delta), freecam.getZ(delta))
|
||||
: mc.player.getEntityPos();
|
||||
|
||||
return (int) pos.x + " " + (int) pos.y + " " + (int) pos.z;
|
||||
}
|
||||
case "fps" -> {
|
||||
return "FPS: " + mc.getCurrentFps();
|
||||
}
|
||||
case "tps" -> {
|
||||
return String.format("TPS: %.1f", estimatedTPS);
|
||||
}
|
||||
case "customText" -> {
|
||||
return ModuleManager.INSTANCE.getModuleByClass(HUD.class).customText.getValue();
|
||||
}
|
||||
case "time" -> {
|
||||
ZoneOffset offset = ZoneOffset.ofHours(hud.timezone.getIntValue());
|
||||
LocalTime now = LocalTime.now(offset);
|
||||
|
||||
boolean is24 = hud.timeFormat.is(HUD.TimeFormat.TWENTY_FOUR_HOUR);
|
||||
DateTimeFormatter format = DateTimeFormatter.ofPattern(is24 ? "HH:mm" : "hh:mm a");
|
||||
return now.format(format);
|
||||
}
|
||||
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; }
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onReceivePacket(PacketEvent.Receive event) {
|
||||
if (event.getPacket() instanceof WorldTimeUpdateS2CPacket packet) {
|
||||
long currentWorldTime = packet.time();
|
||||
long currentRealTime = System.currentTimeMillis();
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/** para cuando se cambie el valor del texto custom */
|
||||
@SubscribeEvent
|
||||
public void onUpdateSetting(UpdateSettingEvent event) {
|
||||
if (ModuleManager.INSTANCE == null) return;
|
||||
HUD hud = ModuleManager.INSTANCE.getModuleByClass(HUD.class);
|
||||
if (event.getSetting() == hud.customText) {
|
||||
if (customTextElement != null) {
|
||||
int newX = mc.getWindow().getScaledWidth() / 2 - mc.textRenderer.getWidth(hud.customText.getValue()) / 2;
|
||||
customTextElement.setX(newX);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
package me.retucio.camtweaks.ui.buttons;
|
||||
|
||||
import me.retucio.camtweaks.module.Module;
|
||||
import me.retucio.camtweaks.module.settings.BooleanSetting;
|
||||
import me.retucio.camtweaks.module.settings.OptionSetting;
|
||||
import me.retucio.camtweaks.ui.frames.SettingsFrame;
|
||||
import me.retucio.camtweaks.ui.screen.ClickGUI;
|
||||
import me.retucio.camtweaks.util.Colors;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static me.retucio.camtweaks.CameraTweaks.mc;
|
||||
|
||||
public class ChooseButton<T> extends SettingButton {
|
||||
|
||||
private final OptionSetting<T> setting;
|
||||
private final Module dummy;
|
||||
private final Map<T, BooleanSetting> optionButtons = new HashMap<>();
|
||||
private T lastSelectedValue;
|
||||
|
||||
public ChooseButton(OptionSetting<T> setting, SettingsFrame parent, int offset) {
|
||||
super(setting, parent, offset);
|
||||
this.setting = setting;
|
||||
this.lastSelectedValue = setting.getValue();
|
||||
|
||||
// crear un módulo "dummy" (falso)
|
||||
dummy = new Module(setting.getName(), setting.getDescription()) {
|
||||
@Override public void onEnable() {}
|
||||
@Override public void onDisable() {}
|
||||
};
|
||||
|
||||
// ocultar cosas innecesarias
|
||||
dummy.getBind().setVisible(false);
|
||||
dummy.getSettings().stream()
|
||||
.filter(s -> s.getName().equalsIgnoreCase("modo de tecla"))
|
||||
.findFirst()
|
||||
.ifPresent(s -> s.setVisible(false));
|
||||
dummy.getSettings().stream()
|
||||
.filter(s -> s.getName().equalsIgnoreCase("notificar"))
|
||||
.findFirst()
|
||||
.ifPresent(s -> s.setVisible(false));
|
||||
dummy.shouldSaveSettings(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(DrawContext ctx, double mouseX, double mouseY, float delta) {
|
||||
int bgColor = isHovered(mouseX, mouseY)
|
||||
? Colors.buttonColor.brighter().getRGB()
|
||||
: Colors.buttonColor.getRGB();
|
||||
|
||||
ctx.fill(x, y, x + w, y + h, bgColor);
|
||||
|
||||
String label = setting.getName() + ": " + setting.getDisplayName(setting.getValue());
|
||||
ctx.drawText(parent.mc.textRenderer, label, x + 5, y + 3, -1, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseClicked(double mouseX, double mouseY, int button) {
|
||||
if (isHovered(mouseX, mouseY) && ClickGUI.INSTANCE.trySelect(this)) {
|
||||
// click izquierdo / derecho: abrir marco
|
||||
if (button <= 1 && !mc.isShiftPressed()) {
|
||||
if (ClickGUI.INSTANCE.isSettingsFrameOpen(dummy)) {
|
||||
ClickGUI.INSTANCE.closeSettingsFrame(dummy);
|
||||
return;
|
||||
}
|
||||
|
||||
rebuildDummy();
|
||||
ClickGUI.INSTANCE.openListSettingsFrame(dummy, parent.x + 40, parent.y + 40);
|
||||
// shift + clic derecho: restablecer valores
|
||||
} else if (button == 1 && mc.isShiftPressed()) {
|
||||
setting.reset();
|
||||
refreshDummy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void rebuildDummy() {
|
||||
dummy.getSettings().clear();
|
||||
optionButtons.clear();
|
||||
|
||||
setting.getOptions().stream()
|
||||
.sorted(Comparator.comparing(setting::getDisplayName, String.CASE_INSENSITIVE_ORDER))
|
||||
.forEach(option -> {
|
||||
String displayName = setting.getDisplayName(option);
|
||||
BooleanSetting b = new BooleanSetting(
|
||||
displayName,
|
||||
"incluir " + displayName,
|
||||
setting.is(option)
|
||||
);
|
||||
|
||||
b.onUpdate(value -> {
|
||||
if (value) {
|
||||
// deseleccionar el resto de opciones
|
||||
for (Map.Entry<T, BooleanSetting> entry : optionButtons.entrySet()) {
|
||||
if (!entry.getKey().equals(option))
|
||||
entry.getValue().setEnabled(false);
|
||||
}
|
||||
setting.setValue(option);
|
||||
} else {
|
||||
if (setting.is(option))
|
||||
b.setEnabled(true);
|
||||
}
|
||||
});
|
||||
|
||||
dummy.addSetting(b);
|
||||
optionButtons.put(option, b);
|
||||
});
|
||||
}
|
||||
|
||||
public void refreshDummy() {
|
||||
T currentValue = setting.getValue();
|
||||
for (Map.Entry<T, BooleanSetting> entry : optionButtons.entrySet()) {
|
||||
boolean shouldBeEnabled = entry.getKey().equals(currentValue);
|
||||
if (entry.getValue().isEnabled() != shouldBeEnabled) {
|
||||
entry.getValue().setEnabled(shouldBeEnabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public OptionSetting<T> getSetting() {
|
||||
return setting;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(double mouseX, double mouseY, int button) {
|
||||
ClickGUI.INSTANCE.unselect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseDragged(double mouseX, double mouseY) {}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package me.retucio.camtweaks.ui.buttons;
|
||||
|
||||
import me.retucio.camtweaks.module.settings.AbstractSetting;
|
||||
import me.retucio.camtweaks.module.settings.Setting;
|
||||
import me.retucio.camtweaks.ui.screen.ClickGUI;
|
||||
import me.retucio.camtweaks.ui.frames.SettingsFrame;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
@@ -9,13 +9,13 @@ import net.minecraft.text.Text;
|
||||
// clase base para los botones de los ajustes
|
||||
public abstract class SettingButton {
|
||||
|
||||
protected final AbstractSetting setting;
|
||||
protected final Setting setting;
|
||||
protected final SettingsFrame parent;
|
||||
protected int offset;
|
||||
|
||||
protected int x, y, w, h;
|
||||
|
||||
public SettingButton(AbstractSetting setting, SettingsFrame parent, int offset) {
|
||||
public SettingButton(Setting setting, SettingsFrame parent, int offset) {
|
||||
this.setting = setting;
|
||||
this.parent = parent;
|
||||
this.offset = offset;
|
||||
@@ -42,7 +42,7 @@ public abstract class SettingButton {
|
||||
mouseY > y && mouseY < y + h;
|
||||
}
|
||||
|
||||
public AbstractSetting getSetting() {
|
||||
public Setting getSetting() {
|
||||
return setting;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
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.Setting;
|
||||
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;
|
||||
@@ -73,7 +72,7 @@ public class ColorPickerFrame extends SettingsFrame {
|
||||
|
||||
// añadir ajustes y tal
|
||||
dummyModule.addSettings(redSetting, greenSetting, blueSetting, rainbowSpeedSetting, saturationSetting, brightnessSetting, rainbowSetting);
|
||||
for (AbstractSetting setting : dummyModule.getSettings()) {
|
||||
for (Setting setting : dummyModule.getSettings()) {
|
||||
if (setting instanceof NumberSetting n) n.onUpdate(v -> updateColorFromSettings());
|
||||
if (setting instanceof BooleanSetting b) b.onUpdate(v -> updateColorFromSettings());
|
||||
rainbowSetting.onUpdate(v -> {
|
||||
@@ -120,7 +119,7 @@ public class ColorPickerFrame extends SettingsFrame {
|
||||
updateWidth();
|
||||
|
||||
// al parecer este era el problema :/
|
||||
for (AbstractSetting setting : dummyModule.getSettings())
|
||||
for (Setting setting : dummyModule.getSettings())
|
||||
if (setting instanceof NumberSetting ns) ns.setLocked(
|
||||
pickingAlpha || pickingHue || pickingSaturationBrightness);
|
||||
|
||||
@@ -473,7 +472,7 @@ public class ColorPickerFrame extends SettingsFrame {
|
||||
private void updateSettingsFromColor() {
|
||||
if (colorSetting == null) return;
|
||||
|
||||
for (AbstractSetting setting : dummyModule.getSettings()) {
|
||||
for (Setting setting : dummyModule.getSettings()) {
|
||||
switch (setting.getName()) {
|
||||
case "rojo" -> ((NumberSetting) setting).setValue(colorSetting.getR());
|
||||
case "verde" -> ((NumberSetting) setting).setValue(colorSetting.getG());
|
||||
|
||||
@@ -50,7 +50,7 @@ public class SettingsFrame {
|
||||
|
||||
// añadir el respectivo tipo de botón de cada ajuste a la lista de botones
|
||||
int offset = h;
|
||||
for (AbstractSetting setting : module.getSettings()) {
|
||||
for (Setting setting : module.getSettings()) {
|
||||
switch (setting) {
|
||||
case BooleanSetting b -> {
|
||||
addButton(new ToggleButton(b, this, offset));
|
||||
@@ -73,6 +73,9 @@ public class SettingsFrame {
|
||||
} case ColorSetting c -> {
|
||||
addButton(new ColorButton(c, this, offset));
|
||||
offset += 18;
|
||||
} case OptionSetting o -> {
|
||||
addButton(new ChooseButton<>(o, this, offset));
|
||||
offset += 18;
|
||||
}
|
||||
default -> {}
|
||||
}
|
||||
|
||||
+38
-85
@@ -1,19 +1,18 @@
|
||||
package me.retucio.camtweaks.ui.screen;
|
||||
package me.retucio.camtweaks.ui.hud;
|
||||
|
||||
import me.retucio.camtweaks.config.ConfigManager;
|
||||
import me.retucio.camtweaks.module.ModuleManager;
|
||||
import me.retucio.camtweaks.module.modules.HUD;
|
||||
import me.retucio.camtweaks.ui.frames.ClientSettingsFrame;
|
||||
import me.retucio.camtweaks.ui.widgets.HudElement;
|
||||
import me.retucio.camtweaks.util.Colors;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.Click;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.input.KeyInput;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -30,7 +29,7 @@ public class HudEditorScreen extends Screen {
|
||||
private int dragOffsetX, dragOffsetY;
|
||||
|
||||
public HudEditorScreen() {
|
||||
super(Text.literal("editor del hud"));
|
||||
super(Text.literal("editor del HUD"));
|
||||
}
|
||||
|
||||
public void setElements(List<HudElement> elements) {
|
||||
@@ -42,24 +41,26 @@ public class HudEditorScreen extends Screen {
|
||||
public void render(DrawContext ctx, int mouseX, int mouseY, float delta) {
|
||||
ctx.fill(0, 0, this.width, this.height, Colors.hudEditorScreenBackgroundColor.getRGB());
|
||||
|
||||
// texto con instrucciones
|
||||
ctx.drawCenteredTextWithShadow(mc.textRenderer, "EDITOR DEL HUD", this.width / 2, this.height / 2 - mc.textRenderer.fontHeight, -1);
|
||||
// instrucciones
|
||||
ctx.drawCenteredTextWithShadow(mc.textRenderer, "editor del HUD",
|
||||
this.width / 2, this.height / 2 - mc.textRenderer.fontHeight, -1);
|
||||
ctx.drawCenteredTextWithShadow(mc.textRenderer,
|
||||
Text.literal("arrastrar para mover · click derecho para alternar visibilidad · esc para guardar y salir · shift + click derecho para restablecer"),
|
||||
Text.literal("arrastrar para mover · clic derecho para visibilidad · ESC para guardar y salir · shift + clic derecho para restablecer"),
|
||||
this.width / 2, this.height / 2 + mc.textRenderer.fontHeight, Colors.instructionsTextColor.getRGB());
|
||||
|
||||
// dibujar elementos
|
||||
// elementos
|
||||
for (HudElement element : elements)
|
||||
element.renderPreview(ctx);
|
||||
element.renderInEditor(ctx, null);
|
||||
|
||||
// tooltips con información sobre el elemento sobre el que está el puntero del ratón
|
||||
// tooltips
|
||||
if (!dragging) {
|
||||
for (HudElement element : elements) {
|
||||
if (!element.isVisible()) continue;
|
||||
|
||||
if (element.contains(mouseX, mouseY)) {
|
||||
List<Text> tooltip = getTooltipFor(element);
|
||||
if (!tooltip.isEmpty()) ctx.drawTooltip(mc.textRenderer, tooltip, mouseX + 7, mouseY + 20);
|
||||
if (element.isHovered(mouseX, mouseY)) {
|
||||
List<Text> tooltip = element.getTooltip();
|
||||
if (!tooltip.isEmpty())
|
||||
ctx.drawTooltip(mc.textRenderer, tooltip, mouseX + 7, mouseY + 20);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -73,28 +74,27 @@ public class HudEditorScreen extends Screen {
|
||||
int mouseX = (int) click.x();
|
||||
int mouseY = (int) click.y();
|
||||
|
||||
// iterar de atrás a adelante para respetar el orden z
|
||||
for (int i = elements.size() - 1; i >= 0; i--) {
|
||||
HudElement element = elements.get(i);
|
||||
if (element.contains(mouseX, mouseY)) {
|
||||
if (element.isHovered(mouseX, mouseY)) {
|
||||
selected = element;
|
||||
|
||||
if (click.button() == 0) {
|
||||
dragging = true;
|
||||
|
||||
dragOffsetX = mouseX - element.getX();
|
||||
dragOffsetY = mouseY - element.getY();
|
||||
|
||||
// traer el elemento seleccionado al frente
|
||||
elements.remove(i);
|
||||
elements.add(element);
|
||||
return true;
|
||||
|
||||
} else if (click.button() == 1) {
|
||||
if (mc.isShiftPressed())
|
||||
if (mc.isShiftPressed()) {
|
||||
selected.resetPosition();
|
||||
else
|
||||
} else {
|
||||
selected.setVisible(!selected.isVisible());
|
||||
}
|
||||
saveElementToConfig(selected);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -114,7 +114,6 @@ public class HudEditorScreen extends Screen {
|
||||
int newX = mouseX - dragOffsetX;
|
||||
int newY = mouseY - dragOffsetY;
|
||||
|
||||
// clampear para evitar que los elementos se salgan de la pantalla
|
||||
newX = Math.max(1, Math.min(newX, width - selected.getWidth() - 1));
|
||||
newY = Math.max(1, Math.min(newY, height - selected.getHeight() - 1));
|
||||
|
||||
@@ -126,92 +125,46 @@ public class HudEditorScreen extends Screen {
|
||||
public boolean mouseReleased(Click click) {
|
||||
if (dragging && click.button() == 0) {
|
||||
dragging = false;
|
||||
savePositionsToConfig(); // guardar inmediatamente al config
|
||||
return true;
|
||||
} else if (click.button() == 1 && selected != null) {
|
||||
saveVisibilitiesToConfig();
|
||||
selected = null;
|
||||
if (selected != null)
|
||||
saveElementToConfig(selected);
|
||||
return true;
|
||||
}
|
||||
|
||||
selected = null;
|
||||
return super.mouseReleased(click);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyPressed(KeyInput input) {
|
||||
// esc para guardar y salir
|
||||
if (input.key() == GLFW.GLFW_KEY_ESCAPE) {
|
||||
saveAndClose();
|
||||
saveAllElementsToConfig();
|
||||
selected = null;
|
||||
mc.setScreen(null);
|
||||
return true;
|
||||
}
|
||||
return super.keyPressed(input);
|
||||
}
|
||||
|
||||
private void savePositionsToConfig() {
|
||||
for (HudElement element : elements)
|
||||
ConfigManager.setHudPosition(element.getId(), element.getX(), element.getY());
|
||||
|
||||
private void saveElementToConfig(HudElement element) {
|
||||
ConfigManager.setHudPosition(element.getId(), element.getX(), element.getY());
|
||||
ConfigManager.setHudVisibility(element.getId(), element.isVisible());
|
||||
ConfigManager.save();
|
||||
}
|
||||
|
||||
private void saveVisibilitiesToConfig() {
|
||||
for (HudElement element : elements)
|
||||
ConfigManager.setHudVisibility(element.getId(), element.isVisible());
|
||||
|
||||
ConfigManager.save();
|
||||
}
|
||||
|
||||
private void saveAndClose() {
|
||||
savePositionsToConfig();
|
||||
selected = null;
|
||||
mc.setScreen(null);
|
||||
private void saveAllElementsToConfig() {
|
||||
for (HudElement element : elements) {
|
||||
saveElementToConfig(element);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void applyBlur(DrawContext ctx) {
|
||||
if (ClientSettingsFrame.guiSettings.blur.isEnabled()) super.applyBlur(ctx);
|
||||
if (ClientSettingsFrame.guiSettings.blur.isEnabled()) {
|
||||
super.applyBlur(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isSelected(HudElement element) {
|
||||
return selected == element;
|
||||
}
|
||||
|
||||
// para los tooltips
|
||||
private List<Text> getTooltipFor(HudElement element) {
|
||||
List<Text> list = new ArrayList<>();
|
||||
|
||||
switch (element.getId()) {
|
||||
case "coords" -> {
|
||||
list.add(Text.literal("coordenadas"));
|
||||
list.add(Text.literal("te muestra tu posición en el mundo en coordenadas XYZ"));
|
||||
}
|
||||
case "fps" -> {
|
||||
list.add(Text.literal("FPS"));
|
||||
list.add(Text.literal("te muestra la tasa de fotogramas por segundo del juego"));
|
||||
}
|
||||
case "tps" -> {
|
||||
list.add(Text.literal("tps"));
|
||||
list.add(Text.literal("te muestra la tasa de ticks por segundo del servidor (0-20)"));
|
||||
}
|
||||
case "customText" -> {
|
||||
list.add(Text.literal("texto custom"));
|
||||
list.add(Text.literal("te permite renderizar texto al gusto"));
|
||||
}
|
||||
case "time" -> {
|
||||
list.add(Text.literal("hora"));
|
||||
list.add(Text.literal("te muestra la hora y los minutos de la zona horaria escogida"));
|
||||
}
|
||||
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 -> {
|
||||
list.add(Text.literal(element.getId()));
|
||||
list.add(Text.literal("."));
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package me.retucio.camtweaks.ui.hud;
|
||||
|
||||
import me.retucio.camtweaks.module.modules.HUD;
|
||||
import me.retucio.camtweaks.util.Colors;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class HudElement {
|
||||
|
||||
protected static final MinecraftClient mc = MinecraftClient.getInstance();
|
||||
|
||||
private final String id;
|
||||
protected boolean visible;
|
||||
protected int x, y;
|
||||
protected final int defaultX, defaultY;
|
||||
protected int width = 85, height = 14;
|
||||
|
||||
public HudElement(String id, int defaultX, int defaultY) {
|
||||
this.id = id;
|
||||
this.defaultX = defaultX;
|
||||
this.defaultY = defaultY;
|
||||
this.visible = true;
|
||||
}
|
||||
|
||||
public abstract String getText(float delta, HUD hud);
|
||||
public abstract String getPreviewText();
|
||||
|
||||
public void renderInGame(DrawContext ctx, float delta, HUD hud) {
|
||||
String text = getText(delta, hud);
|
||||
int color = hud != null ? HudRenderer.getColor(hud).getRGB() : -1;
|
||||
boolean shadow = hud != null && hud.shadow.isEnabled();
|
||||
HudRenderer.drawSnappedText(ctx, text, x, y, color, shadow);
|
||||
}
|
||||
|
||||
public void renderInEditor(DrawContext ctx, HUD hud) {
|
||||
String previewText = getPreviewText();
|
||||
width = mc.textRenderer.getWidth(previewText);
|
||||
height = mc.textRenderer.fontHeight;
|
||||
|
||||
drawEditorBackground(ctx);
|
||||
|
||||
int color = hud != null ? HudRenderer.getColor(hud).getRGB() : -1;
|
||||
boolean shadow = hud != null && hud.shadow.isEnabled();
|
||||
HudRenderer.drawSnappedText(ctx, previewText, x, y, color, shadow);
|
||||
}
|
||||
|
||||
public abstract List<Text> getTooltip();
|
||||
|
||||
private void drawEditorBackground(DrawContext ctx) {
|
||||
int bg = visible ? Colors.visibleHudElementColor.getRGB() : Colors.disabledHudElementColor.getRGB();
|
||||
int outline = HudEditorScreen.INSTANCE != null && HudEditorScreen.INSTANCE.isSelected(this)
|
||||
? Colors.selectedHudElementOutlineColor.getRGB()
|
||||
: Colors.unselectedHudElementOutlineColor.getRGB();
|
||||
|
||||
// fondo
|
||||
ctx.fill(x - 1, y - 1, x + width + 1, y + height + 1, bg);
|
||||
|
||||
// contorno
|
||||
ctx.fill(x - 1, y - 1, x + width + 1, y, outline);
|
||||
ctx.fill(x - 1, y + height, x + width + 1, y + height + 1, outline);
|
||||
ctx.fill(x - 1, y, x, y + height, outline);
|
||||
ctx.fill(x + width, y, x + width + 1, y + height, outline);
|
||||
}
|
||||
|
||||
public boolean isHovered(int mouseX, int mouseY) {
|
||||
return mouseX >= x && mouseX <= x + width
|
||||
&& mouseY >= y && mouseY <= y + height;
|
||||
}
|
||||
|
||||
// Getters and setters
|
||||
public String getId() { return id; }
|
||||
public int getX() { return x; }
|
||||
public int getY() { return y; }
|
||||
public int getWidth() { return width; }
|
||||
public int getHeight() { return height; }
|
||||
public boolean isVisible() { return visible; }
|
||||
public void setVisible(boolean visible) { this.visible = visible; }
|
||||
|
||||
public void resetPosition() {
|
||||
this.x = defaultX;
|
||||
this.y = defaultY;
|
||||
}
|
||||
|
||||
public void setPosition(int x, int y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
package me.retucio.camtweaks.ui.hud;
|
||||
|
||||
import me.retucio.camtweaks.config.ConfigManager;
|
||||
import me.retucio.camtweaks.module.ModuleManager;
|
||||
import me.retucio.camtweaks.module.modules.HUD;
|
||||
import me.retucio.camtweaks.ui.hud.elements.*;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.client.gui.screen.ChatScreen;
|
||||
import net.minecraft.client.gui.screen.TitleScreen;
|
||||
import net.minecraft.client.render.RenderTickCounter;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class HudRenderer {
|
||||
|
||||
private static final MinecraftClient mc = MinecraftClient.getInstance();
|
||||
|
||||
private static final List<HudElement> elements = new ArrayList<>();
|
||||
private static boolean initialized = false;
|
||||
|
||||
public static void init() {
|
||||
if (initialized) return;
|
||||
initialized = true;
|
||||
|
||||
Map<String, int[]> positions = ConfigManager.getConfig().hudPositions;
|
||||
Map<String, Boolean> visibilities = ConfigManager.getConfig().hudVisibilities;
|
||||
|
||||
addElement(new CoordsElement(), positions, visibilities);
|
||||
addElement(new FpsElement(), positions, visibilities);
|
||||
addElement(new TpsElement(), positions, visibilities);
|
||||
addElement(new CustomTextElement(), positions, visibilities);
|
||||
addElement(new TimeElement(), positions, visibilities);
|
||||
addElement(new PingElement(), positions, visibilities);
|
||||
|
||||
HudEditorScreen.INSTANCE.setElements(elements);
|
||||
}
|
||||
|
||||
private static void addElement(HudElement element, Map<String, int[]> positions, Map<String, Boolean> visibilities) {
|
||||
int[] savedPos;
|
||||
|
||||
if (positions.get(element.getId()) == null)
|
||||
savedPos = new int[] {element.defaultX, element.defaultY};
|
||||
else
|
||||
savedPos = positions.get(element.getId());
|
||||
|
||||
Boolean savedVisibility = visibilities.get(element.getId());
|
||||
|
||||
if (savedPos != null)
|
||||
element.setPosition(savedPos[0], savedPos[1]);
|
||||
|
||||
if (savedVisibility != null)
|
||||
element.setVisible(savedVisibility);
|
||||
|
||||
elements.add(element);
|
||||
}
|
||||
|
||||
public static Color getColor(HUD hud) {
|
||||
return hud.color.getColor();
|
||||
}
|
||||
|
||||
public static void drawSnappedText(DrawContext ctx, String text, int x, int y, int color, boolean shadow) {
|
||||
int textWidth = mc.textRenderer.getWidth(text);
|
||||
int screenWidth = mc.getWindow().getScaledWidth();
|
||||
int screenHeight = mc.getWindow().getScaledHeight();
|
||||
|
||||
boolean snapRight = x > screenWidth / 2;
|
||||
int drawX = snapRight ? x + (textWidth + 2) - textWidth : x;
|
||||
|
||||
drawX = Math.max(0, Math.min(drawX, screenWidth - textWidth));
|
||||
y = Math.max(0, Math.min(y, screenHeight - mc.textRenderer.fontHeight));
|
||||
|
||||
ctx.drawText(mc.textRenderer, text, drawX, y, color, shadow);
|
||||
}
|
||||
|
||||
public static void render(DrawContext ctx, RenderTickCounter tickCounter) {
|
||||
if (shouldSkipRendering()) return;
|
||||
|
||||
HUD hud = ModuleManager.INSTANCE.getModuleByClass(HUD.class);
|
||||
if (!hud.isEnabled()) return;
|
||||
if (mc.debugHudEntryList.isF3Enabled() && !hud.showOnF3.isEnabled()) return;
|
||||
if (mc.currentScreen instanceof ChatScreen && !hud.showOnChat.isEnabled()) return;
|
||||
|
||||
init();
|
||||
|
||||
if (mc.currentScreen instanceof HudEditorScreen) return;
|
||||
|
||||
float delta = tickCounter.getDynamicDeltaTicks();
|
||||
for (HudElement element : elements) {
|
||||
if (element.isVisible()) {
|
||||
element.renderInGame(ctx, delta, hud);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean shouldSkipRendering() {
|
||||
return ModuleManager.INSTANCE == null
|
||||
|| mc.player == null
|
||||
|| mc.getCameraEntity() == null
|
||||
|| mc.currentScreen instanceof TitleScreen
|
||||
|| mc.options.hudHidden;
|
||||
}
|
||||
|
||||
public static List<HudElement> getElements() {
|
||||
return elements;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package me.retucio.camtweaks.ui.hud;
|
||||
|
||||
import me.retucio.camtweaks.event.events.PacketEvent;
|
||||
import me.retucio.camtweaks.module.ModuleManager;
|
||||
import me.retucio.camtweaks.module.modules.Freecam;
|
||||
import me.retucio.camtweaks.module.modules.HUD;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class CoordsElement extends HudElement {
|
||||
|
||||
public CoordsElement() {
|
||||
super("coords", 2, mc.getWindow().getScaledHeight() - mc.textRenderer.fontHeight);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText(float delta, HUD hud) {
|
||||
Freecam freecam = ModuleManager.INSTANCE.getModuleByClass(Freecam.class);
|
||||
Vec3d pos = freecam != null && freecam.isEnabled()
|
||||
? new Vec3d(freecam.getX(delta), freecam.getY(delta), freecam.getZ(delta))
|
||||
: mc.player.getEntityPos();
|
||||
|
||||
String overworldCoords = (int) pos.x + " " + (int) pos.y + " " + (int) pos.z;
|
||||
String netherCoords = (int) pos.x / 8 + " " + (int) pos.y / 8 + " " + (int) pos.z / 8;
|
||||
|
||||
if (hud.coordsMode.is(HUD.CoordsMode.OVERWORLD)) {
|
||||
return overworldCoords;
|
||||
} else if (hud.coordsMode.is(HUD.CoordsMode.NETHER)) {
|
||||
return netherCoords;
|
||||
} else {
|
||||
return overworldCoords + " (" + netherCoords + ")";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreviewText() {
|
||||
return getText(
|
||||
mc.getRenderTickCounter().getDynamicDeltaTicks(),
|
||||
ModuleManager.INSTANCE.getModuleByClass(HUD.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Text> getTooltip() {
|
||||
return List.of(
|
||||
Text.literal(getId()),
|
||||
Text.literal("te muestra tu posición XYZ en el mundo")
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package me.retucio.camtweaks.ui.hud.elements;
|
||||
|
||||
import me.retucio.camtweaks.event.SubscribeEvent;
|
||||
import me.retucio.camtweaks.event.events.camtweaks.UpdateSettingEvent;
|
||||
import me.retucio.camtweaks.module.ModuleManager;
|
||||
import me.retucio.camtweaks.module.modules.HUD;
|
||||
import me.retucio.camtweaks.ui.hud.HudElement;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class CustomTextElement extends HudElement {
|
||||
|
||||
public CustomTextElement() {
|
||||
super("customText", mc.getWindow().getScaledWidth() / 2 - 40, 2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText(float delta, HUD hud) {
|
||||
return hud != null && hud.customText != null ? hud.customText.getValue() : "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreviewText() {
|
||||
HUD hud = ModuleManager.INSTANCE.getModuleByClass(HUD.class);
|
||||
if (hud != null && hud.customText != null && !hud.customText.getValue().isEmpty())
|
||||
return hud.customText.getValue();
|
||||
|
||||
return "texto custom";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Text> getTooltip() {
|
||||
return List.of(
|
||||
Text.literal("texto custom"),
|
||||
Text.literal("texto que tú eliges")
|
||||
);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onUpdateSetting(UpdateSettingEvent event) {
|
||||
if (ModuleManager.INSTANCE == null) return;
|
||||
HUD hud = ModuleManager.INSTANCE.getModuleByClass(HUD.class);
|
||||
if (hud != null && event.getSetting() == hud.customText) {
|
||||
int newX = mc.getWindow().getScaledWidth() / 2 - mc.textRenderer.getWidth(hud.customText.getValue()) / 2;
|
||||
setPosition(newX, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package me.retucio.camtweaks.ui.hud.elements;
|
||||
|
||||
import me.retucio.camtweaks.module.modules.HUD;
|
||||
import me.retucio.camtweaks.ui.hud.HudElement;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class FpsElement extends HudElement {
|
||||
|
||||
public FpsElement() {
|
||||
super("fps", 2, 2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText(float delta, HUD hud) {
|
||||
return "FPS: " + mc.getCurrentFps();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreviewText() {
|
||||
return "FPS: 67";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Text> getTooltip() {
|
||||
return List.of(
|
||||
Text.literal("FPS"),
|
||||
Text.literal("te muestra los fotogramas por segundo a los que corre el juego")
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package me.retucio.camtweaks.ui.hud.elements;
|
||||
|
||||
import me.retucio.camtweaks.module.modules.HUD;
|
||||
import me.retucio.camtweaks.ui.hud.HudElement;
|
||||
import net.minecraft.client.network.PlayerListEntry;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PingElement extends HudElement {
|
||||
|
||||
public PingElement() {
|
||||
super("ping", 2, 2 * (mc.textRenderer.fontHeight + 4));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText(float delta, HUD hud) {
|
||||
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";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreviewText() {
|
||||
return "67 ms";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Text> getTooltip() {
|
||||
return List.of(
|
||||
Text.literal("ping"),
|
||||
Text.literal("latencia entre cliente y servidor, en milisegundos")
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package me.retucio.camtweaks.ui.hud.elements;
|
||||
|
||||
import me.retucio.camtweaks.module.modules.HUD;
|
||||
import me.retucio.camtweaks.ui.hud.HudElement;
|
||||
import me.retucio.camtweaks.util.MiscUtil;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class TimeElement extends HudElement {
|
||||
|
||||
public TimeElement() {
|
||||
super("time", mc.getWindow().getScaledWidth() - 50, mc.getWindow().getScaledHeight() - mc.textRenderer.fontHeight - 2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText(float delta, HUD hud) {
|
||||
return MiscUtil.getCurrentFormattedTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreviewText() {
|
||||
return "04:20 PM";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Text> getTooltip() {
|
||||
return List.of(
|
||||
Text.literal("hora"),
|
||||
Text.literal("hora y minutos de la zona horaria seleccionada")
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package me.retucio.camtweaks.ui.hud.elements;
|
||||
|
||||
import me.retucio.camtweaks.module.modules.HUD;
|
||||
import me.retucio.camtweaks.ui.hud.HudElement;
|
||||
import me.retucio.camtweaks.util.NetworkUtil;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class TpsElement extends HudElement {
|
||||
|
||||
public TpsElement() {
|
||||
super("tps", 2, mc.textRenderer.fontHeight + 4);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText(float delta, HUD hud) {
|
||||
return "TPS: " + NetworkUtil.getTPS();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreviewText() {
|
||||
return "TPS: 20.0";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Text> getTooltip() {
|
||||
return List.of(
|
||||
Text.literal("TPS"),
|
||||
Text.literal("te muestra la tasa de ticks por segundo del servidor (TPS óptimo: 20)")
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -7,10 +7,8 @@ import me.retucio.camtweaks.event.events.MouseClickEvent;
|
||||
import me.retucio.camtweaks.event.events.MouseScrollEvent;
|
||||
import me.retucio.camtweaks.event.events.camtweaks.SettingsFrameEvent;
|
||||
import me.retucio.camtweaks.module.Module;
|
||||
import me.retucio.camtweaks.module.ModuleManager;
|
||||
import me.retucio.camtweaks.module.settings.AbstractSetting;
|
||||
import me.retucio.camtweaks.module.settings.Setting;
|
||||
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.ModuleButton;
|
||||
import me.retucio.camtweaks.ui.buttons.SettingButton;
|
||||
@@ -20,7 +18,6 @@ import me.retucio.camtweaks.ui.frames.ModuleFrame;
|
||||
import me.retucio.camtweaks.ui.frames.SettingsFrame;
|
||||
import me.retucio.camtweaks.ui.widgets.ScrollBarWidget;
|
||||
import me.retucio.camtweaks.ui.widgets.SearchBarWidget;
|
||||
import me.retucio.camtweaks.util.ChatUtil;
|
||||
import me.retucio.camtweaks.util.KeyUtil;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
@@ -207,7 +204,7 @@ public class ClickGUI extends Screen {
|
||||
|
||||
for (SettingsFrame sf : settingsFrames) {
|
||||
for (SettingButton sb : sf.getButtons()) {
|
||||
AbstractSetting setting = sb.getSetting();
|
||||
Setting setting = sb.getSetting();
|
||||
|
||||
if (searchInput.isEmpty()) {
|
||||
setting.setSearchMatch(true);
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
package me.retucio.camtweaks.ui.widgets;
|
||||
|
||||
import me.retucio.camtweaks.module.settings.Setting;
|
||||
import me.retucio.camtweaks.ui.frames.SettingsFrame;
|
||||
import me.retucio.camtweaks.ui.screen.ClickGUI;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
public abstract class Button {
|
||||
|
||||
protected Frame parent;
|
||||
protected int offset;
|
||||
|
||||
protected int x, y, w, h;
|
||||
|
||||
public Button(Frame parent, int offset) {
|
||||
this.parent = parent;
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
public abstract void render(DrawContext ctx, int mouseX, int mouseY, float delta);
|
||||
|
||||
public abstract void mouseClicked(int mouseX, int mouseY, int button);
|
||||
public abstract void mouseDragged(int mouseX, int mouseY);
|
||||
public void mouseReleased(int mouseX, int mouseY, int button) {
|
||||
ClickGUI.INSTANCE.unselect(this);
|
||||
}
|
||||
|
||||
public abstract void drawTooltip(DrawContext ctx, double mouseX, double mouseY);
|
||||
|
||||
protected boolean isHovered(int mouseX, int mouseY) {
|
||||
if (!ClickGUI.INSTANCE.canSelect(this)) return false;
|
||||
return mouseX > x && mouseX < x + w &&
|
||||
mouseY > y && mouseY < y + h;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package me.retucio.camtweaks.ui.widgets;
|
||||
|
||||
import me.retucio.camtweaks.ui.screen.ClickGUI;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class Frame {
|
||||
|
||||
private final MinecraftClient mc = MinecraftClient.getInstance();
|
||||
|
||||
public final String title;
|
||||
private final List<Button> buttons = new ArrayList<>();
|
||||
private List<Button> visibleButtons = new ArrayList<>();
|
||||
|
||||
private int x, y, w, h;
|
||||
private int renderY;
|
||||
private int dragX, dragY;
|
||||
private boolean dragging;
|
||||
public int totalHeight = 0;
|
||||
|
||||
public Frame(String title, int x, int y, int w, int h) {
|
||||
this.title = title;
|
||||
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.w = w;
|
||||
this.h = h;
|
||||
}
|
||||
|
||||
public abstract void render(DrawContext ctx, int mouseX, int mouseY, float delta);
|
||||
|
||||
public void drawTooltips(DrawContext ctx, int mouseX, int mouseY) {
|
||||
for (Button button : visibleButtons) button.drawTooltip(ctx, mouseX, mouseY);
|
||||
}
|
||||
|
||||
public abstract void mouseClicked(int mouseX, int mouseY, int button);
|
||||
public abstract void mouseDragged(int mouseX, int mouseY);
|
||||
public void mouseReleased(int mouseX, int mouseY, int button) {
|
||||
ClickGUI.INSTANCE.unselect(this);
|
||||
}
|
||||
|
||||
public abstract void updateWidth();
|
||||
|
||||
public List<Button> getButtons() {
|
||||
return buttons;
|
||||
}
|
||||
|
||||
public List<Button> getVisibleButtons() {
|
||||
return visibleButtons;
|
||||
}
|
||||
|
||||
public boolean isHovered(double mouseX, double mouseY) {
|
||||
return mouseX > x && mouseX < x + w && mouseY > renderY && mouseY < renderY + h;
|
||||
}
|
||||
|
||||
public void updateRenderY(int scrollOffset) {
|
||||
renderY = y - scrollOffset;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,145 +0,0 @@
|
||||
package me.retucio.camtweaks.ui.widgets;
|
||||
|
||||
import me.retucio.camtweaks.module.ModuleManager;
|
||||
import me.retucio.camtweaks.module.modules.HUD;
|
||||
import me.retucio.camtweaks.ui.screen.HudEditorScreen;
|
||||
import me.retucio.camtweaks.ui.HudRenderer;
|
||||
import me.retucio.camtweaks.util.Colors;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
|
||||
public class HudElement {
|
||||
|
||||
protected final MinecraftClient mc = MinecraftClient.getInstance();
|
||||
|
||||
private final String id;
|
||||
protected boolean visible;
|
||||
|
||||
protected int x, y;
|
||||
protected int defaultX, defaultY;
|
||||
protected int width = 85, height = 14; // tamaño por defecto
|
||||
|
||||
public HudElement(String id, int defX, int defY, int x, int y, boolean visible) {
|
||||
this.id = id;
|
||||
this.visible = visible;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.defaultX = defX;
|
||||
this.defaultY = defY;
|
||||
}
|
||||
|
||||
// fallback
|
||||
public void render(DrawContext ctx, int mouseX, int mouseY, float tickDelta) {
|
||||
ctx.drawText(mc.textRenderer, Text.literal(getId()), x, y, -1, false);
|
||||
}
|
||||
|
||||
/** renderizar previsualización del elemento para el editor */
|
||||
public void renderPreview(DrawContext ctx) {
|
||||
final HUD hud = ModuleManager.INSTANCE.getModuleByClass(HUD.class);
|
||||
final String previewText = buildPreviewText(hud);
|
||||
|
||||
width = mc.textRenderer.getWidth(previewText);
|
||||
height = mc.textRenderer.fontHeight;
|
||||
|
||||
drawBackground(ctx);
|
||||
|
||||
int color = -1;
|
||||
boolean shadow = false;
|
||||
if (hud != null) {
|
||||
color = HudRenderer.getColor(hud).getRGB();
|
||||
shadow = hud.shadow.isEnabled();
|
||||
}
|
||||
|
||||
HudRenderer.drawSnappedText(ctx, previewText, x, y, color, shadow);
|
||||
}
|
||||
|
||||
/** construir texto para la previsualización */
|
||||
private String buildPreviewText(HUD hud) {
|
||||
float delta = mc.getRenderTickCounter().getDynamicDeltaTicks();
|
||||
|
||||
if ("coords".equals(id)) {
|
||||
if (mc.player == null) return "X Y Z";
|
||||
return HudRenderer.getElementText(id, delta, hud);
|
||||
}
|
||||
|
||||
if ("fps".equals(id)) {
|
||||
return HudRenderer.getElementText(id, delta, hud);
|
||||
}
|
||||
|
||||
if ("tps".equals(id)) {
|
||||
return HudRenderer.getElementText(id, delta, hud);
|
||||
}
|
||||
|
||||
if ("customText".equals(id)) {
|
||||
if (hud != null && hud.customText != null && !hud.customText.getValue().isEmpty())
|
||||
return HudRenderer.getElementText(id, delta, hud);
|
||||
return "texto custom";
|
||||
}
|
||||
|
||||
if ("time".equals(id)) {
|
||||
if (hud != null && hud.timeFormat != null)
|
||||
return HudRenderer.getElementText(id, delta, hud);
|
||||
return "4:20 PM";
|
||||
}
|
||||
|
||||
if ("ping".equals(id)) {
|
||||
if (mc.getCurrentServerEntry() != null)
|
||||
return HudRenderer.getElementText(id, delta, hud);
|
||||
return "67 ms";
|
||||
}
|
||||
|
||||
return id; // fallback: id del elemento
|
||||
}
|
||||
|
||||
/** fondo y contorno */
|
||||
private void drawBackground(DrawContext ctx) {
|
||||
int bg = visible ? Colors.visibleHudElementColor.getRGB() : Colors.disabledHudElementColor.getRGB();
|
||||
int outline = HudEditorScreen.INSTANCE.isSelected(this) ? Colors.selectedHudElementOutlineColor.getRGB() : Colors.unselectedHudElementOutlineColor.getRGB();
|
||||
|
||||
// fondo
|
||||
ctx.fill(x - 1, y - 1, x + width + 1, y + height + 1, bg);
|
||||
|
||||
// contorno
|
||||
ctx.fill(x - 1, y - 1, x + width + 1, y, outline);
|
||||
ctx.fill(x - 1, y + height, x + width + 1, y + height + 1, outline);
|
||||
ctx.fill(x - 1, y, x, y + height, outline);
|
||||
ctx.fill(x + width, y, x + width + 1, y + height, outline);
|
||||
}
|
||||
|
||||
public boolean contains(int mouseX, int mouseY) {
|
||||
return mouseX >= x && mouseX <= x + width
|
||||
&& mouseY >= y && mouseY <= y + height;
|
||||
}
|
||||
|
||||
// getters y setters
|
||||
public String getId() { return id; }
|
||||
|
||||
public int getX() { return x; }
|
||||
public int getY() { return y; }
|
||||
|
||||
public void setX(int x) { this.x = x; }
|
||||
public void setY(int y) { this.y = y; }
|
||||
|
||||
public int getWidth() { return width; }
|
||||
public int getHeight() { return height; }
|
||||
|
||||
public boolean isVisible() { return visible; }
|
||||
public void setVisible(boolean visible) { this.visible = visible; }
|
||||
|
||||
public void setPosition(int newX, int newY) {
|
||||
this.x = newX;
|
||||
this.y = newY;
|
||||
}
|
||||
|
||||
public void resetPosition() {
|
||||
this.x = defaultX;
|
||||
this.y = defaultY;
|
||||
}
|
||||
|
||||
public interface Renderer {
|
||||
void render(DrawContext ctx, int x, int y, float delta);
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,7 @@ public class ChatUtil {
|
||||
}
|
||||
|
||||
public static void addMessage(Text text) {
|
||||
if (mc.inGameHud == null || !CameraTweaks.INSTANCE.settingsApplied) return;
|
||||
if (mc.inGameHud == null || !CameraTweaks.settingsApplied) return;
|
||||
mc.inGameHud.getChatHud().addMessage(text);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
package me.retucio.camtweaks.util;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.projectile.ProjectileUtil;
|
||||
import net.minecraft.util.hit.EntityHitResult;
|
||||
import net.minecraft.util.hit.HitResult;
|
||||
import net.minecraft.util.math.Box;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.RaycastContext;
|
||||
import org.joml.Vector3d;
|
||||
|
||||
import static me.retucio.camtweaks.CameraTweaks.mc;
|
||||
|
||||
public class EntityUtil {
|
||||
|
||||
public static Vector3d getEntityVector(Vector3d vector, Entity entity, double tickDelta) {
|
||||
vector.x = MathHelper.lerp(tickDelta, entity.lastRenderX, entity.getX());
|
||||
vector.y = MathHelper.lerp(tickDelta, entity.lastRenderY, entity.getY());
|
||||
vector.z = MathHelper.lerp(tickDelta, entity.lastRenderZ, entity.getZ());
|
||||
return vector;
|
||||
}
|
||||
|
||||
public static Entity getEntityPlayerIsLookingAt() {
|
||||
if (mc.player == null || mc.world == null) return null;
|
||||
|
||||
float reachDistance = (float) mc.player.getEntityInteractionRange();
|
||||
|
||||
Vec3d cameraPos = mc.player.getCameraPosVec(1.0F);
|
||||
Vec3d rotation = mc.player.getRotationVec(1.0F);
|
||||
Vec3d endPos = cameraPos.add(rotation.x * reachDistance, rotation.y * reachDistance, rotation.z * reachDistance);
|
||||
|
||||
EntityHitResult entityHitResult = ProjectileUtil.raycast(
|
||||
mc.player,
|
||||
cameraPos,
|
||||
endPos,
|
||||
new Box(cameraPos, endPos),
|
||||
entity -> !entity.isSpectator() && entity.canHit(),
|
||||
reachDistance * reachDistance
|
||||
);
|
||||
|
||||
return entityHitResult != null ? entityHitResult.getEntity() : null;
|
||||
}
|
||||
|
||||
public static boolean hasLineOfSight(Entity viewer, Entity target) {
|
||||
HitResult hitResult = viewer.getEntityWorld().raycast(new RaycastContext(
|
||||
viewer.getEyePos(),
|
||||
target.getEyePos(),
|
||||
RaycastContext.ShapeType.COLLIDER,
|
||||
RaycastContext.FluidHandling.NONE,
|
||||
viewer
|
||||
));
|
||||
|
||||
if (hitResult.getType() == HitResult.Type.MISS) return true;
|
||||
else if (hitResult.getType() == HitResult.Type.ENTITY) {
|
||||
return ((EntityHitResult) hitResult).getEntity() == target;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static double getYaw(Entity entity) {
|
||||
return getYaw(entity.getEntityPos());
|
||||
}
|
||||
|
||||
public static double getYaw(Vec3d pos) {
|
||||
return mc.player.getYaw() + MathHelper.wrapDegrees(
|
||||
(float) Math.toDegrees(Math.atan2(
|
||||
pos.getZ() - mc.player.getZ(),
|
||||
pos.getX() - mc.player.getX())
|
||||
) - 90f - mc.player.getYaw());
|
||||
}
|
||||
|
||||
public static double getPitch(Vec3d pos) {
|
||||
double diffX = pos.getX() - mc.player.getX();
|
||||
double diffY = pos.getY() - (mc.player.getY() + mc.player.getEyeHeight(mc.player.getPose()));
|
||||
double diffZ = pos.getZ() - mc.player.getZ();
|
||||
|
||||
double diffXZ = Math.sqrt(diffX * diffX + diffZ * diffZ);
|
||||
|
||||
return mc.player.getPitch() + MathHelper.wrapDegrees((float) -Math.toDegrees(Math.atan2(diffY, diffXZ)) - mc.player.getPitch());
|
||||
}
|
||||
|
||||
public static double getPitch(Entity entity, Target target) {
|
||||
double y;
|
||||
if (target == Target.HEAD) y = entity.getEyeY();
|
||||
else if (target == Target.BODY) y = entity.getY() + entity.getHeight() / 2;
|
||||
else y = entity.getY();
|
||||
|
||||
double diffX = entity.getX() - mc.player.getX();
|
||||
double diffY = y - (mc.player.getY() + mc.player.getEyeHeight(mc.player.getPose()));
|
||||
double diffZ = entity.getZ() - mc.player.getZ();
|
||||
|
||||
double diffXZ = Math.sqrt(diffX * diffX + diffZ * diffZ);
|
||||
|
||||
return mc.player.getPitch() + MathHelper.wrapDegrees((float) -Math.toDegrees(Math.atan2(diffY, diffXZ)) - mc.player.getPitch());
|
||||
}
|
||||
|
||||
public static enum Target {
|
||||
HEAD,
|
||||
BODY,
|
||||
FEET;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,264 @@
|
||||
package me.retucio.camtweaks.util;
|
||||
|
||||
import me.retucio.camtweaks.event.SubscribeEvent;
|
||||
import me.retucio.camtweaks.event.events.DisconnectEvent;
|
||||
import me.retucio.camtweaks.event.events.OpenScreenEvent;
|
||||
import me.retucio.camtweaks.mixin.accessor.KeyBindingAccessor;
|
||||
import net.minecraft.client.gui.screen.ingame.GenericContainerScreen;
|
||||
import net.minecraft.client.gui.screen.ingame.HandledScreen;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.inventory.Inventory;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.screen.GenericContainerScreenHandler;
|
||||
import net.minecraft.screen.PlayerScreenHandler;
|
||||
import net.minecraft.screen.ScreenHandler;
|
||||
import net.minecraft.screen.slot.Slot;
|
||||
import net.minecraft.screen.slot.SlotActionType;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static me.retucio.camtweaks.CameraTweaks.mc;
|
||||
|
||||
public class InventoryUtil {
|
||||
|
||||
public static final int HOTBAR_START = 0;
|
||||
public static final int HOTBAR_END = 8;
|
||||
public static final int MAIN_INVENTORY_START = 9;
|
||||
public static final int MAIN_INVENTORY_END = 35;
|
||||
public static final int ARMOR_START = 36;
|
||||
public static final int ARMOR_END = 39;
|
||||
public static final int OFFHAND_SLOT = 40;
|
||||
|
||||
private static Inventory echestInv;
|
||||
|
||||
public static ItemStack getStackOfItem(Item item) {
|
||||
if (mc.player == null) return null;
|
||||
for (ItemStack stack : mc.player.getInventory())
|
||||
if (stack.getItem() == item)
|
||||
return stack;
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void swapSlots(int containerSlot1, int containerSlot2, HandledScreen<?> screen) {
|
||||
if (mc.player == null || mc.interactionManager == null) return;
|
||||
|
||||
ScreenHandler handler = screen.getScreenHandler();
|
||||
int syncId = handler.syncId;
|
||||
|
||||
mc.interactionManager.clickSlot(syncId, containerSlot1, 0, SlotActionType.PICKUP, mc.player);
|
||||
mc.interactionManager.clickSlot(syncId, containerSlot2, 0, SlotActionType.PICKUP, mc.player);
|
||||
mc.interactionManager.clickSlot(syncId, containerSlot1, 0, SlotActionType.PICKUP, mc.player);
|
||||
}
|
||||
|
||||
public static void swapWithHotbar(int containerSlot, int hotbarSlot, HandledScreen<?> screen) {
|
||||
if (mc.player == null || mc.interactionManager == null) return;
|
||||
|
||||
ScreenHandler handler = screen.getScreenHandler();
|
||||
mc.interactionManager.clickSlot(handler.syncId, containerSlot, hotbarSlot, SlotActionType.SWAP, mc.player);
|
||||
}
|
||||
|
||||
public static void quickMove(int containerSlot, HandledScreen<?> screen) {
|
||||
if (mc.player == null || mc.interactionManager == null) return;
|
||||
|
||||
ScreenHandler handler = screen.getScreenHandler();
|
||||
mc.interactionManager.clickSlot(handler.syncId, containerSlot, 0, SlotActionType.QUICK_MOVE, mc.player);
|
||||
}
|
||||
|
||||
public static void dropItem(int containerSlot, boolean dropStack, HandledScreen<?> screen) {
|
||||
if (mc.player == null || mc.interactionManager == null) return;
|
||||
|
||||
ScreenHandler handler = screen.getScreenHandler();
|
||||
int button = dropStack ? 1 : 0;
|
||||
mc.interactionManager.clickSlot(handler.syncId, containerSlot, button, SlotActionType.THROW, mc.player);
|
||||
}
|
||||
|
||||
public static int getContainerSlotByPlayerIndex(ScreenHandler handler, int playerStorageIndex) {
|
||||
for (Slot slot : handler.slots)
|
||||
if (slot.inventory instanceof PlayerInventory && slot.getIndex() == playerStorageIndex)
|
||||
return slot.id;
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static int getPlayerIndexFromContainerSlot(ScreenHandler handler, int containerSlot) {
|
||||
if (containerSlot < 0 || containerSlot >= handler.slots.size()) return -1;
|
||||
Slot slot = handler.getSlot(containerSlot);
|
||||
if (slot.inventory instanceof PlayerInventory)
|
||||
return slot.getIndex();
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static boolean isPlayerInventorySlot(ScreenHandler handler, int containerSlot) {
|
||||
if (containerSlot < 0 || containerSlot >= handler.slots.size()) return false;
|
||||
Slot slot = handler.getSlot(containerSlot);
|
||||
return slot.inventory instanceof PlayerInventory;
|
||||
}
|
||||
|
||||
public static List<Integer> getPlayerContainerSlots(ScreenHandler handler) {
|
||||
List<Integer> playerSlots = new ArrayList<>();
|
||||
for (Slot slot : handler.slots)
|
||||
if (slot.inventory instanceof PlayerInventory)
|
||||
playerSlots.add(slot.id);
|
||||
return playerSlots;
|
||||
}
|
||||
|
||||
public static List<Integer> getSlotsInSameColumn(ScreenHandler handler, int playerStorageIndex) {
|
||||
List<Integer> slotsInColumn = new ArrayList<>();
|
||||
int column = playerStorageIndex % 9;
|
||||
|
||||
for (Slot slot : handler.slots) {
|
||||
if (slot.inventory instanceof PlayerInventory) {
|
||||
int index = slot.getIndex();
|
||||
if (index >= 0 && index <= 35) {
|
||||
if (index % 9 == column) {
|
||||
slotsInColumn.add(slot.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
slotsInColumn.sort((a, b) -> {
|
||||
int indexA = getPlayerIndexFromContainerSlot(handler, a);
|
||||
int indexB = getPlayerIndexFromContainerSlot(handler, b);
|
||||
return Integer.compare(indexA / 9, indexB / 9);
|
||||
});
|
||||
|
||||
return slotsInColumn;
|
||||
}
|
||||
|
||||
public static void moveToOffhand(int containerSlot, HandledScreen<?> screen) {
|
||||
if (mc.player == null || mc.interactionManager == null) return;
|
||||
|
||||
ScreenHandler handler = screen.getScreenHandler();
|
||||
int offhandContainerSlot = getContainerSlotByPlayerIndex(handler, OFFHAND_SLOT);
|
||||
if (offhandContainerSlot == -1) return;
|
||||
|
||||
swapSlots(containerSlot, offhandContainerSlot, screen);
|
||||
}
|
||||
|
||||
public static ItemStack getOffhandItem() {
|
||||
if (mc.player == null) return ItemStack.EMPTY;
|
||||
return mc.player.getOffHandStack();
|
||||
}
|
||||
|
||||
public static boolean hasEmptyHotbarSlot() {
|
||||
if (mc.player == null) return false;
|
||||
PlayerInventory inv = mc.player.getInventory();
|
||||
|
||||
for (int i = HOTBAR_START; i <= HOTBAR_END; i++)
|
||||
if (inv.getStack(i).isEmpty())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static int findEmptyHotbarSlot() {
|
||||
if (mc.player == null) return -1;
|
||||
PlayerInventory inv = mc.player.getInventory();
|
||||
|
||||
for (int i = HOTBAR_START; i <= HOTBAR_END; i++)
|
||||
if (inv.getStack(i).isEmpty())
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static List<Integer> findMatchingItems(HandledScreen<?> screen, ItemStack reference) {
|
||||
List<Integer> matchingSlots = new ArrayList<>();
|
||||
if (reference.isEmpty()) return matchingSlots;
|
||||
|
||||
ScreenHandler handler = screen.getScreenHandler();
|
||||
for (int i = 0; i < handler.slots.size(); i++) {
|
||||
ItemStack stack = handler.getSlot(i).getStack();
|
||||
if (!stack.isEmpty() && ItemStack.areItemsAndComponentsEqual(reference, stack)) {
|
||||
matchingSlots.add(i);
|
||||
}
|
||||
}
|
||||
|
||||
return matchingSlots;
|
||||
}
|
||||
|
||||
public static void quickMoveAll(HandledScreen<?> screen, ItemStack reference) {
|
||||
if (mc.player == null || mc.interactionManager == null) return;
|
||||
|
||||
List<Integer> matchingSlots = findMatchingItems(screen, reference);
|
||||
ScreenHandler handler = screen.getScreenHandler();
|
||||
|
||||
for (int slot : matchingSlots) {
|
||||
mc.interactionManager.clickSlot(handler.syncId, slot, 0, SlotActionType.QUICK_MOVE, mc.player);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isPlayerScreen(HandledScreen<?> screen) {
|
||||
return screen.getScreenHandler() instanceof PlayerScreenHandler;
|
||||
}
|
||||
|
||||
public static int getRowOffset(HandledScreen<?> screen) {
|
||||
return isPlayerScreen(screen) ? 0 : 9;
|
||||
}
|
||||
|
||||
public static int calculateTargetSlot(HandledScreen<?> screen, int currentContainerSlot,
|
||||
int hotbarColumn, int rowOffset) {
|
||||
ScreenHandler handler = screen.getScreenHandler();
|
||||
|
||||
if (!isPlayerScreen(screen)) {
|
||||
int targetRow = rowOffset / 9;
|
||||
|
||||
for (Slot slot : handler.slots) {
|
||||
if (slot.inventory instanceof PlayerInventory) {
|
||||
int playerIndex = slot.getIndex();
|
||||
|
||||
if (playerIndex >= 0 && playerIndex <= 35) {
|
||||
int playerColumn = playerIndex % 9;
|
||||
int playerRow = playerIndex / 9;
|
||||
|
||||
if (playerColumn == hotbarColumn && playerRow == targetRow) {
|
||||
return slot.id;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (currentContainerSlot >= 9 && currentContainerSlot <= 44) {
|
||||
int targetPlayerIndex = hotbarColumn + rowOffset;
|
||||
|
||||
if (targetPlayerIndex >= 0 && targetPlayerIndex <= 26) {
|
||||
return targetPlayerIndex + 9;
|
||||
} else if (targetPlayerIndex >= 27 && targetPlayerIndex <= 35) {
|
||||
return targetPlayerIndex - 27 + 36;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static int getSlotNumberFromKey(int key) {
|
||||
for (int i = 0; i < 9; i++)
|
||||
if (((KeyBindingAccessor) (mc.options.hotbarKeys[i])).getBoundKey().getCode() == key) return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onOpenScreen(OpenScreenEvent event) {
|
||||
if (mc.player == null
|
||||
|| event.getScreen() == null
|
||||
|| !(mc.player.currentScreenHandler instanceof GenericContainerScreenHandler handler))
|
||||
return;
|
||||
|
||||
if (event.getScreen() instanceof GenericContainerScreen screen
|
||||
&& screen.getTitle().equals(Text.translatable("container.enderchest")))
|
||||
echestInv = handler.getInventory();
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onDisconnect(DisconnectEvent event) {
|
||||
echestInv = null;
|
||||
}
|
||||
|
||||
public static Inventory getEchestInv() {
|
||||
return echestInv;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -21,6 +21,11 @@ public class KeyUtil {
|
||||
) != GLFW.GLFW_RELEASE;
|
||||
}
|
||||
|
||||
public static boolean isShiftDown() {
|
||||
return isKeyDown(GLFW.GLFW_KEY_LEFT_SHIFT)
|
||||
|| isKeyDown(GLFW.GLFW_KEY_RIGHT_SHIFT);
|
||||
}
|
||||
|
||||
public static String getKeyName(int key) {
|
||||
if (key == GLFW.GLFW_KEY_UNKNOWN) return "ninguna";
|
||||
|
||||
|
||||
@@ -1,13 +1,20 @@
|
||||
package me.retucio.camtweaks.util;
|
||||
|
||||
import com.ibm.icu.impl.locale.XCldrStub;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.client.particle.Particle;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.resource.language.I18n;
|
||||
import net.minecraft.client.sound.Sound;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.network.packet.PacketType;
|
||||
import net.minecraft.particle.ParticleType;
|
||||
import net.minecraft.particle.ParticleTypes;
|
||||
import net.minecraft.registry.Registries;
|
||||
import net.minecraft.resource.featuretoggle.FeatureFlag;
|
||||
import net.minecraft.resource.featuretoggle.FeatureFlags;
|
||||
import net.minecraft.screen.ScreenHandler;
|
||||
import net.minecraft.screen.ScreenHandlerType;
|
||||
import net.minecraft.sound.SoundEvent;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
import java.awt.*;
|
||||
@@ -30,22 +37,48 @@ public class Lists {
|
||||
public static Map<Item, String> itemNames;
|
||||
|
||||
public static final List<Block> blockList = Registries.BLOCK.stream().toList();
|
||||
public static Map<Block, String> blockNames;
|
||||
|
||||
public static final List<SoundEvent> soundList = Registries.SOUND_EVENT.stream().toList();
|
||||
public static Map<SoundEvent, String> soundNames;
|
||||
|
||||
public static final List<ScreenHandlerType<?>> screenList = Registries.SCREEN_HANDLER.stream().toList();
|
||||
public static Map<ScreenHandlerType<?>, String> screenNames;
|
||||
|
||||
public static final List<Color> colorList = new ArrayList<>();
|
||||
|
||||
// intentar traducir nombres y fallar miserablemente
|
||||
public static void init() {
|
||||
// no consigo traducir el texto. a tomar por culo, se queda en inglés, si no entiendes pues a estudiar
|
||||
entityNames = getMapOfLists(entityList,
|
||||
entityList.stream().map(entity -> I18n.translate(entity.getTranslationKey())).toList());
|
||||
entityList.stream().map(entity -> Text.translatable(entity.getTranslationKey()).getString()).toList());
|
||||
|
||||
// no hay traducciones para nombres de partículas, y paso de hacerlas yo
|
||||
particleNames = getMapOfLists(particleList,
|
||||
particleList.stream().map(particle -> Registries.PARTICLE_TYPE.getId(particle).toShortTranslationKey()).toList());
|
||||
particleList.stream().map(particle -> Text.translatable(
|
||||
Registries.PARTICLE_TYPE.getId(particle).toShortTranslationKey()).getString()
|
||||
).toList());
|
||||
|
||||
itemNames = getMapOfLists(itemList,
|
||||
itemList.stream().map(item -> I18n.translate(item.getTranslationKey())).toList());
|
||||
itemList.stream().map(item -> Text.translatable(
|
||||
item.getTranslationKey()).getString()
|
||||
).toList());
|
||||
|
||||
colorList.addAll(Arrays.asList(RED, ORANGE, YELLOW, LIME, GREEN, CYAN, CELESTE, BLUE, PURPLE, MAGENTA, PINK, LAVENDER, WHITE, SILVER, GRAY, BLACK, BROWN));
|
||||
blockNames = getMapOfLists(blockList,
|
||||
blockList.stream().map(block -> Text.translatable(
|
||||
block.getTranslationKey()).getString()
|
||||
).toList());
|
||||
|
||||
soundNames = getMapOfLists(soundList,
|
||||
soundList.stream().map(sound -> Text.translatable(
|
||||
sound.id().toShortTranslationKey()).getString()
|
||||
).toList());
|
||||
|
||||
screenNames = getMapOfLists(screenList,
|
||||
screenList.stream().map(screen -> Text.translatable(
|
||||
Registries.SCREEN_HANDLER.getId(screen).toShortTranslationKey()).getString()
|
||||
).toList());
|
||||
|
||||
colorList.addAll(Arrays.asList(
|
||||
RED, ORANGE, YELLOW, LIME, GREEN, CYAN, CELESTE, BLUE, PURPLE, MAGENTA, PINK, LAVENDER, WHITE, SILVER, GRAY, BLACK, BROWN));
|
||||
}
|
||||
|
||||
public static <T> Map<T, Boolean> allTrue(List<T> options) {
|
||||
|
||||
@@ -1,29 +1,23 @@
|
||||
package me.retucio.camtweaks.util;
|
||||
|
||||
import me.retucio.camtweaks.event.SubscribeEvent;
|
||||
import me.retucio.camtweaks.event.events.DisconnectEvent;
|
||||
import me.retucio.camtweaks.event.events.OpenScreenEvent;
|
||||
import me.retucio.camtweaks.event.events.TickEvent;
|
||||
import me.retucio.camtweaks.module.ModuleManager;
|
||||
import me.retucio.camtweaks.module.modules.HUD;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.gui.screen.ingame.GenericContainerScreen;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.projectile.ProjectileUtil;
|
||||
import net.minecraft.inventory.Inventory;
|
||||
import net.minecraft.screen.GenericContainerScreenHandler;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.annotation.UsesSystemOut;
|
||||
import net.minecraft.util.hit.EntityHitResult;
|
||||
import net.minecraft.util.math.Box;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import org.joml.Vector3d;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
import static me.retucio.camtweaks.CameraTweaks.mc;
|
||||
|
||||
public class MiscUtil {
|
||||
|
||||
public static Screen screen;
|
||||
private static Inventory echestInv;
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onTick(TickEvent.Post event) {
|
||||
@@ -33,58 +27,29 @@ public class MiscUtil {
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onOpenScreen(OpenScreenEvent event) {
|
||||
if (mc.player == null
|
||||
|| event.getScreen() == null
|
||||
|| !(mc.player.currentScreenHandler instanceof GenericContainerScreenHandler handler))
|
||||
return;
|
||||
|
||||
if (event.getScreen() instanceof GenericContainerScreen screen
|
||||
&& screen.getTitle().equals(Text.translatable("container.enderchest")))
|
||||
echestInv = handler.getInventory();
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onDisconnect(DisconnectEvent event) {
|
||||
echestInv = null;
|
||||
}
|
||||
|
||||
public static void copyVector(Vector3d destination, Vec3d source) {
|
||||
destination.x = source.x;
|
||||
destination.y = source.y;
|
||||
destination.z = source.z;
|
||||
}
|
||||
|
||||
public static Vector3d getEntityVector(Vector3d vector, Entity entity, double tickDelta) {
|
||||
vector.x = MathHelper.lerp(tickDelta, entity.lastRenderX, entity.getX());
|
||||
vector.y = MathHelper.lerp(tickDelta, entity.lastRenderY, entity.getY());
|
||||
vector.z = MathHelper.lerp(tickDelta, entity.lastRenderZ, entity.getZ());
|
||||
return vector;
|
||||
public static String getCurrentFormattedTime() {
|
||||
return getFormattedTime(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
public static Entity getEntityPlayerIsLookingAt() {
|
||||
if (mc.player == null || mc.world == null) return null;
|
||||
public static String getFormattedTime(long timeMillis) {
|
||||
try {
|
||||
HUD hud = ModuleManager.INSTANCE.getModuleByClass(HUD.class);
|
||||
Instant instant = Instant.ofEpochMilli(timeMillis);
|
||||
ZoneOffset offset = ZoneOffset.ofHours(hud.timezone.getIntValue());
|
||||
LocalTime time = LocalTime.from(instant.atOffset(offset));
|
||||
|
||||
float reachDistance = (float) mc.player.getEntityInteractionRange();
|
||||
|
||||
Vec3d cameraPos = mc.player.getCameraPosVec(1.0F);
|
||||
Vec3d rotation = mc.player.getRotationVec(1.0F);
|
||||
Vec3d endPos = cameraPos.add(rotation.x * reachDistance, rotation.y * reachDistance, rotation.z * reachDistance);
|
||||
|
||||
EntityHitResult entityHitResult = ProjectileUtil.raycast(
|
||||
mc.player,
|
||||
cameraPos,
|
||||
endPos,
|
||||
new Box(cameraPos, endPos),
|
||||
entity -> !entity.isSpectator() && entity.canHit(),
|
||||
reachDistance * reachDistance
|
||||
);
|
||||
|
||||
return entityHitResult != null ? entityHitResult.getEntity() : null;
|
||||
boolean is24 = hud.timeFormat.is(HUD.TimeFormat.TWENTY_FOUR_HOUR);
|
||||
DateTimeFormatter format = DateTimeFormatter.ofPattern(is24 ? "HH:mm" : "hh:mm a");
|
||||
return time.format(format);
|
||||
} catch (Exception e) {
|
||||
return "??:??";
|
||||
}
|
||||
}
|
||||
|
||||
public static Inventory getEchestInv() {
|
||||
return echestInv;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package me.retucio.camtweaks.util;
|
||||
|
||||
|
||||
import me.retucio.camtweaks.event.SubscribeEvent;
|
||||
import me.retucio.camtweaks.event.events.PacketEvent;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.network.ClientConnection;
|
||||
import net.minecraft.network.listener.PacketListener;
|
||||
import net.minecraft.network.packet.Packet;
|
||||
import net.minecraft.network.packet.s2c.play.WorldTimeUpdateS2CPacket;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class NetworkUtil {
|
||||
|
||||
private static final MinecraftClient mc = MinecraftClient.getInstance();
|
||||
|
||||
// tps
|
||||
private static final List<Float> tpsHistory = new ArrayList<>();
|
||||
private static float estimatedTPS = 20f;
|
||||
private static long lastWorldTime = -1L;
|
||||
private static long lastRealTime = -1L;
|
||||
|
||||
public static float getTPS() {
|
||||
return estimatedTPS;
|
||||
}
|
||||
|
||||
public static void updateTPS(float tps) {
|
||||
tpsHistory.add(tps);
|
||||
if (tpsHistory.size() > 10)
|
||||
tpsHistory.removeFirst();
|
||||
|
||||
|
||||
float sum = 0;
|
||||
for (float t : tpsHistory) sum += t;
|
||||
estimatedTPS = sum / tpsHistory.size();
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onReceivePacket(PacketEvent.Receive event) {
|
||||
if (event.getPacket() instanceof WorldTimeUpdateS2CPacket packet) {
|
||||
long currentWorldTime = packet.time();
|
||||
long currentRealTime = System.currentTimeMillis();
|
||||
|
||||
if (lastWorldTime != -1L && lastRealTime != -1L) {
|
||||
long elapsedRealTime = currentRealTime - lastRealTime;
|
||||
long elapsedWorldTicks = currentWorldTime - lastWorldTime;
|
||||
|
||||
if (elapsedRealTime > 0) {
|
||||
float tps = (float) elapsedWorldTicks / (elapsedRealTime / 1000.0f);
|
||||
tps = Math.max(0.1f, Math.min(20.0f, tps));
|
||||
updateTPS(tps);
|
||||
}
|
||||
}
|
||||
|
||||
lastWorldTime = currentWorldTime;
|
||||
lastRealTime = currentRealTime;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void sendPacketNoEvent(Packet<?> packet) {
|
||||
mc.getNetworkHandler().getConnection().sendImmediately(packet, null, true);
|
||||
}
|
||||
|
||||
public static void receivePacketNoEvent(Packet<?> packet) {
|
||||
receivePacketNoEvent(packet, mc.getNetworkHandler().getConnection().getPacketListener());
|
||||
}
|
||||
|
||||
public static void receivePacketNoEvent(Packet<?> packet, PacketListener listener) {
|
||||
ClientConnection.handlePacket(packet, listener);
|
||||
}
|
||||
}
|
||||
@@ -2,14 +2,15 @@ package me.retucio.camtweaks.util.render;
|
||||
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
import me.retucio.camtweaks.util.ChatUtil;
|
||||
import net.minecraft.SharedConstants;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.client.render.*;
|
||||
import net.minecraft.client.render.state.OutlineRenderState;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Box;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.util.math.*;
|
||||
import net.minecraft.util.shape.VoxelShape;
|
||||
import net.minecraft.util.shape.VoxelShapes;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
@@ -19,16 +20,77 @@ public class RenderUtil {
|
||||
private static final MinecraftClient mc = MinecraftClient.getInstance();
|
||||
private static final Tessellator tesselator = Tessellator.getInstance();
|
||||
|
||||
public static void drawBlockOutline(MatrixStack matrices, BlockPos pos, Color color, double lineWidth) {
|
||||
Box box = new Box(pos.getX(), pos.getY(), pos.getZ(),
|
||||
pos.getX() + 1, pos.getY() + 1, pos.getZ() + 1);
|
||||
drawOutlineBox(matrices, box, color, lineWidth);
|
||||
|
||||
// líneas
|
||||
|
||||
public static void drawHorizontalLine(MatrixStack matrices, float x1, float x2, float y, Color color) {
|
||||
if (x2 < x1) {
|
||||
float i = x1;
|
||||
x1 = x2;
|
||||
x2 = i;
|
||||
}
|
||||
|
||||
drawFilledRect(matrices, x1, y, x2 + 1, y + 1, color);
|
||||
}
|
||||
|
||||
public static void drawBlockFilled(MatrixStack matrices, BlockPos pos, Color color) {
|
||||
Box box = new Box(pos.getX(), pos.getY(), pos.getZ(),
|
||||
pos.getX() + 1, pos.getY() + 1, pos.getZ() + 1);
|
||||
drawFilledBox(matrices, box, color);
|
||||
public static void drawVerticalLine(MatrixStack matrices, float x, float y1, float y2, Color color) {
|
||||
if (y2 < y1) {
|
||||
float i = y1;
|
||||
y1 = y2;
|
||||
y2 = i;
|
||||
}
|
||||
|
||||
drawFilledRect(matrices, x, y1 + 1, x + 1, y2, color);
|
||||
}
|
||||
|
||||
public static void drawHorizontalLine(MatrixStack matrices, float x1, float x2, float y, Color color, float width) {
|
||||
if (x2 < x1) {
|
||||
float i = x1;
|
||||
x1 = x2;
|
||||
x2 = i;
|
||||
}
|
||||
|
||||
drawFilledRect(matrices, x1, y, x2 + width, y + width, color);
|
||||
}
|
||||
|
||||
public static void drawVerticalLine(MatrixStack matrices, float x, float y1, float y2, Color color, float width) {
|
||||
if (y2 < y1) {
|
||||
float i = y1;
|
||||
y1 = y2;
|
||||
y2 = i;
|
||||
}
|
||||
|
||||
drawFilledRect(matrices, x, y1 + width, x + width, y2, color);
|
||||
}
|
||||
|
||||
|
||||
// caras
|
||||
|
||||
public static void drawFilledRect(MatrixStack matrices, float x, float y, float width, float height, Color color) {
|
||||
float r = color.getRed() / 255f;
|
||||
float g = color.getGreen() / 255f;
|
||||
float b = color.getBlue() / 255f;
|
||||
float a = color.getAlpha() / 255f;
|
||||
|
||||
matrices.push();
|
||||
matrices.translate(0, 0, 0);
|
||||
|
||||
BufferBuilder buffer = tesselator.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_COLOR);
|
||||
|
||||
buffer.vertex(matrices.peek().getPositionMatrix(), x, y + height, 0).color(r, g, b, a);
|
||||
buffer.vertex(matrices.peek().getPositionMatrix(), x + width, y + height, 0).color(r, g, b, a);
|
||||
buffer.vertex(matrices.peek().getPositionMatrix(), x + width, y, 0).color(r, g, b, a);
|
||||
buffer.vertex(matrices.peek().getPositionMatrix(), x, y, 0).color(r, g, b, a);
|
||||
|
||||
Layers.getGlobalQuads().draw(buffer.end());
|
||||
matrices.pop();
|
||||
}
|
||||
|
||||
public static void drawRectOutlines(MatrixStack stack, float x1, float y1, float x2, float y2, Color color, float width) {
|
||||
drawHorizontalLine(stack, x1, x2, y1, color, width);
|
||||
drawVerticalLine(stack, x2, y1, y2, color, width);
|
||||
drawHorizontalLine(stack, x1, x2, y2, color, width);
|
||||
drawVerticalLine(stack, x1, y1, y2, color, width);
|
||||
}
|
||||
|
||||
// expand es para evitar z-fighting
|
||||
@@ -107,71 +169,10 @@ public class RenderUtil {
|
||||
Layers.getGlobalQuads().draw(buffer.end());
|
||||
}
|
||||
|
||||
public static void drawLine(MatrixStack matrices, Vec3d start, Vec3d end, Color color, float width) {
|
||||
Vec3d cameraPos = mc.gameRenderer.getCamera().getPos();
|
||||
|
||||
float x1 = (float) (start.x - cameraPos.x);
|
||||
float y1 = (float) (start.y - cameraPos.y);
|
||||
float z1 = (float) (start.z - cameraPos.z);
|
||||
float x2 = (float) (end.x - cameraPos.x);
|
||||
float y2 = (float) (end.y - cameraPos.y);
|
||||
float z2 = (float) (end.z - cameraPos.z);
|
||||
// cajas
|
||||
|
||||
float r = color.getRed() / 255f;
|
||||
float g = color.getGreen() / 255f;
|
||||
float b = color.getBlue() / 255f;
|
||||
float a = color.getAlpha() / 255f;
|
||||
|
||||
BufferBuilder buffer = tesselator.begin(VertexFormat.DrawMode.LINE_STRIP, VertexFormats.POSITION_COLOR);
|
||||
|
||||
buffer.vertex(matrices.peek().getPositionMatrix(), x1, y1, z1).color(r, g, b, a);
|
||||
buffer.vertex(matrices.peek().getPositionMatrix(), x2, y2, z2).color(r, g, b, a);
|
||||
|
||||
Layers.getGlobalLines(width).draw(buffer.end());
|
||||
}
|
||||
|
||||
public static void drawOutlineRect(MatrixStack matrices, float x, float y, float w, float h, Color color, int linewidth) {
|
||||
float r = color.getRed() / 255f;
|
||||
float g = color.getGreen() / 255f;
|
||||
float b = color.getBlue() / 255f;
|
||||
float a = color.getAlpha() / 255f;
|
||||
|
||||
matrices.push();
|
||||
matrices.translate(0, 0, 0);
|
||||
|
||||
BufferBuilder buffer = tesselator.begin(VertexFormat.DrawMode.DEBUG_LINE_STRIP, VertexFormats.POSITION_COLOR);
|
||||
|
||||
buffer.vertex(matrices.peek().getPositionMatrix(), x, y, 0).color(r, g, b, a);
|
||||
buffer.vertex(matrices.peek().getPositionMatrix(), x + w, y, 0).color(r, g, b, a);
|
||||
buffer.vertex(matrices.peek().getPositionMatrix(), x + w, y + h, 0).color(r, g, b, a);
|
||||
buffer.vertex(matrices.peek().getPositionMatrix(), x, y + h, 0).color(r, g, b, a);
|
||||
buffer.vertex(matrices.peek().getPositionMatrix(), x, y, 0).color(r, g, b, a);
|
||||
|
||||
Layers.getGlobalLines(linewidth).draw(buffer.end());
|
||||
matrices.pop();
|
||||
}
|
||||
|
||||
public static void drawFilledRect(MatrixStack matrices, float x, float y, float width, float height, Color color) {
|
||||
float r = color.getRed() / 255f;
|
||||
float g = color.getGreen() / 255f;
|
||||
float b = color.getBlue() / 255f;
|
||||
float a = color.getAlpha() / 255f;
|
||||
|
||||
matrices.push();
|
||||
matrices.translate(0, 0, 0);
|
||||
|
||||
BufferBuilder buffer = tesselator.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_COLOR);
|
||||
|
||||
buffer.vertex(matrices.peek().getPositionMatrix(), x, y + height, 0).color(r, g, b, a);
|
||||
buffer.vertex(matrices.peek().getPositionMatrix(), x + width, y + height, 0).color(r, g, b, a);
|
||||
buffer.vertex(matrices.peek().getPositionMatrix(), x + width, y, 0).color(r, g, b, a);
|
||||
buffer.vertex(matrices.peek().getPositionMatrix(), x, y, 0).color(r, g, b, a);
|
||||
|
||||
Layers.getGlobalQuads().draw(buffer.end());
|
||||
matrices.pop();
|
||||
}
|
||||
|
||||
public static void drawOutlineBox(MatrixStack matrices, Box box, Color color, double lineWidth) {
|
||||
public static void drawOutlineBox(MatrixStack matrices, Box box, Color color, float lineWidth) {
|
||||
float r = color.getRed() / 255f;
|
||||
float g = color.getGreen() / 255f;
|
||||
float b = color.getBlue() / 255f;
|
||||
@@ -235,4 +236,48 @@ public class RenderUtil {
|
||||
|
||||
Layers.getGlobalQuads().draw(buffer.end());
|
||||
}
|
||||
|
||||
|
||||
// formas custom
|
||||
|
||||
public static void drawVoxelShapeOutline(MatrixStack matrices, VoxelShape voxelShape, BlockPos pos, Color color, float lineWidth) {
|
||||
if (voxelShape.isEmpty()) return;
|
||||
|
||||
voxelShape.forEachBox((minX, minY, minZ, maxX, maxY, maxZ) -> {
|
||||
Box box = new Box(
|
||||
pos.getX() + minX, pos.getY() + minY, pos.getZ() + minZ,
|
||||
pos.getX() + maxX, pos.getY() + maxY, pos.getZ() + maxZ
|
||||
);
|
||||
|
||||
drawOutlineBox(matrices, box, color, lineWidth);
|
||||
});
|
||||
}
|
||||
|
||||
public static void drawVoxelShapeFilled(MatrixStack matrices, VoxelShape voxelShape, BlockPos pos, Color color) {
|
||||
if (voxelShape.isEmpty()) return;
|
||||
|
||||
voxelShape.forEachBox((minX, minY, minZ, maxX, maxY, maxZ) -> {
|
||||
Box box = new Box(
|
||||
pos.getX() + minX, pos.getY() + minY, pos.getZ() + minZ,
|
||||
pos.getX() + maxX, pos.getY() + maxY, pos.getZ() + maxZ
|
||||
);
|
||||
|
||||
drawFilledBox(matrices, box, color);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// bloques
|
||||
|
||||
public static void drawBlockOutline(MatrixStack matrices, BlockPos pos, Color color, float lineWidth) {
|
||||
Box box = new Box(pos.getX(), pos.getY(), pos.getZ(),
|
||||
pos.getX() + 1, pos.getY() + 1, pos.getZ() + 1);
|
||||
drawOutlineBox(matrices, box, color, lineWidth);
|
||||
}
|
||||
|
||||
public static void drawBlockFilled(MatrixStack matrices, BlockPos pos, Color color) {
|
||||
Box box = new Box(pos.getX(), pos.getY(), pos.getZ(),
|
||||
pos.getX() + 1, pos.getY() + 1, pos.getZ() + 1);
|
||||
drawFilledBox(matrices, box, color);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,13 @@
|
||||
accessWidener v2 named
|
||||
|
||||
accessible method net/minecraft/network/ClientConnection handleQueuedTasks ()V
|
||||
accessible method net/minecraft/network/ClientConnection sendImmediately (Lnet/minecraft/network/packet/Packet;Lio/netty/channel/ChannelFutureListener;Z)V
|
||||
accessible field net/minecraft/network/ClientConnection queuedTasks Ljava/util/Queue;
|
||||
accessible method net/minecraft/network/ClientConnection handlePacket (Lnet/minecraft/network/packet/Packet;Lnet/minecraft/network/listener/PacketListener;)V
|
||||
|
||||
accessible class net/minecraft/client/network/ClientCommonNetworkHandler$ConfirmServerResourcePackScreen
|
||||
accessible class net/minecraft/client/network/ClientCommonNetworkHandler$ConfirmServerResourcePackScreen$Pack
|
||||
|
||||
accessible class net/minecraft/client/font/TextRenderer$Drawer
|
||||
|
||||
accessible field net/minecraft/client/particle/BillboardParticle alpha F
|
||||
@@ -9,9 +17,9 @@ accessible field net/minecraft/client/particle/Particle gravityStrength F
|
||||
accessible field net/minecraft/client/particle/Particle collidesWithWorld Z
|
||||
accessible field net/minecraft/entity/LivingEntity jumpingCooldown I
|
||||
|
||||
accessible field net/minecraft/client/render/WorldRenderer worldRenderState Lnet/minecraft/client/render/state/WorldRenderState;
|
||||
accessible method net/minecraft/client/render/WorldRenderer method_74752 (Lnet/minecraft/client/render/Camera;Lnet/minecraft/client/render/Frustum;Z)V
|
||||
accessible method net/minecraft/client/render/GameRenderer getProjectionMatrix (F)Lorg/joml/Matrix4f;
|
||||
accessible method net/minecraft/client/render/command/DebugHitboxCommandRenderer renderDebugHitbox (Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/entity/state/EntityHitboxAndView;Lnet/minecraft/client/render/VertexConsumer;F)V
|
||||
|
||||
accessible class net/minecraft/client/network/ClientCommonNetworkHandler$ConfirmServerResourcePackScreen
|
||||
accessible class net/minecraft/client/network/ClientCommonNetworkHandler$ConfirmServerResourcePackScreen$Pack
|
||||
accessible method net/minecraft/screen/ScreenHandlerType register (Ljava/lang/String;Lnet/minecraft/screen/ScreenHandlerType$Factory;)Lnet/minecraft/screen/ScreenHandlerType;
|
||||
Reference in new issue
Block a user