Compare commits

...
5 Commits
Author SHA1 Message Date
retuci0 6fa409d60a v1.7 2025-12-10 19:26:51 +01:00
retuci0 4f816381c3 upsi 2025-12-07 09:01:21 +01:00
retuci0 36c38bdf02 ups 2025-12-07 09:00:41 +01:00
retuci0 a6a6f1261e v1.5 2025-12-07 08:59:33 +01:00
retuci0 8891a57c7c v1.4 2025-10-12 13:00:18 +02:00
80 changed files with 1810 additions and 408 deletions

No files matched your search

+8 -1
View File
@@ -39,6 +39,13 @@ replay_*.log
*.hprof
*.jfr
# otros
todo.txt
test.java
cambios.md
cambios.md
# no está terminado
src/main/java/me/retucio/camtweaks/module/modules/TooltipsPlus.java
src/main/java/me/retucio/camtweaks/util/RenderUtil.java
src/main/java/me/retucio/camtweaks/util/Layers.java
remappedSrc/
+12 -5
View File
@@ -1,6 +1,6 @@
# jenny's mod 2 100% real
mod para Minecraft Fabric 1.21.6 que añade algunas cosas QOL, mayormente relacionadas a la cámara.
mod para Minecraft Fabric 1.21.10 que añade algunas cosas QOL, mayormente relacionadas a la cámara.
## instalación
@@ -10,8 +10,8 @@ mod para Minecraft Fabric 1.21.6 que añade algunas cosas QOL, mayormente relaci
3. descargar el .jar
4. moverlo a tu directorio de mods (probablemente `%appdata%/.minecraft/mods`)
asegúrate de tener una version de Minecraft y Fabric compatibles con el mod (MC 1.21.6; Fabric 0.128.2)
es posible que hayan problemas al usarlo junto a otros mods, especialmente otros clientes, pues pueden conflictar
asegúrate de tener una version de Minecraft y Fabric compatibles con el mod (MC `1.21.10`; Fabric `0.138.3`)
es posible que haya problemas al usarlo junto a otros mods, especialmente junto a otros clientes, pues pueden conflictar entre ellos.
### para frikis de 200 de iq
1. clona el respositorio (`git clone https://github.com/retuci0/camera-tweaks`)
@@ -23,9 +23,11 @@ es posible que hayan problemas al usarlo junto a otros mods, especialmente otros
`shift derecho` por defecto para abrir la interfaz
`pág. arriba` por defecto para abrir el editor del hud
`$` como prefijo por defecto para comandos (se autocompletan)
algunos módulos tienen teclas asignadas por defecto, asígnales `ESC` para desactivar sus teclas
algunos módulos tienen teclas asignadas por defecto, asígnales `ESC` para desactivar sus atajos de teclado
## interfaz
@@ -51,6 +53,7 @@ algunos módulos tienen teclas asignadas por defecto, asígnales `ESC` para desa
<img src="screenshots/crits.png" alt="críticos">
<img src="screenshots/fullbright.png" alt="fullbright en modo gamma cambiando el color de los shaders">
<img src="screenshots/hud.png" alt="HUD">
<img src="screenshots/hudeditor.png" alt="editor de HUD">
## contibuciones
@@ -58,4 +61,8 @@ sí por favor
## licencia
no sé, haz lo que quieras con esto, es puta basura xd
no sé, haz lo que quieras con esto, es puta basura xd
aunque estaría guay que acreditases
pero bueno
-1
View File
@@ -24,7 +24,6 @@ dependencies {
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
// Fabric API. This is technically optional, but you probably want it anyway.
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
}
+10 -16
View File
@@ -1,27 +1,21 @@
# v1.3
# v1.6
## novedades
todo un sistema de renderizado skiddeado de https://github.com/mioclient/oyvey-ported/
### adiciones
- barra de búsqueda: filtra los ajustes de todos los paneles de ajustes, por nombre y descripción
- barra de deslizamiento
- módulo de jugador falso: invoca una entidad de jugador falsa, por motivos de testeo
- HUD: mostrar información adicional en pantalla (ej.: hora, fps, coordenadas, ...)
- marca de agua en la pantalla de inicio porque molo un montón
- prev. de shulkers: te permite previsualizar el contenido de cajas de shulker desde el inventario
- puntos de desconexión: te muestra el punto donde un jugador se desconecta
### arreglos / mejoras
- mejoras a la interfaz
- ahora el color de los widgets depende del color principal
- ahora solo se puede seleccionar un objeto de la interfaz a la vez
- cambiada la posición de los títulos de los marcos
- ahora los módulos están ordenados por orden alfabético
- ahora nametags también tiene en cuenta la absorción de un jugador al mostrar su vida
- el color del prefijo de las notificaciones por chat ahora depende de los ajustes de color
- ya no se muestra el prefijo equivocado en notificaciones por chat al meterse a un mundo por primera vez
- el scroll del freecam ahora requiere una tecla (para mayor comodidad)
- ahora puedes ver tu propio nametag (nametags -> mostrar propio)
- opción para desactivar hud en chat agregada
- arreglos menores varios
## problemas reconocidos
+8 -5
View File
@@ -1,5 +1,8 @@
meteor client dev team
oyvey client (1.21 port by mioclient)
lennyboi (youtube)
packbar by cattyn on github
shotify mod
Meteor Client: https://github.com/MeteorDevelopment/meteor-client | https://meteorclient.com
OyVey Port: https://github.com/mioclient/oyvey-ported/
Lenny Boi: https://www.youtube.com/@lennyboi7195
Shotify: https://modrinth.com/mod/shotify
No Telemetry: https://modrinth.com/mod/no-telemetry
probablemente más pero como tengo demencia se me olvida
si quieres que te acredite mándame un mensaje en discord (username: retucio) y sin problemas :)
+5 -10
View File
@@ -1,18 +1,13 @@
# Done to increase the memory available to gradle.
org.gradle.jvmargs=-Xmx1G
org.gradle.parallel=true
# Fabric Properties
# check these on https://fabricmc.net/develop
minecraft_version=1.21.6
yarn_mappings=1.21.6+build.1
loader_version=0.17.2
minecraft_version=1.21.10
yarn_mappings=1.21.10+build.2
loader_version=0.17.3
loom_version=1.11-SNAPSHOT
# Mod Properties
mod_version=1.3
mod_version=1.6
maven_group=me.retucio
archives_base_name=camtweaks
# Dependencies
fabric_version=0.128.2+1.21.6
fabric_version=0.135.0+1.21.10
Binary file not shown.

After

Width:  |  Height:  |  Size: 243 KiB

@@ -16,7 +16,10 @@ import me.retucio.camtweaks.event.events.camtweaks.LoadModuleManagerEvent;
import me.retucio.camtweaks.module.Module;
import me.retucio.camtweaks.module.ModuleManager;
import me.retucio.camtweaks.ui.ClickGUI;
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.buttons.BindButton;
import me.retucio.camtweaks.ui.buttons.SettingButton;
import me.retucio.camtweaks.ui.buttons.TextButton;
@@ -31,10 +34,10 @@ import me.retucio.camtweaks.util.MiscUtil;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.TitleScreen;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -45,15 +48,28 @@ import org.lwjgl.glfw.GLFW;
public class CameraTweaks implements ClientModInitializer {
// cosas necesarias
public static final String MOD_ID = "camtweaks";
public static final CameraTweaks INSTANCE = new CameraTweaks();
public static final Logger LOGGER = LogManager.getLogger(CameraTweaks.class);
public static final EventBus EVENT_BUS = new EventBus();
public static final Logger LOGGER = LogManager.getLogger(CameraTweaks.class);
public static MinecraftClient mc;
// id y versión
public static final String MOD_ID = "camtweaks";
public static final String MOD_VERSION;
static {
MOD_VERSION = FabricLoader.getInstance().getModContainer(MOD_ID)
.orElseThrow()
.getMetadata()
.getVersion()
.getFriendlyString();
}
private Screen prevScreen;
public boolean settingsApplied = false;
@Override
public void onInitializeClient() {
// por algún motivo aunque lo añada a los args de la JVM sigue siendo true a menos que haga esto??? puta vida
@@ -64,6 +80,7 @@ public class CameraTweaks implements ClientModInitializer {
EVENT_BUS.register(this);
EVENT_BUS.register(MiscUtil.class);
EVENT_BUS.register(ChatUtil.class);
EVENT_BUS.register(HudRenderer.class);
Lists.init();
@@ -74,6 +91,7 @@ public class CameraTweaks implements ClientModInitializer {
EVENT_BUS.post(new LoadCommandManagerEvent());
ClickGUI.INSTANCE = new ClickGUI();
HudEditorScreen.INSTANCE = new HudEditorScreen();
EVENT_BUS.post(new LoadClickGUIEvent());
ConfigManager.load();
@@ -99,17 +117,21 @@ public class CameraTweaks implements ClientModInitializer {
// se ejecuta cada vez que se presiona una tecla
public void onKeyPress(int key, int action) {
if (key == GLFW.GLFW_KEY_F3) return; // prevenir activación de módulos al usar combinaciones de F3
ModuleManager.INSTANCE.getEnabledModules().forEach(module -> module.onKey(key, action));
boolean anyFocused = isAnySettingButtonFocused() || ClickGUI.INSTANCE.getSearchBar().isFocused();
ClickGUI.INSTANCE.setAnyFocused(anyFocused);
if (action == GLFW.GLFW_PRESS) {
if (action != GLFW.GLFW_RELEASE) {
if (BindCommand.onKeyPress(key)) return;
if (action == GLFW.GLFW_PRESS) {
handleModuleToggle(key, anyFocused);
handleClickGUIKey(key, anyFocused);
handleHudEditorKey(key, anyFocused);
}
handleSettingButtonsKey(key, action);
handleModuleToggle(key, anyFocused);
handleClickGUIKey(key, anyFocused);
} else if (action == GLFW.GLFW_RELEASE && !anyFocused) {
} else if (!anyFocused) {
handleModuleRelease(key);
}
}
@@ -150,10 +172,11 @@ public class CameraTweaks implements ClientModInitializer {
// maneja la lógica de apertura de la interfaz
private void handleClickGUIKey(int key, boolean anyFocused) {
if (key != ClientSettingsFrame.guiSettings.getKey() || anyFocused) return;
if (!(mc != null && mc.world != null && mc.player != null)) return;
// al parecer esto hace que con la tecla de la interfaz puedas ir cambiando de splash text en la pantalla del título
// pero me ha hecho gracia así que así se queda
if (mc.currentScreen != ClickGUI.INSTANCE && !(mc.currentScreen instanceof TitleScreen)) {
if (mc.currentScreen != ClickGUI.INSTANCE) {
prevScreen = mc.currentScreen;
mc.setScreen(ClickGUI.INSTANCE);
} else {
@@ -162,6 +185,20 @@ public class CameraTweaks implements ClientModInitializer {
}
}
// manejar la lógica de apertura del editor de elementos del hud, con la misma lógica que handleClickGUIKey()
private void handleHudEditorKey(int key, boolean anyFocused) {
if (key != ModuleManager.INSTANCE.getModuleByClass(HUD.class).editorKey.getKey() || anyFocused) return;
if (!(mc != null && mc.world != null && mc.player != null)) return;
if (mc.currentScreen != HudEditorScreen.INSTANCE) {
prevScreen = mc.currentScreen;
mc.setScreen(HudEditorScreen.INSTANCE);
} else {
HudEditorScreen.INSTANCE.close();
mc.setScreen(prevScreen);
}
}
// se ocupa de apagar los módulos que tengan configurado hacerlo tras soltar su tecla
private void handleModuleRelease(int key) {
if (mc.currentScreen != null && mc.currentScreen != ClickGUI.INSTANCE) return;
@@ -3,7 +3,7 @@ package me.retucio.camtweaks.config;
import me.retucio.camtweaks.event.SubscribeEvent;
import me.retucio.camtweaks.event.events.camtweaks.*;
import me.retucio.camtweaks.module.settings.*;
import me.retucio.camtweaks.ui.ClickGUI;
import me.retucio.camtweaks.ui.screen.ClickGUI;
import java.util.HashMap;
import java.util.Map;
@@ -26,11 +26,16 @@ public class ClientConfig {
// nombre del frame -> FrameData (que contiene extended, x & y)
public Map<String, FrameData> extendableFrames = new HashMap<>();
// id del elemento del hud -> posición (x, y)
public Map<String, int[]> hudPositions = new HashMap<>();
// id del elemento del hud -> true: visible / false: no visible
public Map<String, Boolean> hudVisibilities = new HashMap<>();
public ClientConfig() {
EVENT_BUS.register(this);
}
@SubscribeEvent
public void onToggleModule(ToggleModuleEvent event) {
ConfigManager.setModuleState(event.getModule());
@@ -6,7 +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.ClickGUI;
import me.retucio.camtweaks.ui.screen.ClickGUI;
import me.retucio.camtweaks.ui.frames.ClientSettingsFrame;
import me.retucio.camtweaks.ui.frames.SettingsFrame;
@@ -114,7 +114,7 @@ public class ConfigManager {
public static void setFramePosition(SettingsFrame frame) {
ensureConfig();
config.settingsFrames.put(frame.module.getName(), new int[]{frame.x, frame.y});
ConfigManager.save();
save();
}
public static void setExtendableFrame(String key, ClientConfig.FrameData data) {
@@ -123,6 +123,19 @@ public class ConfigManager {
save();
}
public static void setHudPosition(String id, int x, int y) {
ensureConfig();
config.hudPositions.put(id, new int[]{x, y});
save();
}
public static void setHudVisibility(String id, Boolean visible) {
ensureConfig();
config.hudVisibilities.put(id, visible);
save();
}
@SuppressWarnings({"rawtypes", "unchecked"})
public static void applySetting(Module parent, AbstractSetting setting) {
String id = parent.getName() + ":" + setting.getName();
@@ -0,0 +1,31 @@
package me.retucio.camtweaks.event.events;
import me.retucio.camtweaks.event.Event;
import net.minecraft.client.render.Camera;
import net.minecraft.client.render.RenderTickCounter;
import net.minecraft.client.util.math.MatrixStack;
public class RenderWorldEvent extends Event {
private final MatrixStack matrices;
private final RenderTickCounter tc;
private final Camera camera;
public RenderWorldEvent(MatrixStack matrices, RenderTickCounter tc, Camera camera) {
this.matrices = matrices;
this.tc = tc;
this.camera = camera;
}
public MatrixStack getMatrices() {
return matrices;
}
public RenderTickCounter getTickCounter() {
return tc;
}
public Camera getCamera() {
return camera;
}
}
@@ -0,0 +1,17 @@
package me.retucio.camtweaks.event.events.camtweaks;
import me.retucio.camtweaks.event.Event;
import net.minecraft.entity.Entity;
public class AddEntityEvent extends Event {
private final Entity entity;
public AddEntityEvent(Entity entity) {
this.entity = entity;
}
public Entity getEntity() {
return entity;
}
}
@@ -0,0 +1,17 @@
package me.retucio.camtweaks.event.events.camtweaks;
import me.retucio.camtweaks.event.Event;
import net.minecraft.entity.Entity;
public class RemoveEntityEvent extends Event {
private final Entity entity;
public RemoveEntityEvent(Entity entity) {
this.entity = entity;
}
public Entity getEntity() {
return entity;
}
}
@@ -0,0 +1,19 @@
package me.retucio.camtweaks.mixin;
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import me.retucio.camtweaks.module.ModuleManager;
import me.retucio.camtweaks.module.modules.PortalGUI;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.network.ClientPlayerEntity;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
@Mixin(ClientPlayerEntity.class)
public abstract class ClientPlayerEntityMixin {
@ModifyExpressionValue(method = "tickNausea", at = @At(value = "FIELD", target = "Lnet/minecraft/client/MinecraftClient;currentScreen:Lnet/minecraft/client/gui/screen/Screen;"))
private Screen allowScreensInPortals(Screen original) {
if (ModuleManager.INSTANCE.getModuleByClass(PortalGUI.class).isEnabled()) return null;
return original;
}
}
@@ -0,0 +1,32 @@
package me.retucio.camtweaks.mixin;
import me.retucio.camtweaks.event.events.camtweaks.AddEntityEvent;
import me.retucio.camtweaks.event.events.camtweaks.RemoveEntityEvent;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.entity.Entity;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import static me.retucio.camtweaks.CameraTweaks.EVENT_BUS;
@Mixin(ClientWorld.class)
public abstract class ClientWorldMixin {
@Shadow @Nullable
public abstract Entity getEntityById(int id);
@Inject(method = "addEntity", at = @At("HEAD"))
private void onEntityAdded(Entity entity, CallbackInfo ci) {
if (entity != null) EVENT_BUS.post(new AddEntityEvent(entity));
}
@Inject(method = "removeEntity", at = @At("HEAD"))
private void onRemoveEntity(int entityId, Entity.RemovalReason removalReason, CallbackInfo ci) {
Entity entity = getEntityById(entityId);
if (entity != null) EVENT_BUS.post(new RemoveEntityEvent(entity));
}
}
@@ -1,48 +0,0 @@
package me.retucio.camtweaks.mixin;
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import com.llamalad7.mixinextras.injector.ModifyReturnValue;
import me.retucio.camtweaks.CameraTweaks;
import me.retucio.camtweaks.module.ModuleManager;
import me.retucio.camtweaks.module.modules.Freecam;
import net.minecraft.client.render.Camera;
import net.minecraft.client.render.item.property.numeric.CompassState;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import static me.retucio.camtweaks.CameraTweaks.mc;
@Mixin(CompassState.class)
public abstract class CompassStateMixin {
@Unique
private static Freecam freecam;
@Inject(method = "<init>", at = @At("TAIL"))
private void getModules(boolean wobble, CompassState.Target target, CallbackInfo ci) {
freecam = ModuleManager.INSTANCE.getModuleByClass(Freecam.class);
}
@ModifyExpressionValue(method = "getBodyYaw", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;getBodyYaw()F"))
private static float getBodyYaw(float original) {
if (freecam.isEnabled()) return mc.gameRenderer.getCamera().getYaw();
return original;
}
@ModifyReturnValue(method = "getAngleTo(Lnet/minecraft/entity/Entity;Lnet/minecraft/util/math/BlockPos;)D", at = @At("RETURN"))
private static double getAngleTo(double original, Entity entity, BlockPos blockPos) {
if (freecam.isEnabled()) {
Vec3d vec3d = Vec3d.ofCenter(blockPos);
Camera camera = mc.gameRenderer.getCamera();
return Math.atan2(vec3d.getZ() - camera.getPos().z, vec3d.getX() - camera.getPos().x) / (float) (Math.PI * 2);
}
return original;
}
}
@@ -3,6 +3,7 @@ package me.retucio.camtweaks.mixin;
import com.llamalad7.mixinextras.injector.ModifyReturnValue;
import me.retucio.camtweaks.module.ModuleManager;
import me.retucio.camtweaks.module.modules.CritsPlus;
import net.minecraft.client.particle.BillboardParticle;
import net.minecraft.client.particle.DamageParticle;
import net.minecraft.client.particle.ParticleTextureSheet;
import org.spongepowered.asm.mixin.Mixin;
@@ -14,9 +15,9 @@ import java.awt.*;
@Mixin(DamageParticle.class)
public abstract class DamageParticleMixin {
@ModifyReturnValue(method = "getType", at = @At("RETURN"))
private ParticleTextureSheet makeCritsTranslucent(ParticleTextureSheet original) {
if (ModuleManager.INSTANCE.getModuleByClass(CritsPlus.class).isEnabled()) return ParticleTextureSheet.PARTICLE_SHEET_TRANSLUCENT;
@ModifyReturnValue(method = "getRenderType", at = @At("RETURN"))
private BillboardParticle.RenderType makeCritsTranslucent(BillboardParticle.RenderType original) {
if (ModuleManager.INSTANCE.getModuleByClass(CritsPlus.class).isEnabled()) return BillboardParticle.RenderType.PARTICLE_ATLAS_TRANSLUCENT;
return original;
}
}
@@ -25,7 +26,7 @@ public abstract class DamageParticleMixin {
@Mixin(DamageParticle.Factory.class)
abstract class DamageParticleFactoryMixin {
@ModifyVariable(method = "createParticle(Lnet/minecraft/particle/SimpleParticleType;Lnet/minecraft/client/world/ClientWorld;DDDDDD)Lnet/minecraft/client/particle/Particle;", at = @At(value = "STORE"))
@ModifyVariable(method = "createParticle(Lnet/minecraft/particle/SimpleParticleType;Lnet/minecraft/client/world/ClientWorld;DDDDDDLnet/minecraft/util/math/random/Random;)Lnet/minecraft/client/particle/Particle;", at = @At(value = "STORE"))
private DamageParticle modifyCritColor(DamageParticle original) {
CritsPlus crits = ModuleManager.INSTANCE.getModuleByClass(CritsPlus.class);
if (!crits.isEnabled()) return original;
@@ -1,19 +0,0 @@
package me.retucio.camtweaks.mixin;
import me.retucio.camtweaks.module.ModuleManager;
import me.retucio.camtweaks.module.modules.NoRender;
import net.minecraft.particle.EntityEffectParticleEffect;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(EntityEffectParticleEffect.class)
public abstract class EntityEffectParticleEffectMixin {
@Inject(method = "getAlpha", at = @At("HEAD"), cancellable = true)
private void noRenderPotionParticles(CallbackInfoReturnable<Float> cir) {
NoRender noRender = ModuleManager.INSTANCE.getModuleByClass(NoRender.class);
if (noRender.isEnabled()) cir.setReturnValue(256 - noRender.potionParticleAlpha.getFloatValue());
}
}
@@ -6,7 +6,6 @@ import me.retucio.camtweaks.module.modules.AntiInvis;
import me.retucio.camtweaks.module.modules.Freecam;
import me.retucio.camtweaks.module.modules.Freelook;
import me.retucio.camtweaks.module.modules.Nametags;
import me.retucio.camtweaks.util.ChatUtil;
import net.minecraft.entity.*;
import net.minecraft.entity.passive.TameableEntity;
import net.minecraft.entity.player.PlayerEntity;
@@ -14,7 +13,6 @@ import net.minecraft.entity.projectile.PersistentProjectileEntity;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
@@ -80,6 +78,7 @@ public abstract class EntityMixin {
private boolean renderEntityNametags(boolean original) {
if (!nametags.isEnabled()) return original;
if ((Object) this instanceof PersistentProjectileEntity p && p.isOnGround()) return false;
if ((Object) this instanceof ItemEntity i && !nametags.items.isEnabled(i.getStack().getItem())) return false;
return nametags.entities.isEnabled((this.getType()));
}
@@ -1,19 +1,23 @@
package me.retucio.camtweaks.mixin;
import com.llamalad7.mixinextras.injector.ModifyReturnValue;
import me.retucio.camtweaks.event.events.GetFOVEvent;
import me.retucio.camtweaks.module.ModuleManager;
import me.retucio.camtweaks.module.modules.Freecam;
import me.retucio.camtweaks.module.modules.NoRender;
import me.retucio.camtweaks.module.modules.Zoom;
import me.retucio.camtweaks.util.interfaces.IVec3d;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.BufferBuilderStorage;
import net.minecraft.client.render.GameRenderer;
import net.minecraft.client.render.block.BlockRenderManager;
import net.minecraft.client.render.item.HeldItemRenderer;
import net.minecraft.entity.Entity;
import org.joml.Matrix4f;
import org.joml.Vector3d;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@@ -22,9 +26,11 @@ import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyVariable;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.llamalad7.mixinextras.injector.ModifyReturnValue;
import static me.retucio.camtweaks.CameraTweaks.EVENT_BUS;
@Mixin(GameRenderer.class)
public abstract class GameRendererMixin {
@@ -47,7 +53,7 @@ public abstract class GameRendererMixin {
public abstract void updateCrosshairTarget(float tickDelta);
@Inject(method = "<init>", at = @At("TAIL"))
private void getModules(MinecraftClient client, HeldItemRenderer firstPersonHeldItemRenderer, BufferBuilderStorage buffers, CallbackInfo ci) {
private void getModules(MinecraftClient client, HeldItemRenderer firstPersonHeldItemRenderer, BufferBuilderStorage buffers, BlockRenderManager blockRenderManager, CallbackInfo ci) {
zoom = ModuleManager.INSTANCE.getModuleByClass(Zoom.class);;
freecam = ModuleManager.INSTANCE.getModuleByClass(Freecam.class);
noRender = ModuleManager.INSTANCE.getModuleByClass(NoRender.class);
@@ -78,7 +84,7 @@ public abstract class GameRendererMixin {
float lastYaw = cameraEntity.lastYaw;
float lastPitch = cameraEntity.lastPitch;
((IVec3d) cameraEntity.getPos()).smegma$set(pos.x, pos.y - cameraEntity.getEyeHeight(cameraEntity.getPose()), pos.z);
((IVec3d) cameraEntity.getEntityPos()).smegma$set(pos.x, pos.y - cameraEntity.getEyeHeight(cameraEntity.getPose()), pos.z);
cameraEntity.lastX = prevPos.x;
cameraEntity.lastY = prevPos.y - cameraEntity.getEyeHeight(cameraEntity.getPose());
cameraEntity.lastZ = prevPos.z;
@@ -91,7 +97,7 @@ public abstract class GameRendererMixin {
updateCrosshairTarget(tickDelta);
freecamDone = false;
((IVec3d) cameraEntity.getPos()).smegma$set(x, y, z);
((IVec3d) cameraEntity.getEntityPos()).smegma$set(x, y, z);
cameraEntity.lastX = lastX;
cameraEntity.lastY = lastY;
cameraEntity.lastZ = lastZ;
@@ -9,7 +9,8 @@ import net.minecraft.client.MinecraftClient;
import net.minecraft.client.item.ItemModelManager;
import net.minecraft.client.network.AbstractClientPlayerEntity;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.entity.EntityRenderDispatcher;
import net.minecraft.client.render.command.OrderedRenderCommandQueue;
import net.minecraft.client.render.entity.EntityRenderManager;
import net.minecraft.client.render.item.HeldItemRenderer;
import net.minecraft.client.render.item.ItemRenderer;
import net.minecraft.client.util.math.MatrixStack;
@@ -49,17 +50,17 @@ public abstract class HeldItemRendererMixin {
protected abstract boolean shouldSkipHandAnimationOnSwap(ItemStack from, ItemStack to);
@Inject(method = "<init>", at = @At("TAIL"))
private void getModules(MinecraftClient client, EntityRenderDispatcher entityRenderDispatcher, ItemRenderer itemRenderer, ItemModelManager itemModelManager, CallbackInfo ci) {
private void getModules(MinecraftClient client, EntityRenderManager entityRenderDispatcher, ItemRenderer itemRenderer, ItemModelManager itemModelManager, CallbackInfo ci) {
handView = ModuleManager.INSTANCE.getModuleByClass(HandView.class);
}
@Inject(method = "renderFirstPersonItem", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/item/HeldItemRenderer;renderItem(Lnet/minecraft/entity/LivingEntity;Lnet/minecraft/item/ItemStack;Lnet/minecraft/item/ItemDisplayContext;Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;I)V", shift = At.Shift.BEFORE))
private void onRenderItem(AbstractClientPlayerEntity player, float tickDelta, float pitch, Hand hand, float swingProgress, ItemStack item, float equipProgress, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, CallbackInfo ci) {
@Inject(method = "renderFirstPersonItem", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/item/HeldItemRenderer;renderItem(Lnet/minecraft/entity/LivingEntity;Lnet/minecraft/item/ItemStack;Lnet/minecraft/item/ItemDisplayContext;Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/command/OrderedRenderCommandQueue;I)V", shift = At.Shift.BEFORE))
private void onRenderItem(AbstractClientPlayerEntity player, float tickProgress, float pitch, Hand hand, float swingProgress, ItemStack item, float equipProgress, MatrixStack matrices, OrderedRenderCommandQueue orderedRenderCommandQueue, int light, CallbackInfo ci) {
EVENT_BUS.post(new RenderHeldItemEvent(matrices, hand));
}
@Inject(method = "renderFirstPersonItem", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/item/HeldItemRenderer;renderArmHoldingItem(Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;IFFLnet/minecraft/util/Arm;)V"))
private void onRenderArm(AbstractClientPlayerEntity player, float tickDelta, float pitch, Hand hand, float swingProgress, ItemStack item, float equipProgress, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, CallbackInfo ci) {
@Inject(method = "renderFirstPersonItem", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/item/HeldItemRenderer;renderArmHoldingItem(Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/command/OrderedRenderCommandQueue;IFFLnet/minecraft/util/Arm;)V"))
private void onRenderArm(AbstractClientPlayerEntity player, float tickProgress, float pitch, Hand hand, float swingProgress, ItemStack item, float equipProgress, MatrixStack matrices, OrderedRenderCommandQueue orderedRenderCommandQueue, int light, CallbackInfo ci) {
EVENT_BUS.post(new RenderArmEvent(matrices, hand));
}
@@ -5,7 +5,7 @@ import me.retucio.camtweaks.module.ModuleManager;
import me.retucio.camtweaks.module.modules.ChatPlus;
import me.retucio.camtweaks.module.modules.Freecam;
import me.retucio.camtweaks.module.modules.NoRender;
import me.retucio.camtweaks.ui.HUD;
import me.retucio.camtweaks.ui.HudRenderer;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.hud.InGameHud;
@@ -66,7 +66,7 @@ public abstract class InGameHudMixin {
@Inject(method = "render", at = @At("RETURN"))
private void renderHUD(DrawContext ctx, RenderTickCounter tc, CallbackInfo ci) {
HUD.render(ctx, tc);
HudRenderer.render(ctx, tc);
}
@ModifyExpressionValue(method = "renderCrosshair", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/option/Perspective;isFirstPerson()Z"))
@@ -5,6 +5,8 @@ import me.retucio.camtweaks.module.modules.NoRender;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.hud.InGameOverlayRenderer;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.texture.Sprite;
import net.minecraft.client.texture.SpriteHolder;
import net.minecraft.client.util.math.MatrixStack;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
@@ -19,12 +21,12 @@ public abstract class InGameOverlayRendererMixin {
private static NoRender noRender;
@Inject(method = "<init>", at = @At("TAIL"))
private void getModules(MinecraftClient client, VertexConsumerProvider vertexConsumers, CallbackInfo ci) {
private void getModules(MinecraftClient client, SpriteHolder spriteHolder, VertexConsumerProvider vertexConsumers, CallbackInfo ci) {
noRender = ModuleManager.INSTANCE.getModuleByClass(NoRender.class);
}
@Inject(method = "renderFireOverlay", at = @At("HEAD"), cancellable = true)
private static void noRenderFireOverlay(MatrixStack matrices, VertexConsumerProvider vertexConsumers, CallbackInfo ci) {
private static void noRenderFireOverlay(MatrixStack matrices, VertexConsumerProvider vertexConsumers, Sprite sprite, CallbackInfo ci) {
if (noRender.isEnabled() && !noRender.fireOverlay.isEnabled()) ci.cancel();
}
@@ -5,7 +5,9 @@ import me.retucio.camtweaks.module.ModuleManager;
import me.retucio.camtweaks.module.modules.Nametags;
import net.minecraft.entity.ItemEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.text.MutableText;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
@@ -22,7 +24,15 @@ public abstract class ItemEntityMixin {
if (!nametags.isEnabled()) return original;
int count = this.getStack().getCount();
if (nametags.countItems.isEnabled() && count > 1) return original.copy().append(" x" + count);
MutableText name = this.getStack().getCustomName() != null ? this.getStack().getCustomName().copyContentOnly() : original.copyContentOnly();
if (!name.equals(original)) name = name.formatted(Formatting.ITALIC);
if (nametags.countItems.isEnabled()) {
if (count > 1) return name.copy().append(" x" + count);
return name;
}
return original;
}
}
@@ -3,6 +3,7 @@ package me.retucio.camtweaks.mixin;
import me.retucio.camtweaks.CameraTweaks;
import me.retucio.camtweaks.event.events.KeyEvent;
import net.minecraft.client.Keyboard;
import net.minecraft.client.input.KeyInput;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
@@ -14,10 +15,10 @@ import static me.retucio.camtweaks.CameraTweaks.EVENT_BUS;
public abstract class KeyboardMixin {
@Inject(method = "onKey", at = @At("HEAD"), cancellable = true)
private void onKeyPress(long window, int key, int scancode, int action, int modifiers, CallbackInfo ci) {
CameraTweaks.INSTANCE.onKeyPress(key, action);
private void onKeyPress(long window, int action, KeyInput input, CallbackInfo ci) {
CameraTweaks.INSTANCE.onKeyPress(input.key(), action);
KeyEvent event = EVENT_BUS.post(new KeyEvent(key, scancode, action));
KeyEvent event = EVENT_BUS.post(new KeyEvent(input.key(), input.scancode(), action));
if (event.isCancelled()) ci.cancel();
}
}
@@ -8,7 +8,6 @@ import me.retucio.camtweaks.module.modules.Freecam;
import me.retucio.camtweaks.module.modules.Nametags;
import net.minecraft.client.render.entity.EntityRendererFactory;
import net.minecraft.client.render.entity.LivingEntityRenderer;
import net.minecraft.client.render.entity.PlayerEntityRenderer;
import net.minecraft.client.render.entity.model.EntityModel;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
@@ -19,6 +18,9 @@ import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import static me.retucio.camtweaks.CameraTweaks.mc;
@Mixin(LivingEntityRenderer.class)
public abstract class LivingEntityRendererMixin<T extends LivingEntity> {
@@ -52,4 +54,14 @@ public abstract class LivingEntityRendererMixin<T extends LivingEntity> {
if (nametags.isEnabled() && livingEntity instanceof PlayerEntity) return nametags.entities.isEnabled(EntityType.PLAYER) && original;
return original;
}
@Inject(method = "hasLabel(Lnet/minecraft/entity/LivingEntity;D)Z", at = @At("RETURN"), cancellable = true)
private void renderSelfNametag(T livingEntity, double d, CallbackInfoReturnable<Boolean> cir) {
if (livingEntity instanceof PlayerEntity player) {
if (player == mc.player && nametags.showSelf.isEnabled()) {
cir.setReturnValue(true);
cir.cancel();
}
}
}
}
@@ -1,5 +1,6 @@
package me.retucio.camtweaks.mixin;
import com.llamalad7.mixinextras.injector.ModifyReturnValue;
import me.retucio.camtweaks.CameraTweaks;
import me.retucio.camtweaks.event.events.OpenScreenEvent;
import me.retucio.camtweaks.event.events.ShutdownEvent;
@@ -10,6 +11,7 @@ import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import static me.retucio.camtweaks.CameraTweaks.EVENT_BUS;
@@ -37,4 +39,9 @@ public abstract class MinecraftClientMixin {
OpenScreenEvent event = EVENT_BUS.post(new OpenScreenEvent(screen));
if (event.isCancelled()) ci.cancel();
}
@Inject(method = "isTelemetryEnabledByApi", at = @At("RETURN"), cancellable = true)
private void disableMicropenisTelemetryShi(CallbackInfoReturnable<Boolean> cir) {
cir.setReturnValue(false);
}
}
@@ -4,6 +4,7 @@ import me.retucio.camtweaks.CameraTweaks;
import me.retucio.camtweaks.event.events.MouseClickEvent;
import me.retucio.camtweaks.event.events.MouseScrollEvent;
import net.minecraft.client.Mouse;
import net.minecraft.client.input.MouseInput;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
@@ -15,8 +16,8 @@ import static me.retucio.camtweaks.CameraTweaks.EVENT_BUS;
public abstract class MouseMixin {
@Inject(method = "onMouseButton", at = @At("HEAD"), cancellable = true)
private void onMouseButton(long window, int button, int action, int mods, CallbackInfo ci) {
MouseClickEvent event = EVENT_BUS.post(new MouseClickEvent(action, button));
private void onMouseButton(long window, MouseInput input, int action, CallbackInfo ci) {
MouseClickEvent event = EVENT_BUS.post(new MouseClickEvent(action, input.button()));
if (event.isCancelled()) ci.cancel();
}
@@ -15,6 +15,8 @@ import java.io.File;
import java.io.IOException;
import java.util.function.Consumer;
import static me.retucio.camtweaks.CameraTweaks.mc;
@Mixin(ScreenshotRecorder.class)
public abstract class ScreenshotRecorderMixin {
@@ -35,7 +37,8 @@ public abstract class ScreenshotRecorderMixin {
if (!screenshotPlus.isEnabled()) return;
screenshotPlus.sendScreenshotMessage();
// por los threads o lo que sea
mc.execute(screenshotPlus::sendScreenshotMessage);
switch (screenshotPlus.defaultAction.getValue()) {
case COPY -> screenshotPlus.copyScreenshot(nativeImage);
@@ -24,12 +24,12 @@ public abstract class SkyRendererMixin {
}
@Inject(method = "renderSun", at = @At("HEAD"), cancellable = true)
private void onRenderSun(float alpha, VertexConsumerProvider vertexConsumers, MatrixStack matrices, CallbackInfo ci) {
private void onRenderSun(float alpha, MatrixStack matrices, CallbackInfo ci) {
if (timeChanger.isEnabled() && !timeChanger.renderSun.isEnabled()) ci.cancel();
}
@Inject(method = "renderMoon", at = @At("HEAD"), cancellable = true)
private void onRenderMoon(int phase, float alpha, VertexConsumerProvider vertexConsumers, MatrixStack matrices, CallbackInfo ci) {
private void onRenderMoon(int phase, float alpha, MatrixStack matrixStack, CallbackInfo ci) {
if (timeChanger.isEnabled() && !timeChanger.renderMoon.isEnabled()) ci.cancel();
}
@@ -0,0 +1,16 @@
package me.retucio.camtweaks.mixin;
import net.minecraft.client.session.telemetry.TelemetryManager;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Coerce;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(TelemetryManager.class)
public class TelemetryManagerMixin {
@Redirect(method = "computeSender", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;isTelemetryEnabledByApi()Z"))
private boolean disableTelemetry(@Coerce Object minecraftClient) {
return false;
}
}
@@ -1,15 +1,22 @@
package me.retucio.camtweaks.mixin;
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import com.llamalad7.mixinextras.injector.ModifyReturnValue;
import me.retucio.camtweaks.module.ModuleManager;
import me.retucio.camtweaks.module.modules.NoRender;
import net.minecraft.client.font.BakedGlyph;
import net.minecraft.client.font.GlyphProvider;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.text.Style;
import net.minecraft.text.TextColor;
import net.minecraft.util.math.MathHelper;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.*;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import static me.retucio.camtweaks.CameraTweaks.mc;
// falta italics pero no sé dónde se comprueba eso, no es aquí :P
@Mixin(TextRenderer.Drawer.class)
public abstract class TextRendererDrawerMixin {
@@ -22,27 +29,22 @@ public abstract class TextRendererDrawerMixin {
noRender = ModuleManager.INSTANCE.getModuleByClass(NoRender.class);
}
@Redirect(method = "accept", at = @At(value = "INVOKE", target = "Lnet/minecraft/text/Style;isBold()Z"))
@Redirect(method = "accept(ILnet/minecraft/text/Style;Lnet/minecraft/client/font/BakedGlyph;)Z", at = @At(value = "INVOKE", target = "Lnet/minecraft/text/Style;isBold()Z"))
private boolean noRenderBold(Style style) {
return !(noRender.isEnabled() && !noRender.bold.isEnabled()) && style.isBold();
}
@Redirect(method = "accept", at = @At(value = "INVOKE", target = "Lnet/minecraft/text/Style;isUnderlined()Z"))
@Redirect(method = "accept(ILnet/minecraft/text/Style;Lnet/minecraft/client/font/BakedGlyph;)Z", at = @At(value = "INVOKE", target = "Lnet/minecraft/text/Style;isUnderlined()Z"))
private boolean noRenderUnderlined(Style style) {
return !(noRender.isEnabled() && !noRender.underlined.isEnabled()) && style.isUnderlined();
}
@Redirect(method = "accept", at = @At(value = "INVOKE", target = "Lnet/minecraft/text/Style;isStrikethrough()Z"))
@Redirect(method = "accept(ILnet/minecraft/text/Style;Lnet/minecraft/client/font/BakedGlyph;)Z", at = @At(value = "INVOKE", target = "Lnet/minecraft/text/Style;isStrikethrough()Z"))
private boolean noRenderStrikethrough(Style style) {
return !(noRender.isEnabled() && !noRender.strikethrough.isEnabled()) && style.isStrikethrough();
}
@Redirect(method = "accept", at = @At(value = "INVOKE", target = "Lnet/minecraft/text/Style;isObfuscated()Z"))
private boolean noRenderMTS(Style style) {
return !(noRender.isEnabled() && !noRender.scrambledText.isEnabled()) && style.isObfuscated();
}
@ModifyArg(method = "accept", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/font/TextRenderer$Drawer;getRenderColor(Lnet/minecraft/text/TextColor;)I"))
@ModifyArg(method = "accept(ILnet/minecraft/text/Style;Lnet/minecraft/client/font/BakedGlyph;)Z", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/font/TextRenderer$Drawer;getRenderColor(Lnet/minecraft/text/TextColor;)I"))
private TextColor noRenderColor(TextColor original) {
return !noRender.color.is(NoRender.Colors.DEFAULT) ? TextColor.fromFormatting(noRender.color.getValue().toFormatting()) : original;
}
@@ -0,0 +1,18 @@
package me.retucio.camtweaks.mixin;
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import me.retucio.camtweaks.module.ModuleManager;
import me.retucio.camtweaks.module.modules.NoRender;
import net.minecraft.client.font.TextRenderer;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
@Mixin(TextRenderer.class)
public abstract class TextRendererMixin {
@ModifyExpressionValue(method = "getGlyph", at = @At(value = "INVOKE", target = "Lnet/minecraft/text/Style;isObfuscated()Z"))
private boolean noRenderMTS(boolean original) {
NoRender noRender = ModuleManager.INSTANCE.getModuleByClass(NoRender.class);
return (!noRender.isEnabled() || noRender.scrambledText.isEnabled()) && original;
}
}
@@ -0,0 +1,33 @@
package me.retucio.camtweaks.mixin;
import me.retucio.camtweaks.CameraTweaks;
import me.retucio.camtweaks.ui.frames.ClientSettingsFrame;
import net.minecraft.SharedConstants;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.TitleScreen;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.awt.*;
import static me.retucio.camtweaks.CameraTweaks.mc;
@Mixin(TitleScreen.class)
public abstract class TitleScreenMixin {
// marca de agua porque soy superguay
@Inject(method = "render", at = @At("TAIL"))
private void renderWatermark(DrawContext context, int mouseX, int mouseY, float deltaTicks, CallbackInfo ci) {
String watermark = CameraTweaks.MOD_ID + "_v" + CameraTweaks.MOD_VERSION + "_" + SharedConstants.getGameVersion().name();
context.drawText(mc.textRenderer, watermark,
mc.getWindow().getScaledWidth() - mc.textRenderer.getWidth(watermark) - 2, 2,
new Color((int) ClientSettingsFrame.guiSettings.red.getDefaultValue(),
(int) ClientSettingsFrame.guiSettings.green.getDefaultValue(),
(int) ClientSettingsFrame.guiSettings.blue.getDefaultValue(),
(int) ClientSettingsFrame.guiSettings.alpha.getDefaultValue()
).getRGB(), false
);
}
}
@@ -5,6 +5,7 @@ import me.retucio.camtweaks.module.modules.NoRender;
import net.minecraft.client.render.Camera;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.WeatherRendering;
import net.minecraft.client.render.state.WeatherRenderState;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.particle.ParticlesMode;
import net.minecraft.util.math.Vec3d;
@@ -33,11 +34,11 @@ public abstract class WeatherRenderingMixin {
if (noRender.isEnabled() && !noRender.rain.isEnabled()) ci.cancel();
}
@Inject(method = "renderPrecipitation(Lnet/minecraft/client/render/VertexConsumerProvider;Lnet/minecraft/util/math/Vec3d;IFLjava/util/List;Ljava/util/List;)V", at = @At("HEAD"))
private void noRenderRainAndSnow(VertexConsumerProvider vertexConsumers, Vec3d pos, int range, float gradient, List<?> rainPieces, List<?> snowPieces, CallbackInfo ci) {
@Inject(method = "renderPrecipitation", at = @At("HEAD"))
private void noRenderRainAndSnow(VertexConsumerProvider vertexConsumers, Vec3d pos, WeatherRenderState weatherRenderState, CallbackInfo ci) {
if (noRender.isEnabled()) {
if (!noRender.rain.isEnabled()) rainPieces.clear();
if (!noRender.snow.isEnabled()) snowPieces.clear();
if (!noRender.rain.isEnabled()) weatherRenderState.rainPieces.clear();
if (!noRender.snow.isEnabled()) weatherRenderState.snowPieces.clear();
}
}
}
@@ -1,23 +1,74 @@
package me.retucio.camtweaks.mixin;
import com.llamalad7.mixinextras.sugar.Local;
import com.mojang.blaze3d.buffers.GpuBufferSlice;
import me.retucio.camtweaks.CameraTweaks;
import me.retucio.camtweaks.event.events.RenderWorldEvent;
import me.retucio.camtweaks.module.ModuleManager;
import me.retucio.camtweaks.module.modules.BlockOutline;
import me.retucio.camtweaks.module.modules.Freecam;
import net.minecraft.client.render.WorldRenderer;
import me.retucio.camtweaks.module.modules.NoRender;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.*;
import net.minecraft.client.render.state.WorldRenderState;
import net.minecraft.client.util.ObjectAllocator;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.math.ColorHelper;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.RotationAxis;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.profiler.Profiler;
import org.joml.Matrix4f;
import org.joml.Vector4f;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyArg;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.awt.*;
import static me.retucio.camtweaks.CameraTweaks.EVENT_BUS;
import static me.retucio.camtweaks.CameraTweaks.mc;
@Mixin(WorldRenderer.class)
public abstract class WorldRendererMixin {
@ModifyArg(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/WorldRenderer;setupTerrain(Lnet/minecraft/client/render/Camera;Lnet/minecraft/client/render/Frustum;ZZ)V"), index = 3)
private boolean renderSetupTerrainModifyArg(boolean hasForcedFrustum) {
return ModuleManager.INSTANCE.getModuleByClass(Freecam.class).isEnabled() || hasForcedFrustum;
@ModifyArg(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/WorldRenderer;method_74752(Lnet/minecraft/client/render/Camera;Lnet/minecraft/client/render/Frustum;Z)V"), index = 2)
private boolean renderSetupTerrainModifyArg(boolean spectator) {
return ModuleManager.INSTANCE.getModuleByClass(Freecam.class).isEnabled() || spectator;
}
@Inject(method = "render", at = @At("RETURN"))
private void render(ObjectAllocator allocator, RenderTickCounter tickCounter, boolean renderBlockOutline, Camera camera, Matrix4f positionMatrix, Matrix4f matrix4f, Matrix4f projectionMatrix, GpuBufferSlice fogBuffer, Vector4f fogColor, boolean renderSky, CallbackInfo ci, @Local Profiler profiler) {
if (mc == null || mc.world == null) return;
MatrixStack matrices = new MatrixStack();
matrices.push();
matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(camera.getPitch()));
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(camera.getYaw() + 180f));
profiler.push(CameraTweaks.MOD_ID + "-3d");
EVENT_BUS.post(new RenderWorldEvent(matrices, tickCounter, camera));
profiler.pop();
matrices.pop();
}
@Inject(method = "renderTargetBlockOutline", at = @At("HEAD"), cancellable = true)
private void noRenderBlockOutlinesFreecam(VertexConsumerProvider.Immediate immediate, MatrixStack matrices, boolean renderBlockOutline, WorldRenderState renderStates, CallbackInfo ci) {
Freecam freecam = ModuleManager.INSTANCE.getModuleByClass(Freecam.class);
if (freecam.isEnabled() && !freecam.blockOutlines.isEnabled()) ci.cancel();
}
@Inject(method = "hasBlindnessOrDarkness(Lnet/minecraft/client/render/Camera;)Z", at = @At("HEAD"), cancellable = true)
private void hasBlindnessOrDarkness(Camera camera, CallbackInfoReturnable<Boolean> cir) {
NoRender noRender = ModuleManager.INSTANCE.getModuleByClass(NoRender.class);
if (!noRender.isEnabled()) return;
if (!noRender.blindnessEffect.isEnabled() || !noRender.darknessEffect.isEnabled()) cir.setReturnValue(null);
}
@Redirect(method = "renderTargetBlockOutline", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/math/ColorHelper;withAlpha(II)I"))
@@ -0,0 +1,18 @@
package me.retucio.camtweaks.mixin;
import com.mojang.authlib.yggdrasil.YggdrasilUserApiService;
import com.mojang.authlib.yggdrasil.response.UserAttributesResponse;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
// código robado de: https://github.com/kb-1000/no-telemetry
@Mixin(YggdrasilUserApiService.class)
public abstract class YggdrasilUserApiServiceMixin {
@Redirect(method = "fetchProperties", at = @At(value = "INVOKE", target = "Lcom/mojang/authlib/yggdrasil/response/UserAttributesResponse$Privileges;getTelemetry()Z", remap = false), remap = false, require = 0)
private boolean getTelemetry(UserAttributesResponse.Privileges instance) {
return false;
}
}
@@ -0,0 +1,13 @@
package me.retucio.camtweaks.mixin.accessor;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.screen.slot.Slot;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(HandledScreen.class)
public interface HandledScreenAccessor {
@Accessor("focusedSlot")
Slot getFocusedSlot();
}
@@ -37,11 +37,15 @@ public class ModuleManager {
modules.add(new Fullbright());
modules.add(new HandView());
modules.add(new HUD());
modules.add(new LogoutSpots());
modules.add(new Nametags());
modules.add(new NoRender());
modules.add(new PerspectivePlus());
modules.add(new PortalGUI());
modules.add(new ScreenshotPlus());
modules.add(new ShulkerPeek());
modules.add(new TimeChanger());
// modules.add(new TooltipsPlus());
modules.add(new Zoom());
modules.sort(Comparator.comparing(module -> module.getName().toLowerCase()));
@@ -162,7 +162,7 @@ public class ChatPlus extends Module {
GameProfile sender = getSender(line, text);
if (sender == null) return;
PlayerListEntry entry = mc.getNetworkHandler().getPlayerListEntry(sender.getId());
PlayerListEntry entry = mc.getNetworkHandler().getPlayerListEntry(sender.id());
if (entry == null) return;
PlayerSkinDrawer.draw(context, entry.getSkinTextures(), 0, y, 8);
@@ -23,7 +23,7 @@ public class CritsPlus extends Module {
public NumberSetting multiplier; // no sé dónde se calcula cuántas partículas aparecen :/
public NumberSetting velocityMultipler = addSetting(new NumberSetting("dispersión", "multiplicador de la velocidad de dispersión", 1, 0, 10, 0.1));
public NumberSetting gravity = addSetting(new NumberSetting("gravedad", "multiplicador de fuerza de gravedad", 1, 0, 10, 0.1));
public NumberSetting maxAge = addSetting(new NumberSetting("vida máxima", "cuánto persiste la partícula", 4, 0, 50, 1));
public NumberSetting maxAge = addSetting(new NumberSetting("vida máxima", "cuánto persiste la partícula", 10, 0, 50, 1));
public BooleanSetting collide = addSetting(new BooleanSetting("colisionar", "colisionar con bloques", false));
public CritsPlus() {
@@ -5,6 +5,7 @@ import me.retucio.camtweaks.module.Module;
import me.retucio.camtweaks.module.settings.StringSetting;
import net.minecraft.client.network.OtherClientPlayerEntity;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity;
import java.util.UUID;
@@ -21,24 +22,28 @@ public class FakePlayer extends Module {
@Override
public void onEnable() {
if (mc.world == null) return;
player = new OtherClientPlayerEntity(mc.world, new GameProfile(UUID.randomUUID(), name.getValue()));
// player.copyPositionAndRotation(mc.player);
player.copyFrom(mc.player);
mc.world.addEntity(player);
addPlayer(mc.player, name.getValue());
super.onEnable();
}
@Override
public void onDisable() {
if (mc.world == null || player == null) return;
removePlayer();
super.onDisable();
}
public OtherClientPlayerEntity addPlayer(PlayerEntity playerToCopy, String dummyName) {
player = new OtherClientPlayerEntity(mc.world, new GameProfile(UUID.randomUUID(), dummyName));
player.copyFrom(playerToCopy);
player.setCustomNameVisible(true);
mc.world.addEntity(player);
return player;
}
public void removePlayer() {
player.setRemoved(Entity.RemovalReason.KILLED);
player.onRemoved();
player = null;
super.onDisable();
}
}
@@ -5,10 +5,15 @@ import me.retucio.camtweaks.event.SubscribeEvent;
import me.retucio.camtweaks.event.events.*;
import me.retucio.camtweaks.module.Module;
import me.retucio.camtweaks.module.settings.BooleanSetting;
import me.retucio.camtweaks.module.settings.KeySetting;
import me.retucio.camtweaks.module.settings.NumberSetting;
import me.retucio.camtweaks.util.ChatUtil;
import me.retucio.camtweaks.util.KeyUtil;
import me.retucio.camtweaks.util.MiscUtil;
import net.minecraft.client.gui.Click;
import net.minecraft.client.input.KeyInput;
import net.minecraft.client.input.MouseInput;
import net.minecraft.client.option.KeyBinding;
import net.minecraft.client.option.Perspective;
import net.minecraft.network.packet.Packet;
import net.minecraft.network.packet.c2s.play.HandSwingC2SPacket;
@@ -26,7 +31,6 @@ import org.lwjgl.glfw.GLFW;
* @see me.retucio.camtweaks.mixin.CameraMixin
* @see me.retucio.camtweaks.mixin.ChunkBorderDebugRendererMixin
* @see me.retucio.camtweaks.mixin.ClientPlayerInteractionManagerMixin
* @see me.retucio.camtweaks.mixin.CompassStateMixin
* @see me.retucio.camtweaks.mixin.EntityMixin
* @see me.retucio.camtweaks.mixin.GameRendererMixin
* @see me.retucio.camtweaks.mixin.KeyInputMixin
@@ -44,17 +48,18 @@ public class Freecam extends Module {
public BooleanSetting stayCrouching = addSetting(new BooleanSetting("mantenerse agachado", "mantener al jugador agachado tras entrar en el modo de cámara libre", false));
public BooleanSetting staticView = addSetting(new BooleanSetting("visión estática", "desactiva ajustes que muevan la cámara", true));
public BooleanSetting cancelActionPackets = addSetting(new BooleanSetting("cancelar paquetes", "evita flaggear el anticheat al interactuar con bloques / entidades", true));
public BooleanSetting blockOutlines = addSetting(new BooleanSetting("contorno de bloques", "mostrar el contorno de los bloques estando en el modo de cámara libre", true));
public NumberSetting speedSetting = addSetting(new NumberSetting(
"velocidad", "velocidad de movimiento de la cámara",
1, 0, 10, 0.2));
public KeySetting scrollKey = addSetting(new KeySetting("tecla del scroll", "tecla a mantener pulsada para cambiar velocidad con el scroll", GLFW.GLFW_KEY_LEFT_CONTROL));
public NumberSetting scrollSens = addSetting(new NumberSetting(
"sensibilidad del scroll", "sensibilidad de la rueda del ratón para modificar la velocidad, 0 para desactivar",
0, 0, 2, 0.1));
1, 0, 2, 0.1));
// rotate?
private final Vector3d prevPos = new Vector3d();
private float prevYaw, prevPitch;
@@ -141,9 +146,9 @@ public class Freecam extends Module {
@Override
public void onTick() {
if (mc.cameraEntity == null || perspective == null) return;
if (mc.getCameraEntity() == null || perspective == null) return;
mc.cameraEntity.noClip = mc.cameraEntity.isInsideWall();
mc.getCameraEntity().noClip = mc.getCameraEntity().isInsideWall();
if (!perspective.isFirstPerson()) mc.options.setPerspective(Perspective.FIRST_PERSON);
Vec3d forward = Vec3d.fromPolar(0, yaw);
@@ -204,24 +209,25 @@ public class Freecam extends Module {
public void onKey(KeyEvent event) {
if (mc.currentScreen != null) return;
if (KeyUtil.isKeyDown(GLFW.GLFW_KEY_F3)) return;
KeyInput key = new KeyInput(event.getKey(), event.getScancode(), 0);
boolean shouldCancel = true;
if (mc.options.forwardKey.matchesKey(event.getKey(), event.getScancode())) {
if (mc.options.forwardKey.matchesKey(key)) {
forward = event.getAction() != GLFW.GLFW_RELEASE;
mc.options.forwardKey.setPressed(false);
} else if (mc.options.backKey.matchesKey(event.getKey(), event.getScancode())) {
} else if (mc.options.backKey.matchesKey(key)) {
backward = event.getAction() != GLFW.GLFW_RELEASE;
mc.options.backKey.setPressed(false);
} else if (mc.options.rightKey.matchesKey(event.getKey(), event.getScancode())) {
} else if (mc.options.rightKey.matchesKey(key)) {
right = event.getAction() != GLFW.GLFW_RELEASE;
mc.options.rightKey.setPressed(false);
} else if (mc.options.leftKey.matchesKey(event.getKey(), event.getScancode())) {
} else if (mc.options.leftKey.matchesKey(key)) {
left = event.getAction() != GLFW.GLFW_RELEASE;
mc.options.leftKey.setPressed(false);
} else if (mc.options.jumpKey.matchesKey(event.getKey(), event.getScancode())) {
} else if (mc.options.jumpKey.matchesKey(key)) {
up = event.getAction() != GLFW.GLFW_RELEASE;
mc.options.jumpKey.setPressed(false);
} else if (mc.options.sneakKey.matchesKey(event.getKey(), event.getScancode())) {
} else if (mc.options.sneakKey.matchesKey(key)) {
down = event.getAction() != GLFW.GLFW_RELEASE;
mc.options.sneakKey.setPressed(false);
} else {
@@ -234,24 +240,25 @@ public class Freecam extends Module {
@SubscribeEvent
public void onMouseClick(MouseClickEvent event) { // por si el restrasado del usuario usa el ratón para moverse
if (mc.currentScreen != null) return;
Click click = new Click(0, 0, new MouseInput(event.getButton(), 0));
boolean shouldCancel = true;
if (mc.options.forwardKey.matchesKey(event.getButton(), 0)) {
if (mc.options.forwardKey.matchesMouse(click)) {
forward = event.getAction() != GLFW.GLFW_RELEASE;
mc.options.forwardKey.setPressed(false);
} else if (mc.options.backKey.matchesKey(event.getButton(), 0)) {
} else if (mc.options.backKey.matchesMouse(click)) {
backward = event.getAction() != GLFW.GLFW_RELEASE;
mc.options.backKey.setPressed(false);
} else if (mc.options.rightKey.matchesKey(event.getButton(), 0)) {
} else if (mc.options.rightKey.matchesMouse(click)) {
right = event.getAction() != GLFW.GLFW_RELEASE;
mc.options.rightKey.setPressed(false);
} else if (mc.options.leftKey.matchesKey(event.getButton(), 0)) {
} else if (mc.options.leftKey.matchesMouse(click)) {
left = event.getAction() != GLFW.GLFW_RELEASE;
mc.options.leftKey.setPressed(false);
} else if (mc.options.jumpKey.matchesKey(event.getButton(), 0)) {
} else if (mc.options.jumpKey.matchesMouse(click)) {
up = event.getAction() != GLFW.GLFW_RELEASE;
mc.options.jumpKey.setPressed(false);
} else if (mc.options.sneakKey.matchesKey(event.getButton(), 0)) {
} else if (mc.options.sneakKey.matchesMouse(click)) {
down = event.getAction() != GLFW.GLFW_RELEASE;
mc.options.sneakKey.setPressed(false);
} else {
@@ -263,7 +270,7 @@ public class Freecam extends Module {
@SubscribeEvent
private void onMouseScroll(MouseScrollEvent event) {
if (scrollSens.getValue() > 0 && mc.currentScreen == null) {
if (scrollSens.getValue() > 0 && mc.currentScreen == null && KeyUtil.isKeyDown(scrollKey.getKey())) {
speed += event.getVertical() / 4 * (scrollSens.getValue() * speed);
if (speed < 0.1) speed = 0.1;
event.cancel();
@@ -39,6 +39,8 @@ public class Fullbright extends Module {
green.setVisible(v);
blue.setVisible(v);
alpha.setVisible(v);
if (v) disableNightVision();
});
}
@@ -1,13 +1,22 @@
package me.retucio.camtweaks.module.modules;
import me.retucio.camtweaks.module.Module;
import me.retucio.camtweaks.module.settings.BooleanSetting;
import me.retucio.camtweaks.module.settings.EnumSetting;
import me.retucio.camtweaks.module.settings.NumberSetting;
import me.retucio.camtweaks.module.settings.StringSetting;
import me.retucio.camtweaks.module.settings.*;
import me.retucio.camtweaks.ui.screen.HudEditorScreen;
import org.lwjgl.glfw.GLFW;
/** lógica del HUD manejada en:
* @see me.retucio.camtweaks.ui.HudRenderer
* @see me.retucio.camtweaks.ui.widgets.HudElement
* @see HudEditorScreen
*/
public class HUD extends Module {
// editor
public KeySetting editorKey = addSetting(new KeySetting("tecla del editor", "tecla asignada al editor de elementos del hud", GLFW.GLFW_KEY_PAGE_UP));
// colores
public NumberSetting red = addSetting(new NumberSetting("rojo", "cantidad de rojo", 255, 0, 255, 1));
public NumberSetting green = addSetting(new NumberSetting("verde", "cantidad de verde", 255, 0, 255, 1));
public NumberSetting blue = addSetting(new NumberSetting("azul", "cantidad de azul", 255, 0, 255, 1));
@@ -16,18 +25,15 @@ public class HUD extends Module {
public NumberSetting rainbowSpeed = addSetting(new NumberSetting("velocidad del arcoíris", "velocidad del arcoíris", 1000, 0, 10000, 2));
public NumberSetting alpha = addSetting(new NumberSetting("opacidad", "antitransparencia", 255, 0, 255, 1));
// ajustes
public BooleanSetting showOnF3 = addSetting(new BooleanSetting("mostrar en F3", "renderizar HUD en el menú de debug", false));
public BooleanSetting showOnChat = addSetting(new BooleanSetting("mostrar en chat", "renderizar HUD en la pantalla del chat", false));
public BooleanSetting shadow = addSetting(new BooleanSetting("sombra", "texto con sombra", true));
public BooleanSetting dontOverride = addSetting(new BooleanSetting("no sobreescribir", "evita dibujar por encima de otros elementos de la interfaz", true));
public EnumSetting<TimeFormat> timeFormat = addSetting(new EnumSetting<>("formato de la hora", "12h o 24h", TimeFormat.class, TimeFormat.TWENTY_FOUR_HOUR));
public NumberSetting timezone = addSetting(new NumberSetting("zona horaria", "zona horaria en UTC+n", 1, -6, 6, 1));
public BooleanSetting coords = addSetting(new BooleanSetting("coordenadas", "mostrar coordenadas", true));
public StringSetting customText = addSetting(new StringSetting("texto custom", "marca de agua (dejar vacío para quitar)", "ESCROTO", 40));
public BooleanSetting fps = addSetting(new BooleanSetting("fps", "mostrar frames por segundo", true));
public BooleanSetting tps = addSetting(new BooleanSetting("tps", "mostrar tasa de ticks por segundo del server", true));
public BooleanSetting time = addSetting(new BooleanSetting("hora", "mostrar hora actual", true));
public 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 HUD() {
super("HUD", "superposición de la pantalla con info. adicional");
@@ -38,11 +44,6 @@ public class HUD extends Module {
green.setVisible(!v);
blue.setVisible(!v);
});
time.onUpdate(v -> {
timeFormat.setVisible(v);
timezone.setVisible(v);
});
}
public enum TimeFormat {
@@ -0,0 +1,119 @@
package me.retucio.camtweaks.module.modules;
import me.retucio.camtweaks.event.SubscribeEvent;
import me.retucio.camtweaks.event.events.KeyEvent;
import me.retucio.camtweaks.event.events.RenderWorldEvent;
import me.retucio.camtweaks.event.events.camtweaks.AddEntityEvent;
import me.retucio.camtweaks.event.events.camtweaks.RemoveEntityEvent;
import me.retucio.camtweaks.module.Module;
import me.retucio.camtweaks.module.ModuleManager;
import me.retucio.camtweaks.module.settings.BooleanSetting;
import me.retucio.camtweaks.module.settings.KeySetting;
import me.retucio.camtweaks.module.settings.NumberSetting;
import me.retucio.camtweaks.util.render.RenderUtil;
import net.minecraft.client.network.OtherClientPlayerEntity;
import net.minecraft.client.render.*;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity;
import org.joml.*;
import org.lwjgl.glfw.GLFW;
import java.awt.*;
import java.time.Instant;
import java.time.LocalTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
public class LogoutSpots extends Module {
public KeySetting clearBoxesKey = addSetting(new KeySetting("vaciar cajas", "tecla asignada a olvidar todas las cajas activas", GLFW.GLFW_KEY_UNKNOWN));
public BooleanSetting filledBox = addSetting(new BooleanSetting("caja rellena", "rellenar caja", true));
public BooleanSetting outlineBox = addSetting(new BooleanSetting("caja de esquinas", "contorno de caja", true));
public NumberSetting red = addSetting(new NumberSetting("rojo", "cantidad de rojo", 200, 0, 255, 1));
public NumberSetting green = addSetting(new NumberSetting("verde", "cantidad de verde", 90, 0, 255, 1));
public NumberSetting blue = addSetting(new NumberSetting("azul", "cantidad de azul", 255, 0, 255, 1));
public NumberSetting alpha = addSetting(new NumberSetting("opacidad", "antitransparencia", 50, 0, 255, 1));
public NumberSetting lineWidth = addSetting(new NumberSetting("grosor", "grosor de las líneas a dibujar", 2, 1, 10, 0.5f));
private final List<LogoutBox> boxes = new ArrayList<>();
public LogoutSpots() {
super("puntos de desconexión", "te muestra los puntos donde se desconectan los jugadores");
}
@SubscribeEvent
public void onWorldRender(RenderWorldEvent event) {
if (mc.player == null || mc.world == null) return;
int r = red.getIntValue();
int g = green.getIntValue();
int b = blue.getIntValue();
int a = alpha.getIntValue();
MatrixStack matrices = event.getMatrices();
for (LogoutBox box : boxes) {
if (filledBox.isEnabled())
RenderUtil.drawFilledBox(matrices, box.dummy.getBoundingBox(), new Color(r, g, b, a));
if (outlineBox.isEnabled())
RenderUtil.drawOutlineBox(matrices, box.dummy.getBoundingBox(), new Color(r, g, b, a), lineWidth.getFloatValue());
}
}
@SubscribeEvent
public void onEntityRemoved(RemoveEntityEvent event) {
if (event.getEntity() instanceof PlayerEntity player && player != mc.player) {
String playerName = player.getName().getString() + " (" + getLogoutTime(System.currentTimeMillis()) + ")";
boxes.add(new LogoutBox(
ModuleManager.INSTANCE.getModuleByClass(FakePlayer.class).addPlayer(player, playerName),
System.currentTimeMillis()
));
}
}
@SubscribeEvent
public void onEntityAdded(AddEntityEvent event) {
boxes.removeIf(box -> event.getEntity().getUuid().equals(box.dummy.getUuid()));
}
@SubscribeEvent
public void onKey(KeyEvent event) {
if (event.getKey() == clearBoxesKey.getKey()) {
boxes.forEach(box -> {
box.dummy.setRemoved(Entity.RemovalReason.KILLED);
box.dummy.onRemoved();
});
boxes.clear();
}
}
private String getLogoutTime(long logoutTimeMillis) {
HUD hud = ModuleManager.INSTANCE.getModuleByClass(HUD.class);
Instant instant = Instant.ofEpochMilli(logoutTimeMillis);
ZoneOffset offset = ZoneOffset.ofHours(hud.timezone.getIntValue());
LocalTime logoutTime = LocalTime.from(instant.atOffset(offset));
boolean is24 = hud.timeFormat.is(HUD.TimeFormat.TWENTY_FOUR_HOUR);
DateTimeFormatter format = DateTimeFormatter.ofPattern(is24 ? "HH:mm" : "hh:mm a");
return logoutTime.format(format);
}
public record LogoutBox(
OtherClientPlayerEntity dummy,
long logoutTime
) {}
}
@@ -14,8 +14,11 @@ import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.damage.DamageSource;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.projectile.PersistentProjectileEntity;
import net.minecraft.item.Item;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.entity.EntityQueriable;
import net.minecraft.world.entity.UniquelyIdentifiable;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
@@ -44,8 +47,11 @@ public class Nametags extends Module {
public EnumSetting<HealthMode> healthMode = addSetting(new EnumSetting<>("mostrar vida en", "de qué manera mostrar la vida", HealthMode.class, HealthMode.POINTS));
public BooleanSetting countItems = addSetting(new BooleanSetting("contar items", "muestra cuánto de un item hay en un stack dropeado", true));
public ListSetting<Item> items = addSetting(new ListSetting<>("items", "te permite elegir cuáles items tienen su nombre visible",
Lists.itemList, Lists.allTrue(Lists.itemList), Lists.itemNames));
public BooleanSetting showProjectileDamage = addSetting(new BooleanSetting("daño del proyectil", "muestra cuánto daño hace un proyectil en su nametag", true));
public BooleanSetting showSelf = addSetting(new BooleanSetting("mostrar propio", "mostrar nametag propio", false));
public BooleanSetting distinguishBabies = addSetting(new BooleanSetting("distinguir bebés", "cambia el nametag cuando una entidad está en su fase bebé", false));
public BooleanSetting petOwner = addSetting(new BooleanSetting("mostrar dueño", "muestra el dueño de una mascota (no funciona en servers no premium)", false));
@@ -64,6 +70,10 @@ public class Nametags extends Module {
entities.setDefaultValues(entities.getValues());
health.onUpdate(v -> healthMode.setVisible(v));
entities.onUpdate(entities -> {
items.setVisible(entities.get(EntityType.ITEM));
});
}
// literalmente cómo lo calcula Minecraft
@@ -74,7 +84,7 @@ public class Nametags extends Module {
double velocity = arrow.getVelocity().length();
DamageSource damageSource = arrow.getDamageSources().arrow(arrow, arrow.getOwner());
if (arrow.getWeaponStack() != null && arrow.getWorld() instanceof ServerWorld world)
if (arrow.getWeaponStack() != null && arrow.getEntityWorld() instanceof ServerWorld world)
initialDamage = EnchantmentHelper.getDamage(world, arrow.getWeaponStack(), mc.player, damageSource, (float) initialDamage);
int finalDamage = MathHelper.ceil(MathHelper.clamp(velocity * initialDamage, 0, 2.147483647E9));
@@ -88,9 +98,11 @@ public class Nametags extends Module {
@SuppressWarnings("deprecation")
public String getOwnerName(LazyEntityReference<LivingEntity> owner) {
// si el dueño está en línea
LivingEntity ownerEntity = owner.resolve(mc.world, LivingEntity.class);
if (ownerEntity instanceof PlayerEntity playerEntity) return playerEntity.getName().getString();
// si el dueño está en línea (de manera segura)
if (mc.world instanceof EntityQueriable<?> queriableWorld) {
LivingEntity ownerEntity = owner.resolve(queriableWorld, LivingEntity.class);
if (ownerEntity instanceof PlayerEntity playerEntity) return playerEntity.getName().getString();
}
// mirar si ya está en la caché
UUID uuid = owner.getUuid();
@@ -42,8 +42,6 @@ public class NoRender extends Module {
public BooleanSetting blindnessEffect = addSetting(new BooleanSetting("ceguera", "renderizar miopía", false));
public BooleanSetting darknessEffect = addSetting(new BooleanSetting("oscuridad", "renderizar miedo a la oscuridad", false));
public BooleanSetting nightVisionEffect;
public NumberSetting potionParticleAlpha = addSetting(new NumberSetting("opacidad de burbujas", "opacidad de las partículas de pociones",
170, 0, 255, 1));
public BooleanSetting scoreboard = addSetting(new BooleanSetting("marcador", "mostrar marcador a la derecha", false));
public BooleanSetting titles = addSetting(new BooleanSetting("títulos", "mostrar títulos (del comando /title)", false));
@@ -0,0 +1,14 @@
package me.retucio.camtweaks.module.modules;
import me.retucio.camtweaks.module.Module;
/** continúa en:
* @see me.retucio.camtweaks.mixin.ClientPlayerEntityMixin
*/
public class PortalGUI extends Module {
public PortalGUI() {
super("interfaz en portales", "te permite abrir interfaces dentro de portales, como el chat o el inventario");
}
}
@@ -0,0 +1,98 @@
package me.retucio.camtweaks.module.modules;
import me.retucio.camtweaks.event.SubscribeEvent;
import me.retucio.camtweaks.event.events.KeyEvent;
import me.retucio.camtweaks.mixin.accessor.HandledScreenAccessor;
import me.retucio.camtweaks.module.Module;
import me.retucio.camtweaks.module.settings.KeySetting;
import me.retucio.camtweaks.ui.screen.ShulkerPreviewScreen;
import net.minecraft.block.ShulkerBoxBlock;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.component.DataComponentTypes;
import net.minecraft.component.type.ContainerComponent;
import net.minecraft.item.BlockItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.screen.slot.Slot;
import org.lwjgl.glfw.GLFW;
import java.awt.*;
import java.util.HashMap;
public class ShulkerPeek extends Module {
public KeySetting previewKey = addSetting(new KeySetting("tecla de previsualización", "tecla a mantener para previsualizar", GLFW.GLFW_KEY_LEFT_ALT));
public static final HashMap<Item, Color> SHULKER_COLORS = new HashMap<>();
public ShulkerPeek() {
super("prev. de shulkers", "te permite previsualizar el contenido de shulkers desde el inventario");
// colores y tal (https://github.com/kgriff0n/shulker-preview)
SHULKER_COLORS.put(Items.SHULKER_BOX, new Color(142, 108, 142));
SHULKER_COLORS.put(Items.WHITE_SHULKER_BOX, new Color(225, 230, 230));
SHULKER_COLORS.put(Items.LIGHT_GRAY_SHULKER_BOX, new Color(137, 137, 128));
SHULKER_COLORS.put(Items.GRAY_SHULKER_BOX, new Color(60, 65, 68));
SHULKER_COLORS.put(Items.BLACK_SHULKER_BOX, new Color(31, 31, 35));
SHULKER_COLORS.put(Items.BROWN_SHULKER_BOX, new Color(113, 70, 39));
SHULKER_COLORS.put(Items.RED_SHULKER_BOX, new Color(152, 36, 34));
SHULKER_COLORS.put(Items.ORANGE_SHULKER_BOX, new Color(241, 114, 15));
SHULKER_COLORS.put(Items.YELLOW_SHULKER_BOX, new Color(249, 196, 35));
SHULKER_COLORS.put(Items.LIME_SHULKER_BOX, new Color(110, 185, 24));
SHULKER_COLORS.put(Items.GREEN_SHULKER_BOX, new Color(83, 107, 29));
SHULKER_COLORS.put(Items.CYAN_SHULKER_BOX, new Color(22, 133, 144));
SHULKER_COLORS.put(Items.LIGHT_BLUE_SHULKER_BOX, new Color(57, 177, 215));
SHULKER_COLORS.put(Items.BLUE_SHULKER_BOX, new Color(49, 52, 152));
SHULKER_COLORS.put(Items.PURPLE_SHULKER_BOX, new Color(113, 37, 166));
SHULKER_COLORS.put(Items.MAGENTA_SHULKER_BOX, new Color(183, 61, 172));
SHULKER_COLORS.put(Items.PINK_SHULKER_BOX, new Color(239, 135, 166));
}
@SubscribeEvent
public void onKey(KeyEvent event) {
if (mc.player == null) return;
if (event.getKey() != previewKey.getKey()) return;
if (event.getAction() == GLFW.GLFW_PRESS) {
openPreviewScreen();
return;
}
if (event.getAction() == GLFW.GLFW_REPEAT) {
if (!(mc.currentScreen instanceof ShulkerPreviewScreen)) {
openPreviewScreen();
return;
}
}
if (event.getAction() == GLFW.GLFW_RELEASE) {
if (mc.currentScreen instanceof ShulkerPreviewScreen preview)
preview.close();
}
}
private void openPreviewScreen() {
if (!(mc.currentScreen instanceof HandledScreen<?> prevScreen)) return;
Slot focusedSlot = ((HandledScreenAccessor) prevScreen).getFocusedSlot();
if (focusedSlot == null) return;
ItemStack stack = focusedSlot.getStack();
if (isShulkerEmpty(stack)) return;
mc.setScreen(new ShulkerPreviewScreen(stack, prevScreen));
}
public static boolean isShulkerEmpty(ItemStack stack) {
if (!(stack.getItem() instanceof BlockItem blockItem)) return true;
if (!(blockItem.getBlock() instanceof ShulkerBoxBlock)) return true;
ContainerComponent container = stack.get(DataComponentTypes.CONTAINER);
if (container == null) return true;
return container.stream().allMatch(ItemStack::isEmpty);
}
}
@@ -0,0 +1,51 @@
package me.retucio.camtweaks.module.modules;
import me.retucio.camtweaks.module.Module;
import me.retucio.camtweaks.module.settings.BooleanSetting;
import me.retucio.camtweaks.module.settings.EnumSetting;
import me.retucio.camtweaks.module.settings.KeySetting;
import org.lwjgl.glfw.GLFW;
public class TooltipsPlus extends Module {
public EnumSetting<DisplayModes> displayMode = addSetting(new EnumSetting<>(
"mostrar", "cúando mostrar la cajita de los huevos", DisplayModes.class, DisplayModes.ALWAYS));
public KeySetting displayKey = addSetting(new KeySetting(
"tecla de visualización", "tecla a presionar para mostrar la cajita", GLFW.GLFW_KEY_LEFT_CONTROL));
public BooleanSetting middleClickPreview = addSetting(new BooleanSetting("preview de middle click",
"abre una interfaz con los contenidos de un bloque de almacenamiento al presionar el middle click (la ruedita)", false));
public EnumSetting<SizeFormat> itemSize = addSetting(new EnumSetting<>(
"tamaño del ítem", "cómo mostrar el tamaño del ítem en memoria", SizeFormat.class, SizeFormat.NONE));
public TooltipsPlus() {
super("tooltips plus", "mejoras varias a las cajitas de descripción de items");
}
public enum DisplayModes {
ALWAYS("siempre"),
KEY("al presionar una tecla"),
NEVER("nunca");
final String name;
DisplayModes(String name) { this.name = name; }
@Override public String toString() { return name; }
}
public enum SizeFormat {
NONE("no mostrar"),
BYTES("bytes"),
KB("kilobytes"),
MB("megabytes");
final String name;
SizeFormat(String name) { this.name = name; }
@Override public String toString() { return name; }
}
}
@@ -1,110 +0,0 @@
package me.retucio.camtweaks.ui;
import me.retucio.camtweaks.event.SubscribeEvent;
import me.retucio.camtweaks.event.events.PacketEvent;
import me.retucio.camtweaks.module.ModuleManager;
import me.retucio.camtweaks.module.modules.Freecam;
import me.retucio.camtweaks.module.modules.HUD.TimeFormat;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.ChatScreen;
import net.minecraft.client.render.RenderTickCounter;
import net.minecraft.util.math.Vec3d;
import java.awt.Color;
import java.time.LocalTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
// en un principio esto iba a mostrar en pantalla los módulos activados, pero me parece innecesario. se queda aquí por si acaso
// igual lo uso para algo...
public class HUD {
private static final MinecraftClient mc = MinecraftClient.getInstance();
private long lastPacketTime = 0;
private static float estimatedTPS = 20f;
public static void render(DrawContext ctx, RenderTickCounter tc) {
if (ModuleManager.INSTANCE == null || mc.player == null || mc.cameraEntity == null) return;
me.retucio.camtweaks.module.modules.HUD hud = ModuleManager.INSTANCE.getModuleByClass(me.retucio.camtweaks.module.modules.HUD.class);
int width = mc.getWindow().getScaledWidth();
int height = mc.getWindow().getScaledHeight();
Color color;
if (hud.rainbow.isEnabled()) {
float speed = 10001 - hud.rainbowSpeed.getFloatValue();
float hue = (System.currentTimeMillis() % (int) speed) / speed;
Color gamning = Color.getHSBColor(hue, 1, 1);
color = new Color(gamning.getRed(), gamning.getGreen(), gamning.getBlue(), hud.alpha.getIntValue());
} else {
color = new Color(hud.red.getIntValue(), hud.green.getIntValue(), hud.blue.getIntValue(), hud.alpha.getIntValue());
}
boolean shadow = hud.shadow.isEnabled();
if (hud.isEnabled()) {
// coordenadas
if (hud.coords.isEnabled()) {
Vec3d coords;
Freecam freecam = ModuleManager.INSTANCE.getModuleByClass(Freecam.class);
if (freecam.isEnabled())
coords = new Vec3d(
freecam.getX(tc.getDynamicDeltaTicks()),
freecam.getY(tc.getDynamicDeltaTicks()),
freecam.getZ(tc.getDynamicDeltaTicks())
);
else
coords = mc.player.getPos();
String text = (int) coords.x + " " + (int) coords.y + " " + (int) coords.z;
ctx.drawText(mc.textRenderer, text,
width - mc.textRenderer.getWidth(text) - 2,
height - mc.textRenderer.fontHeight - 2,
color.getRGB(), shadow);
}
// fps y tps
if (hud.fps.isEnabled())
ctx.drawText(mc.textRenderer, "FPS: " + mc.getCurrentFps(), 2, 2, color.getRGB(), shadow);
if (hud.tps.isEnabled())
ctx.drawText(mc.textRenderer, "TPS: " + estimatedTPS, 2, 4 + mc.textRenderer.fontHeight, color.getRGB(), shadow);
// marca de agua
if (!hud.customText.getValue().isEmpty()) {
int y;
if (!mc.player.getActiveStatusEffects().isEmpty() && hud.dontOverride.isEnabled()) y = 26;
else y = 2;
ctx.drawText(mc.textRenderer, hud.customText.getValue(), width - mc.textRenderer.getWidth(hud.customText.getValue()) - 2, y, color.getRGB(), shadow);
}
// hora real
if (hud.time.isEnabled()) {
int y;
if (mc.currentScreen instanceof ChatScreen && hud.dontOverride.isEnabled()) y = height - mc.textRenderer.fontHeight - 14;
else y = height - mc.textRenderer.fontHeight - 2;
ZoneOffset offset = ZoneOffset.ofHours(hud.timezone.getIntValue());
LocalTime now = LocalTime.now(offset);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(hud.timeFormat.is(TimeFormat.TWENTY_FOUR_HOUR) ? "HH:mm" : "hh:mm a");
String time = now.format(formatter);
ctx.drawText(mc.textRenderer, time, 2, y, color.getRGB(), shadow);
}
}
}
@SubscribeEvent
public void onReceivePacket(PacketEvent.Receive event) {
// estimar el tps teniendo en cuenta el tiempo entre paquetes
long now = System.currentTimeMillis();
if (lastPacketTime > 0) {
long diff = now - lastPacketTime; // ms entre paquetes
float tps = 1000f / diff;
estimatedTPS = Math.min(20.0f, tps);
}
lastPacketTime = now;
}
}
@@ -0,0 +1,204 @@
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 net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.ChatScreen;
import net.minecraft.client.gui.screen.TitleScreen;
import net.minecraft.client.render.RenderTickCounter;
import net.minecraft.util.math.Vec3d;
import java.awt.*;
import java.time.LocalTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class HudRenderer {
private static final MinecraftClient mc = MinecraftClient.getInstance();
private static float estimatedTPS = 20f;
private long lastPacketTime = 0;
private static final Map<String, int[]> positions = ConfigManager.getConfig().hudPositions;
private static final Map<String, Boolean> visibilities = ConfigManager.getConfig().hudVisibilities;
private static final List<HudElement> elements = new ArrayList<>();
private static boolean initialized = false;
private static HudElement customTextElement = null;
public static void initElements() {
if (initialized) return;
initialized = true;
HUD hud = ModuleManager.INSTANCE.getModuleByClass(HUD.class);
// coordenadas
addElement("coords", 2, mc.getWindow().getScaledHeight() - mc.textRenderer.fontHeight, (ctx, mx, my, delta) -> {
drawSnappedText(ctx, getElementText("coords", delta, hud), mx, my, getColor(hud).getRGB(), hud.shadow.isEnabled());
});
// FPS
addElement("fps", 2, 2, (ctx, mx, my, delta) -> {
drawSnappedText(ctx, getElementText("fps", 0, hud), mx, my, getColor(hud).getRGB(), hud.shadow.isEnabled());
});
// TPS
addElement("tps", 2, mc.textRenderer.fontHeight + 4, (ctx, mx, my, delta) -> {
drawSnappedText(ctx, getElementText("tps", delta, hud), mx, my, getColor(hud).getRGB(), hud.shadow.isEnabled());
});
// texto custom
addElement("customText", mc.getWindow().getScaledWidth() / 2 - mc.textRenderer.getWidth(getElementText("customText", 0, ModuleManager.INSTANCE.getModuleByClass(HUD.class))) / 2, 2, (ctx, mx, my, delta) -> {
drawSnappedText(ctx, getElementText("customText", delta, hud), mx, my, getColor(hud).getRGB(), hud.shadow.isEnabled());
});
customTextElement = elements.stream()
.filter(e -> e.getId().equals("customText"))
.findFirst()
.orElse(null);
// hora
addElement("time", mc.getWindow().getScaledWidth() - mc.textRenderer.getWidth("04:20"), mc.getWindow().getScaledHeight() - mc.textRenderer.fontHeight - 2, (ctx, mx, my, delta) -> {
drawSnappedText(ctx, getElementText("time", delta, hud), mx, my, getColor(hud).getRGB(), hud.shadow.isEnabled());
});
HudEditorScreen.INSTANCE.setElements(getElements());
}
private static void addElement(String id, int defX, int defY, HudElement.Renderer renderer) {
int[] saved = positions.get(id);
Boolean visible = visibilities.get(id);
int x = saved == null ? defX : saved[0];
int y = saved == null ? defY : saved[1];
boolean v = visible == null || visible;
if (visibilities.isEmpty()) v = true;
elements.add(new HudElement(id, defX, defY, x, y, v) {
@Override public void render(DrawContext ctx, int mx, int my, float delta) {
renderer.render(ctx, x, y, delta);
}
});
}
public static Color getColor(HUD hud) {
if (hud.rainbow.isEnabled()) {
float speed = 10001 - hud.rainbowSpeed.getFloatValue();
float hue = (System.currentTimeMillis() % (int) speed) / speed;
Color rgb = Color.getHSBColor(hue, 1, 1);
return new Color(rgb.getRed(), rgb.getGreen(), rgb.getBlue(), hud.alpha.getIntValue());
}
return new Color(hud.red.getIntValue(), hud.green.getIntValue(), hud.blue.getIntValue(), hud.alpha.getIntValue());
}
public static void drawSnappedText(DrawContext ctx, String text, int x, int y, int color, boolean shadow) {
int textWidth = mc.textRenderer.getWidth(text);
int screenWidth = mc.getWindow().getScaledWidth();
int screenHeight = mc.getWindow().getScaledHeight();
boolean snapRight = x > screenWidth / 2;
int drawX = snapRight ? x + (textWidth + 2) - textWidth : x;
// clampear y
y = Math.max(0, Math.min(y, screenHeight - mc.textRenderer.fontHeight));
// clampear x
drawX = Math.max(0, Math.min(drawX, screenWidth - textWidth));
ctx.drawText(mc.textRenderer, text, drawX, y, color, shadow);
}
public static void render(DrawContext ctx, RenderTickCounter tc) {
if (ModuleManager.INSTANCE == null
|| mc.player == null
|| mc.getCameraEntity() == null
|| mc.currentScreen instanceof TitleScreen
|| mc.options.hudHidden)
return;
HUD hud = ModuleManager.INSTANCE.getModuleByClass(HUD.class);
if (!hud.isEnabled()) return;
if (mc.getDebugHud().shouldShowDebugHud() && !hud.showOnF3.isEnabled()) return;
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 "TPS: " + estimatedTPS;
}
case "customText" -> {
return ModuleManager.INSTANCE.getModuleByClass(HUD.class).customText.getValue();
}
case "time" -> {
ZoneOffset offset = ZoneOffset.ofHours(hud.timezone.getIntValue());
LocalTime now = LocalTime.now(offset);
boolean is24 = hud.timeFormat.is(HUD.TimeFormat.TWENTY_FOUR_HOUR);
DateTimeFormatter format = DateTimeFormatter.ofPattern(is24 ? "HH:mm" : "hh:mm a");
return now.format(format);
}
default -> { return id; }
}
}
@SubscribeEvent
public void onReceivePacket(PacketEvent.Receive event) {
long now = System.currentTimeMillis();
if (lastPacketTime > 0) {
float tps = 1000f / (now - lastPacketTime);
estimatedTPS = Math.min(20f, tps);
}
lastPacketTime = now;
}
/** para cuando se cambie el valor del texto custom */
@SubscribeEvent
public void onUpdateSetting(UpdateSettingEvent event) {
HUD hud = ModuleManager.INSTANCE.getModuleByClass(HUD.class);
if (event.getSetting() == hud.customText) {
if (customTextElement != null) {
int newX = mc.getWindow().getScaledWidth() / 2 - mc.textRenderer.getWidth(hud.customText.getValue()) / 2;
customTextElement.setX(newX);
}
}
}
}
@@ -1,15 +1,20 @@
package me.retucio.camtweaks.ui.buttons;
import me.retucio.camtweaks.module.settings.KeySetting;
import me.retucio.camtweaks.ui.ClickGUI;
import me.retucio.camtweaks.ui.screen.ClickGUI;
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.Colors;
import me.retucio.camtweaks.util.KeyUtil;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.text.Text;
import net.minecraft.client.input.KeyInput;
import net.minecraft.client.option.KeyBinding;
import net.minecraft.client.resource.language.I18n;
import net.minecraft.util.Formatting;
import org.lwjgl.glfw.GLFW;
import static me.retucio.camtweaks.CameraTweaks.mc;
// botón para configurar la tecla asignada a un módulo. comienza a escuchar al hacerle clic
public class BindButton extends SettingButton {
@@ -36,7 +41,7 @@ public class BindButton extends SettingButton {
public void mouseClicked(double mouseX, double mouseY, int button) {
if (isHovered((int) mouseX, (int) mouseY) && ClickGUI.INSTANCE.trySelect(this)) {
if (button == 0) listening = !listening;
else if (button == 1 && KeyUtil.isKeyDown(GLFW.GLFW_KEY_LEFT_SHIFT))
else if (button == 1 && mc.isShiftPressed())
setting.reset();
} else {
listening = false;
@@ -44,15 +49,29 @@ public class BindButton extends SettingButton {
}
public void onKey(int key, int action) {
if (listening && action == GLFW.GLFW_PRESS) {
if (key == GLFW.GLFW_KEY_ESCAPE)
setting.setKey(GLFW.GLFW_KEY_UNKNOWN);
else
setting.setKey(key);
listening = false;
if (!listening || action != GLFW.GLFW_PRESS) return;
if (key == GLFW.GLFW_KEY_ESCAPE) {
setting.setKey(GLFW.GLFW_KEY_UNKNOWN);
} else {
for (KeyBinding bind : mc.options.allKeys) {
boolean keyAlreadyBound = bind.matchesKey(new KeyInput(key, 0, 0));
boolean allowMultiple = ClientSettingsFrame.guiSettings.multipleKeybinds.isEnabled();
if (keyAlreadyBound && !allowMultiple) {
ChatUtil.warn("esa tecla ya está cogida por "
+ Formatting.GREEN + "\"" + I18n.translate(bind.getId()) + "\"");
listening = false;
return;
}
}
setting.setKey(key);
}
listening = false;
}
public boolean isFocused() {
return listening;
}
@@ -1,7 +1,7 @@
package me.retucio.camtweaks.ui.buttons;
import me.retucio.camtweaks.module.settings.EnumSetting;
import me.retucio.camtweaks.ui.ClickGUI;
import me.retucio.camtweaks.ui.screen.ClickGUI;
import me.retucio.camtweaks.ui.frames.SettingsFrame;
import me.retucio.camtweaks.util.Colors;
import me.retucio.camtweaks.util.KeyUtil;
@@ -14,6 +14,8 @@ import org.lwjgl.glfw.GLFW;
import java.util.ArrayList;
import java.util.List;
import static me.retucio.camtweaks.CameraTweaks.mc;
// botón para los ajustes tipo EnumSetting (de modo)
public class CycleButton<E extends Enum<E>> extends SettingButton {
@@ -42,7 +44,7 @@ public class CycleButton<E extends Enum<E>> extends SettingButton {
if (isHovered((int) mouseX, (int) mouseY)) {
Screen currentScreen = parent.mc.currentScreen;
if (currentScreen != null) {
if (KeyUtil.isKeyDown(GLFW.GLFW_KEY_LEFT_SHIFT)) {
if (mc.isShiftPressed()) {
List<Text> lines = new ArrayList<>();
lines.add(Text.literal("modos disponibles:"));
for (Enum<?> val : setting.getValues()) {
@@ -3,16 +3,16 @@ package me.retucio.camtweaks.ui.buttons;
import me.retucio.camtweaks.module.Module;
import me.retucio.camtweaks.module.settings.BooleanSetting;
import me.retucio.camtweaks.module.settings.ListSetting;
import me.retucio.camtweaks.ui.ClickGUI;
import me.retucio.camtweaks.ui.screen.ClickGUI;
import me.retucio.camtweaks.ui.frames.SettingsFrame;
import me.retucio.camtweaks.util.Colors;
import me.retucio.camtweaks.util.KeyUtil;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.text.Text;
import org.lwjgl.glfw.GLFW;
import java.util.*;
import static me.retucio.camtweaks.CameraTweaks.mc;
public class ListButton<T> extends SettingButton {
private final ListSetting<T> setting;
@@ -58,14 +58,14 @@ public class ListButton<T> extends SettingButton {
@Override
public void drawTooltip(DrawContext ctx, double mouseX, double mouseY) {
if (isHovered(mouseX, mouseY))
ctx.drawTooltip(Text.of(setting.getDescription() + "( " + countEnabled() + " de " + setting.getOptions().size() + ")"), (int) mouseX, (int) mouseY);
ctx.drawTooltip(Text.of(setting.getDescription() + " (" + countEnabled() + " de " + setting.getOptions().size() + ")"), (int) mouseX, (int) mouseY);
}
@Override
public void mouseClicked(double mouseX, double mouseY, int button) {
if (isHovered(mouseX, mouseY) && ClickGUI.INSTANCE.trySelect(this)) {
// click izquierdo / derecho: abrir marco
if (button <= 1 && !KeyUtil.isKeyDown(GLFW.GLFW_KEY_LEFT_SHIFT)) {
if (button <= 1 && !mc.isShiftPressed()) {
if (ClickGUI.INSTANCE.isSettingsFrameOpen(dummy)) {
ClickGUI.INSTANCE.closeSettingsFrame(dummy);
return;
@@ -74,7 +74,7 @@ public class ListButton<T> extends SettingButton {
rebuildDummy();
ClickGUI.INSTANCE.openListSettingsFrame(dummy, parent.x + 40, parent.y + 40);
// shift + clic derecho: restablecer valores
} else if (button == 1 && KeyUtil.isKeyDown(GLFW.GLFW_KEY_LEFT_SHIFT)) {
} else if (button == 1 && mc.isShiftPressed()) {
setting.reset();
refreshDummy();
}
@@ -1,11 +1,10 @@
package me.retucio.camtweaks.ui.buttons;
import me.retucio.camtweaks.module.Module;
import me.retucio.camtweaks.ui.ClickGUI;
import me.retucio.camtweaks.ui.screen.ClickGUI;
import me.retucio.camtweaks.ui.frames.ModuleFrame;
import me.retucio.camtweaks.util.Colors;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.text.Text;
// clase para el botón para cada módulo
@@ -1,10 +1,9 @@
package me.retucio.camtweaks.ui.buttons;
import me.retucio.camtweaks.module.settings.AbstractSetting;
import me.retucio.camtweaks.ui.ClickGUI;
import me.retucio.camtweaks.ui.screen.ClickGUI;
import me.retucio.camtweaks.ui.frames.SettingsFrame;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.text.Text;
// clase base para los botones de los ajustes
@@ -3,20 +3,18 @@ package me.retucio.camtweaks.ui.buttons;
import me.retucio.camtweaks.event.SubscribeEvent;
import me.retucio.camtweaks.event.events.KeyEvent;
import me.retucio.camtweaks.module.settings.NumberSetting;
import me.retucio.camtweaks.ui.ClickGUI;
import me.retucio.camtweaks.ui.screen.ClickGUI;
import me.retucio.camtweaks.ui.frames.ClientSettingsFrame;
import me.retucio.camtweaks.ui.frames.SettingsFrame;
import me.retucio.camtweaks.util.Colors;
import me.retucio.camtweaks.util.KeyUtil;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.text.Text;
import org.lwjgl.glfw.GLFW;
import java.awt.*;
import java.text.DecimalFormat;
import static me.retucio.camtweaks.CameraTweaks.EVENT_BUS;
import static me.retucio.camtweaks.CameraTweaks.mc;
// slider (barrita) para los ajustes numéricos
public class SliderButton extends SettingButton {
@@ -65,7 +63,7 @@ public class SliderButton extends SettingButton {
public void mouseClicked(double mouseX, double mouseY, int button) {
if (isHovered((int) mouseX, (int) mouseY) && ClickGUI.INSTANCE.trySelect(this)) {
if (button == 0) dragging = true; // arrastrar con el clic izquierdo
else if (button == 1 && KeyUtil.isKeyDown(GLFW.GLFW_KEY_LEFT_SHIFT)) // restablecer al valor por defecto con shift izquerdo + clic derecho
else if (button == 1 && mc.isShiftPressed()) // restablecer al valor por defecto con shift izquerdo + clic derecho
setting.reset();
}
}
@@ -78,7 +76,7 @@ public class SliderButton extends SettingButton {
@SubscribeEvent
public void onKey(KeyEvent event) {
// de no ser de esto, si se cierra la interfaz sin haber soltado el ratón mientras se arrastraba el valor, al reabrir la interfaz se seguía arrastrando, aún habiendo soltado ya el clic
// de no ser de esto, si se cierra la interfaz sin haber soltado el ratón mientras se arrastraba el valor, al reabrir la interfaz se seguía arrastrando, aún habiendo soltado ya el clic
if (event.getKey() == GLFW.GLFW_KEY_ESCAPE || event.getKey() == ClientSettingsFrame.guiSettings.getKey()) dragging = false;
}
@@ -1,12 +1,11 @@
package me.retucio.camtweaks.ui.buttons;
import me.retucio.camtweaks.module.settings.StringSetting;
import me.retucio.camtweaks.ui.ClickGUI;
import me.retucio.camtweaks.ui.screen.ClickGUI;
import me.retucio.camtweaks.ui.frames.SettingsFrame;
import me.retucio.camtweaks.util.Colors;
import me.retucio.camtweaks.util.KeyUtil;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.text.Text;
import org.lwjgl.glfw.GLFW;
import static me.retucio.camtweaks.CameraTweaks.mc;
@@ -42,7 +41,7 @@ public class TextButton extends SettingButton {
typing = true;
buffer.setLength(0);
buffer.append(setting.getValue()); // precargar valor anterior
} else if (button == 1 && KeyUtil.isKeyDown(GLFW.GLFW_KEY_LEFT_SHIFT)) {
} else if (button == 1 && mc.isShiftPressed()) {
typing = false;
setting.reset();
}
@@ -1,17 +1,15 @@
package me.retucio.camtweaks.ui.buttons;
import me.retucio.camtweaks.module.settings.BooleanSetting;
import me.retucio.camtweaks.ui.ClickGUI;
import me.retucio.camtweaks.ui.screen.ClickGUI;
import me.retucio.camtweaks.ui.frames.SettingsFrame;
import me.retucio.camtweaks.util.Colors;
import me.retucio.camtweaks.util.KeyUtil;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.text.Text;
import org.lwjgl.glfw.GLFW;
import java.awt.*;
import static me.retucio.camtweaks.CameraTweaks.mc;
// botón para los ajustes booleanos (funciona como un interruptor)
public class ToggleButton extends SettingButton {
@@ -39,7 +37,7 @@ public class ToggleButton extends SettingButton {
public void mouseClicked(double mouseX, double mouseY, int button) {
if (isHovered((int) mouseX, (int) mouseY) && ClickGUI.INSTANCE.trySelect(this)) {
if (button == 0) setting.toggle(); // clic izquierdo para alternar
else if (button == 1 && KeyUtil.isKeyDown(GLFW.GLFW_KEY_LEFT_SHIFT)) // shift izquierdo + clic derecho para restablecer al valor por defecto
else if (button == 1 && mc.isShiftPressed()) // shift izquierdo + clic derecho para restablecer al valor por defecto
setting.reset();
}
}
@@ -3,7 +3,7 @@ package me.retucio.camtweaks.ui.frames;
import me.retucio.camtweaks.CameraTweaks;
import me.retucio.camtweaks.event.events.camtweaks.GUISettingsFrameEvent;
import me.retucio.camtweaks.module.modules.GUI;
import me.retucio.camtweaks.ui.ClickGUI;
import me.retucio.camtweaks.ui.screen.ClickGUI;
import me.retucio.camtweaks.ui.buttons.SettingButton;
import me.retucio.camtweaks.util.Colors;
import net.minecraft.client.gui.DrawContext;
@@ -4,7 +4,7 @@ import me.retucio.camtweaks.CameraTweaks;
import me.retucio.camtweaks.event.events.camtweaks.ModuleFrameEvent;
import me.retucio.camtweaks.module.Module;
import me.retucio.camtweaks.module.ModuleManager;
import me.retucio.camtweaks.ui.ClickGUI;
import me.retucio.camtweaks.ui.screen.ClickGUI;
import me.retucio.camtweaks.ui.buttons.ModuleButton;
import me.retucio.camtweaks.util.Colors;
import net.minecraft.client.MinecraftClient;
@@ -4,7 +4,7 @@ import me.retucio.camtweaks.CameraTweaks;
import me.retucio.camtweaks.event.events.camtweaks.SettingsFrameEvent;
import me.retucio.camtweaks.module.Module;
import me.retucio.camtweaks.module.settings.*;
import me.retucio.camtweaks.ui.ClickGUI;
import me.retucio.camtweaks.ui.screen.ClickGUI;
import me.retucio.camtweaks.ui.buttons.*;
import me.retucio.camtweaks.ui.buttons.SliderButton;
import me.retucio.camtweaks.ui.buttons.TextButton;
@@ -1,4 +1,4 @@
package me.retucio.camtweaks.ui;
package me.retucio.camtweaks.ui.screen;
import me.retucio.camtweaks.CameraTweaks;
import me.retucio.camtweaks.event.SubscribeEvent;
@@ -15,12 +15,14 @@ import me.retucio.camtweaks.ui.frames.ModuleFrame;
import me.retucio.camtweaks.ui.frames.SettingsFrame;
import me.retucio.camtweaks.ui.widgets.ScrollBarWidget;
import me.retucio.camtweaks.ui.widgets.SearchBarWidget;
import me.retucio.camtweaks.util.ChatUtil;
import me.retucio.camtweaks.util.KeyUtil;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.Click;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.text.Text;
import org.lwjgl.glfw.GLFW;
import java.util.ArrayList;
@@ -93,35 +95,35 @@ public class ClickGUI extends Screen {
return bottom + 20; // padding
}
@Override
public boolean mouseClicked(double mouseX, double mouseY, int button) {
scrollBar.mouseClicked(mouseX, mouseY, button);
searchBar.mouseClicked(mouseX, mouseY, button);
public boolean mouseClicked(Click click, boolean doubled) {
scrollBar.mouseClicked(click.x(), click.y(), click.button());
searchBar.mouseClicked(click.x(), click.y(), click.button());
// detectar clics sobre los marcos
modulesFrame.mouseClicked(mouseX, mouseY, button);
modulesFrame.mouseClicked(click.x(), click.y(), click.button());
for (SettingsFrame sf : new ArrayList<>(settingsFrames))
sf.mouseClicked(mouseX, mouseY, button);
sf.mouseClicked(click.x(), click.y(), click.button());
return super.mouseClicked(mouseX, mouseY, button);
return super.mouseClicked(click, doubled);
}
@Override
public boolean mouseReleased(double mouseX, double mouseY, int button) {
scrollBar.mouseReleased(mouseX, mouseY, button);
searchBar.mouseReleased(mouseX, mouseY, button);
public boolean mouseReleased(Click click) {
scrollBar.mouseReleased(click.x(), click.y(), click.button());
searchBar.mouseReleased(click.x(), click.y(), click.button());
// registrar cuándo se suelta el clic, en cada marco respectivamente
modulesFrame.mouseReleased(mouseX, mouseY, button);
modulesFrame.mouseReleased(click.x(), click.y(), click.button());
for (SettingsFrame sf : new ArrayList<>(settingsFrames))
sf.mouseRelease(mouseX, mouseY, button);
return super.mouseReleased(mouseX, mouseY, button);
sf.mouseRelease(click.x(), click.y(), click.button());
return super.mouseReleased(click);
}
@Override
public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) {
scrollBar.mouseDragged(mouseY);
return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY);
public boolean mouseDragged(Click click, double deltaX, double deltaY) {
scrollBar.mouseDragged(click.y());
return super.mouseDragged(click, deltaX, deltaY);
}
@SubscribeEvent
@@ -247,8 +249,8 @@ public class ClickGUI extends Screen {
}
@Override
protected void applyBlur(DrawContext context) {
if (guiSettings.blur.isEnabled()) super.applyBlur(context);
protected void applyBlur(DrawContext ctx) {
if (guiSettings.blur.isEnabled()) super.applyBlur(ctx);
}
@@ -0,0 +1,213 @@
package me.retucio.camtweaks.ui.screen;
import me.retucio.camtweaks.config.ConfigManager;
import me.retucio.camtweaks.ui.frames.ClientSettingsFrame;
import me.retucio.camtweaks.ui.widgets.HudElement;
import me.retucio.camtweaks.util.Colors;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.Click;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.input.KeyInput;
import net.minecraft.text.Text;
import org.lwjgl.glfw.GLFW;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
public class HudEditorScreen extends Screen {
public static HudEditorScreen INSTANCE;
private final MinecraftClient mc = MinecraftClient.getInstance();
private final List<HudElement> elements = new ArrayList<>();
@Nullable private HudElement selected = null;
private boolean dragging = false;
private int dragOffsetX, dragOffsetY;
public HudEditorScreen() {
super(Text.literal("editor del hud"));
}
public void setElements(List<HudElement> elements) {
this.elements.clear();
this.elements.addAll(elements);
}
@Override
public void render(DrawContext ctx, int mouseX, int mouseY, float delta) {
ctx.fill(0, 0, this.width, this.height, Colors.hudEditorScreenBackgroundColor.getRGB());
// texto con instrucciones
ctx.drawCenteredTextWithShadow(mc.textRenderer, "EDITOR DEL HUD", this.width / 2, this.height / 2 - mc.textRenderer.fontHeight, -1);
ctx.drawCenteredTextWithShadow(mc.textRenderer,
Text.literal("arrastrar para mover · click derecho para alternar visibilidad · esc para guardar y salir · shift + click derecho para restablecer"),
this.width / 2, this.height / 2 + mc.textRenderer.fontHeight, Colors.instructionsTextColor.getRGB());
// dibujar elementos
for (HudElement element : elements)
element.renderPreview(ctx);
// tooltips con información sobre el elemento sobre el que está el puntero del ratón
if (!dragging) {
for (HudElement element : elements) {
if (!element.isVisible()) continue;
if (element.contains(mouseX, mouseY)) {
List<Text> tooltip = getTooltipFor(element);
if (!tooltip.isEmpty()) ctx.drawTooltip(mc.textRenderer, tooltip, mouseX + 7, mouseY + 20);
break;
}
}
}
super.render(ctx, mouseX, mouseY, delta);
}
@Override
public boolean mouseClicked(Click click, boolean doubled) {
int mouseX = (int) click.x();
int mouseY = (int) click.y();
// iterar de atrás a adelante para respetar el orden z
for (int i = elements.size() - 1; i >= 0; i--) {
HudElement element = elements.get(i);
if (element.contains(mouseX, mouseY)) {
selected = element;
if (click.button() == 0) {
dragging = true;
dragOffsetX = mouseX - element.getX();
dragOffsetY = mouseY - element.getY();
// traer el elemento seleccionado al frente
elements.remove(i);
elements.add(element);
return true;
} else if (click.button() == 1) {
if (mc.isShiftPressed())
selected.resetPosition();
else
selected.setVisible(!selected.isVisible());
return true;
}
}
}
return super.mouseClicked(click, doubled);
}
@Override
public boolean mouseDragged(Click click, double deltaX, double deltaY) {
if (!dragging || selected == null || click.button() != 0)
return super.mouseDragged(click, deltaX, deltaY);
int mouseX = (int) click.x();
int mouseY = (int) click.y();
int newX = mouseX - dragOffsetX;
int newY = mouseY - dragOffsetY;
// clampear para evitar que los elementos se salgan de la pantalla
newX = Math.max(1, Math.min(newX, width - selected.getWidth() - 1));
newY = Math.max(1, Math.min(newY, height - selected.getHeight() - 1));
selected.setPosition(newX, newY);
return true;
}
@Override
public boolean mouseReleased(Click click) {
if (dragging && click.button() == 0) {
dragging = false;
savePositionsToConfig(); // guardar inmediatamente al config
return true;
} else if (click.button() == 1 && selected != null) {
saveVisibilitiesToConfig();
selected = null;
return true;
}
selected = null;
return super.mouseReleased(click);
}
@Override
public boolean keyPressed(KeyInput input) {
// esc para guardar y salir
if (input.key() == GLFW.GLFW_KEY_ESCAPE) {
saveAndClose();
return true;
}
return super.keyPressed(input);
}
private void savePositionsToConfig() {
for (HudElement element : elements)
ConfigManager.setHudPosition(element.getId(), element.getX(), element.getY());
ConfigManager.save();
}
private void saveVisibilitiesToConfig() {
for (HudElement element : elements)
ConfigManager.setHudVisibility(element.getId(), element.isVisible());
ConfigManager.save();
}
private void saveAndClose() {
savePositionsToConfig();
selected = null;
mc.setScreen(null);
}
@Override
protected void applyBlur(DrawContext ctx) {
if (ClientSettingsFrame.guiSettings.blur.isEnabled()) super.applyBlur(ctx);
}
public boolean isSelected(HudElement element) {
return selected == element;
}
// para los tooltips
private List<Text> getTooltipFor(HudElement element) {
List<Text> list = new ArrayList<>();
switch (element.getId()) {
case "coords" -> {
list.add(Text.literal("coordenadas"));
list.add(Text.literal("te muestra tu posición en el mundo en coordenadas XYZ"));
}
case "fps" -> {
list.add(Text.literal("FPS"));
list.add(Text.literal("te muestra la tasa de fotogramas por segundo del juego"));
}
case "tps" -> {
list.add(Text.literal("tps"));
list.add(Text.literal("te muestra la tasa de ticks por segundo del servidor (0-20)"));
}
case "customText" -> {
list.add(Text.literal("texto custom"));
list.add(Text.literal("te permite renderizar texto al gusto"));
}
case "time" -> {
list.add(Text.literal("hora"));
list.add(Text.literal("te muestra la hora y los minutos de la zona horaria escogida"));
}
default -> {
list.add(Text.literal(element.getId()));
list.add(Text.literal("."));
}
}
return list;
}
}
@@ -0,0 +1,112 @@
package me.retucio.camtweaks.ui.screen;
import me.retucio.camtweaks.CameraTweaks;
import me.retucio.camtweaks.module.modules.ShulkerPeek;
import me.retucio.camtweaks.ui.frames.ClientSettingsFrame;
import me.retucio.camtweaks.util.Colors;
import net.minecraft.client.gl.RenderPipelines;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.component.DataComponentTypes;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
import java.awt.*;
import java.util.List;
// https://github.com/kgriff0n/shulker-preview/blob/master/src/main/java/io/github/kgriff0n/screen/FakeShulkerScreen.java
public class ShulkerPreviewScreen extends Screen {
private static final Identifier TEXTURE = Identifier.of(CameraTweaks.MOD_ID, "textures/gui/shulker.png");
private int x, y;
private final int bgWidth = 176;
private final int bgHeight = 78;
private final Color color;
private final Text title;
private final List<ItemStack> inventory;
private final Screen parent;
public ShulkerPreviewScreen(ItemStack shulker, Screen parent) {
super(Text.literal("previsualización del shulker"));
this.color = ShulkerPeek.SHULKER_COLORS.get(shulker.getItem());
this.title = shulker.getName();
this.inventory = shulker.get(DataComponentTypes.CONTAINER).stream().toList();
this.parent = parent;
}
@Override
protected void init() {
this.x = (width - bgWidth) / 2;
this.y = (height - bgHeight) / 2;
}
@Override
public void render(DrawContext ctx, int mouseX, int mouseY, float delta) {
super.render(ctx, mouseX, mouseY, delta);
this.renderBackground(ctx, mouseX, mouseY, delta);
this.renderItems(ctx, inventory, x + 8, y + 18);
int selectedSlot = getSlot(mouseX, mouseY);
if (selectedSlot > -1 && selectedSlot < inventory.size() && !inventory.get(selectedSlot).isOf(Items.AIR))
renderTooltip(ctx, inventory.get(selectedSlot), mouseX, mouseY);
}
@Override
public void renderBackground(DrawContext ctx, int mouseX, int mouseY, float delta) {
ctx.fill(0, 0, width, height, Colors.hudEditorScreenBackgroundColor.getRGB());
ctx.drawTexture(RenderPipelines.GUI_TEXTURED, TEXTURE, x, y, 0, 0, bgWidth, bgHeight, 256, 256, color.getRGB());
ctx.drawText(textRenderer, title, x + 8, y + 6, Colors.instructionsTextColor.getRGB(), false);
}
private void renderItems(DrawContext context, List<ItemStack> inventory, int x, int y) {
int baseX = x;
int count = 0;
for (ItemStack item : inventory) {
count++;
context.drawItem(item, x, y);
context.drawStackOverlay(textRenderer, item, x, y);
x += 18;
if (count % 9 == 0) {
x = baseX;
y += 18;
}
}
}
private int getSlot(int i, int j) {
int x = this.x + 7;
int y = this.y + 17;
int slotX = (i - x) / 18;
int slotY = (j - y) / 18;
if (i < x || j < y || i > x + 9 * 18 - 1 || j > y + 3 * 18 - 1)
return -1;
return slotX + slotY * 9;
}
private void renderTooltip(DrawContext ctx, ItemStack stack, int x, int y) {
ctx.drawItemTooltip(textRenderer, stack, x, y);
}
@Override
public void close() {
client.setScreen(parent);
}
@Override
public void applyBlur(DrawContext ctx) {
if (ClientSettingsFrame.guiSettings.blur.isEnabled()) super.applyBlur(ctx);
}
@Override
public boolean shouldPause() {
return false;
}
}
@@ -0,0 +1,139 @@
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";
}
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);
}
}
@@ -1,6 +1,6 @@
package me.retucio.camtweaks.ui.widgets;
import me.retucio.camtweaks.ui.ClickGUI;
import me.retucio.camtweaks.ui.screen.ClickGUI;
import me.retucio.camtweaks.ui.frames.ClientSettingsFrame;
import me.retucio.camtweaks.util.Colors;
import net.minecraft.client.MinecraftClient;
@@ -1,8 +1,7 @@
package me.retucio.camtweaks.ui.widgets;
import me.retucio.camtweaks.ui.ClickGUI;
import me.retucio.camtweaks.ui.screen.ClickGUI;
import me.retucio.camtweaks.ui.frames.ClientSettingsFrame;
import me.retucio.camtweaks.util.ChatUtil;
import me.retucio.camtweaks.util.Colors;
import me.retucio.camtweaks.util.KeyUtil;
import net.minecraft.client.MinecraftClient;
@@ -56,7 +55,7 @@ public class SearchBarWidget {
ctx.drawHorizontalLine(x + 4, x + 16, renderY + 3 * i + 5, Color.LIGHT_GRAY.getRGB());
// texto
Text label = Text.literal(focused ? buffer + "_" : (buffer.isEmpty() ? Formatting.ITALIC + "buscar..." : buffer.toString()));
Text label = Text.literal(focused ? buffer + "_" : (buffer.isEmpty() ? Formatting.ITALIC + "\uD83D\uDD0D buscar..." : buffer.toString()));
ctx.drawText(mc.textRenderer, label,
x + 24, renderY + h / 2 - mc.textRenderer.fontHeight / 2,
(buffer.isEmpty() && !focused) ? Color.LIGHT_GRAY.getRGB() : -1, true);
@@ -19,8 +19,14 @@ public class Colors {
public static Color mainColor;
public static Color frameBGColor = new Color(40, 40, 40, 75);
public static Color buttonColor = new Color(75, 75, 75, 100);
public static Color hudEditorScreenBackgroundColor = new Color(0, 0, 0, 120);
public static Color instructionsTextColor = new Color(190, 190, 190, 255);
public static Color enabledToggleButtonColor;
public static Color disabledToggleButtonColor;
public static Color visibleHudElementColor;
public static Color disabledHudElementColor;
public static Color selectedHudElementOutlineColor;
public static Color unselectedHudElementOutlineColor;
static {
updateAllColors(new Color(red, green, blue, alpha));
@@ -31,6 +37,23 @@ public class Colors {
enabledToggleButtonColor = mixWithMainColor(new Color(10, 150, 10), 0.8f);
disabledToggleButtonColor = mixWithMainColor(new Color(150, 10, 10), 0.8f);
selectedHudElementOutlineColor = color;
unselectedHudElementOutlineColor = color.darker().darker();
visibleHudElementColor = new Color(
enabledToggleButtonColor.getRed(),
enabledToggleButtonColor.getGreen(),
enabledToggleButtonColor.getBlue(),
enabledToggleButtonColor.getAlpha() / 2
);
disabledHudElementColor = new Color(
disabledToggleButtonColor.getRed(),
disabledToggleButtonColor.getGreen(),
disabledToggleButtonColor.getBlue(),
disabledToggleButtonColor.getAlpha() / 2
);
ChatUtil.updatePrefix(ChatUtil.getJustPrefix());
}
@@ -44,10 +44,12 @@ public class KeyUtil {
case GLFW.GLFW_KEY_DOWN -> "abajo";
case GLFW.GLFW_KEY_LEFT -> "izquierda";
case GLFW.GLFW_KEY_RIGHT -> "derecha";
default -> { // F1–F25
case GLFW.GLFW_KEY_PAGE_UP -> "pág. arriba";
case GLFW.GLFW_KEY_PAGE_DOWN -> "pág. abajo";
default -> {
if (key >= GLFW.GLFW_KEY_F1 && key <= GLFW.GLFW_KEY_F25)
yield "F" + (key - GLFW.GLFW_KEY_F1 + 1);
yield "tecla " + key;
yield "F" + (key - GLFW.GLFW_KEY_F1 + 1); // F1–F25
yield "tecla " + key; // fallback
}
};
}
@@ -4,6 +4,7 @@ import net.minecraft.block.Block;
import net.minecraft.client.particle.Particle;
import net.minecraft.client.resource.language.I18n;
import net.minecraft.entity.EntityType;
import net.minecraft.item.Item;
import net.minecraft.particle.ParticleType;
import net.minecraft.particle.ParticleTypes;
import net.minecraft.registry.Registries;
@@ -18,10 +19,12 @@ public class Lists {
public static final List<EntityType<?>> entityList = Registries.ENTITY_TYPE.stream().toList();
public static Map<EntityType<?>, String> entityNames;
public static final List<ParticleType<?>> particleList = Registries.PARTICLE_TYPE.stream().toList();
public static Map<ParticleType<?>, String> particleNames;
public static final List<Item> itemList = Registries.ITEM.stream().toList();
public static Map<Item, String> itemNames;
public static final List<Block> blockList = Registries.BLOCK.stream().toList();
public static void init() {
@@ -32,6 +35,9 @@ public class Lists {
// 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());
itemNames = getMapOfLists(itemList,
itemList.stream().map(item -> I18n.translate(item.getTranslationKey())).toList());
}
public static <T> Map<T, Boolean> allTrue(List<T> options) {
@@ -0,0 +1,42 @@
package me.retucio.camtweaks.util.render;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.render.RenderPhase;
import net.minecraft.util.Util;
import java.util.OptionalDouble;
import java.util.function.Function;
import static me.retucio.camtweaks.util.render.Pipelines.GLOBAL_LINES_PIPELINE;
import static me.retucio.camtweaks.util.render.Pipelines.GLOBAL_QUADS_PIPELINE;
public class Layers {
private static final RenderLayer GLOBAL_QUADS;
private static final Function<Double, RenderLayer> GLOBAL_LINES;
public static RenderLayer getGlobalLines(double width) {
return GLOBAL_LINES.apply(width);
}
public static RenderLayer getGlobalQuads() {
return GLOBAL_QUADS;
}
private static RenderLayer.MultiPhaseParameters.Builder builder() {
return RenderLayer.MultiPhaseParameters.builder();
}
private static RenderLayer.MultiPhaseParameters empty() {
return builder().build(false);
}
static {
GLOBAL_QUADS = RenderLayer.of("global_fill", 156, GLOBAL_QUADS_PIPELINE, empty());
GLOBAL_LINES = Util.memoize(l -> {
RenderPhase.LineWidth width = new RenderPhase.LineWidth(OptionalDouble.of(l));
return RenderLayer.of("global_lines", 156, GLOBAL_LINES_PIPELINE, builder().lineWidth(width).build(false));
});
}
}
@@ -0,0 +1,52 @@
package me.retucio.camtweaks.util.render;
import com.mojang.blaze3d.pipeline.BlendFunction;
import com.mojang.blaze3d.pipeline.RenderPipeline;
import com.mojang.blaze3d.platform.DepthTestFunction;
import com.mojang.blaze3d.vertex.VertexFormat;
import me.retucio.camtweaks.CameraTweaks;
import net.minecraft.client.gl.RenderPipelines;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.render.RenderPhase;
import net.minecraft.client.render.VertexFormats;
import net.minecraft.util.Identifier;
import net.minecraft.util.Util;
import java.util.OptionalDouble;
import java.util.function.Function;
public class Pipelines {
static final RenderPipeline GLOBAL_LINES_PIPELINE = RenderPipeline.builder(RenderPipelines.RENDERTYPE_LINES_SNIPPET)
.withLocation(Identifier.of(CameraTweaks.MOD_ID, "pipeline/global_lines"))
.withVertexFormat(VertexFormats.POSITION_COLOR_NORMAL, VertexFormat.DrawMode.LINES)
.withDepthTestFunction(DepthTestFunction.NO_DEPTH_TEST)
.withDepthWrite(false)
.withCull(false)
.build();
static final RenderPipeline GLOBAL_QUADS_PIPELINE = RenderPipeline.builder(RenderPipelines.POSITION_COLOR_SNIPPET)
.withLocation("pipeline/global_fill_pipeline")
.withVertexFormat(VertexFormats.POSITION_COLOR, VertexFormat.DrawMode.QUADS)
.withDepthTestFunction(DepthTestFunction.NO_DEPTH_TEST)
.withBlend(BlendFunction.TRANSLUCENT)
.withDepthWrite(false)
.withCull(false)
.build();
static final Function<Double, RenderLayer> GLOBAL_LINES_LAYER = Util.memoize(lineWidth -> {
RenderPhase.LineWidth lineState = new RenderPhase.LineWidth(OptionalDouble.of(lineWidth));
RenderLayer.MultiPhaseParameters compositeState = RenderLayer.MultiPhaseParameters.builder()
.lineWidth(lineState)
.build(false);
return RenderLayer.of("global_lines", RenderLayer.DEFAULT_BUFFER_SIZE, GLOBAL_LINES_PIPELINE, compositeState);
});
public static RenderLayer getGlobalLinesLayer(double lineWidth) {
return GLOBAL_LINES_LAYER.apply(lineWidth);
}
}
@@ -0,0 +1,82 @@
package me.retucio.camtweaks.util.render;
import com.mojang.blaze3d.vertex.VertexFormat;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.*;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.Vec3d;
import java.awt.*;
// literalmente robado de https://github.com/mioclient/oyvey-ported/ (perdón)
public class RenderUtil {
private static final MinecraftClient mc = MinecraftClient.getInstance();
private static final Tessellator tesselator = Tessellator.getInstance();
public static void drawOutlineBox(MatrixStack stack, Box box, Color color, double lineWidth) {
float r = color.getRed() / 255f;
float g = color.getGreen() / 255f;
float b = color.getBlue() / 255f;
float a = color.getAlpha() / 255f;
Vec3d cameraPos = mc.gameRenderer.getCamera().getPos();
float minX = (float) (box.minX - cameraPos.x);
float minY = (float) (box.minY - cameraPos.y);
float minZ = (float) (box.minZ - cameraPos.z);
float maxX = (float) (box.maxX - cameraPos.x);
float maxY = (float) (box.maxY - cameraPos.y);
float maxZ = (float) (box.maxZ - cameraPos.z);
BufferBuilder buffer = tesselator.begin(VertexFormat.DrawMode.LINES, VertexFormats.POSITION_COLOR_NORMAL);
VertexRendering.drawBox(stack.peek(), buffer, minX, minY, minZ, maxX, maxY, maxZ, r, g, b, a);
Layers.getGlobalLines(lineWidth).draw(buffer.end());
}
public static void drawFilledBox(MatrixStack matrices, Box box, Color color) {
Vec3d cameraPos = mc.gameRenderer.getCamera().getPos();
float minX = (float) (box.minX - cameraPos.x);
float minY = (float) (box.minY - cameraPos.y);
float minZ = (float) (box.minZ - cameraPos.z);
float maxX = (float) (box.maxX - cameraPos.x);
float maxY = (float) (box.maxY - cameraPos.y);
float maxZ = (float) (box.maxZ - cameraPos.z);
BufferBuilder buffer = tesselator.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_COLOR);
buffer.vertex(matrices.peek().getPositionMatrix(), minX, minY, minZ).color(color.getRGB());
buffer.vertex(matrices.peek().getPositionMatrix(), maxX, minY, minZ).color(color.getRGB());
buffer.vertex(matrices.peek().getPositionMatrix(), maxX, minY, maxZ).color(color.getRGB());
buffer.vertex(matrices.peek().getPositionMatrix(), minX, minY, maxZ).color(color.getRGB());
buffer.vertex(matrices.peek().getPositionMatrix(), minX, maxY, minZ).color(color.getRGB());
buffer.vertex(matrices.peek().getPositionMatrix(), minX, maxY, maxZ).color(color.getRGB());
buffer.vertex(matrices.peek().getPositionMatrix(), maxX, maxY, maxZ).color(color.getRGB());
buffer.vertex(matrices.peek().getPositionMatrix(), maxX, maxY, minZ).color(color.getRGB());
buffer.vertex(matrices.peek().getPositionMatrix(), minX, minY, minZ).color(color.getRGB());
buffer.vertex(matrices.peek().getPositionMatrix(), minX, maxY, minZ).color(color.getRGB());
buffer.vertex(matrices.peek().getPositionMatrix(), maxX, maxY, minZ).color(color.getRGB());
buffer.vertex(matrices.peek().getPositionMatrix(), maxX, minY, minZ).color(color.getRGB());
buffer.vertex(matrices.peek().getPositionMatrix(), maxX, minY, minZ).color(color.getRGB());
buffer.vertex(matrices.peek().getPositionMatrix(), maxX, maxY, minZ).color(color.getRGB());
buffer.vertex(matrices.peek().getPositionMatrix(), maxX, maxY, maxZ).color(color.getRGB());
buffer.vertex(matrices.peek().getPositionMatrix(), maxX, minY, maxZ).color(color.getRGB());
buffer.vertex(matrices.peek().getPositionMatrix(), minX, minY, maxZ).color(color.getRGB());
buffer.vertex(matrices.peek().getPositionMatrix(), maxX, minY, maxZ).color(color.getRGB());
buffer.vertex(matrices.peek().getPositionMatrix(), maxX, maxY, maxZ).color(color.getRGB());
buffer.vertex(matrices.peek().getPositionMatrix(), minX, maxY, maxZ).color(color.getRGB());
buffer.vertex(matrices.peek().getPositionMatrix(), minX, minY, minZ).color(color.getRGB());
buffer.vertex(matrices.peek().getPositionMatrix(), minX, minY, maxZ).color(color.getRGB());
buffer.vertex(matrices.peek().getPositionMatrix(), minX, maxY, maxZ).color(color.getRGB());
buffer.vertex(matrices.peek().getPositionMatrix(), minX, maxY, minZ).color(color.getRGB());
Layers.getGlobalQuads().draw(buffer.end());
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

+6 -2
View File
@@ -2,8 +2,12 @@ accessWidener v2 named
accessible class net/minecraft/client/font/TextRenderer$Drawer
accessible field net/minecraft/client/particle/Particle alpha F
accessible field net/minecraft/client/particle/BillboardParticle alpha F
accessible field net/minecraft/client/particle/BillboardParticle scale F
accessible field net/minecraft/client/particle/Particle velocityMultiplier F
accessible field net/minecraft/client/particle/Particle gravityStrength F
accessible field net/minecraft/client/particle/Particle collidesWithWorld Z
accessible field net/minecraft/client/particle/Particle collidesWithWorld Z
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
+7 -2
View File
@@ -5,13 +5,13 @@
"mixins": [
"ClientConnectionMixin",
"DimensionTypeMixin",
"EntityEffectParticleEffectMixin",
"EntityMixin",
"ItemEntityMixin",
"KeyInputMixin",
"PlayerEntityMixin",
"StringHelperMixin",
"Vec3dMixin",
"YggdrasilUserApiServiceMixin",
"accessor.StatusEffectInstanceAccessor"
],
"injectors": {
@@ -30,10 +30,11 @@
"ChatScreenMixin",
"ChunkBorderDebugRendererMixin",
"ChunkOcclusionDataBuilderMixin",
"ClientPlayerEntityMixin",
"ClientPlayerInteractionManagerMixin",
"ClientPlayNetworkHandlerMixin",
"ClientWorldMixin",
"ClientWorldPropertiesMixin",
"CompassStateMixin",
"DamageParticleFactoryMixin",
"DamageParticleMixin",
"FogRendererMixin",
@@ -54,10 +55,14 @@
"ScreenshotRecorderMixin",
"SkyRendererMixin",
"StuckArrowsFeatureRendererMixin",
"TelemetryManagerMixin",
"TextRendererDrawerMixin",
"TextRendererMixin",
"TitleScreenMixin",
"WeatherRenderingMixin",
"WorldRendererMixin",
"accessor.ClientPlayNetworkHandlerAccessor",
"accessor.HandledScreenAccessor",
"accessor.KeyBindingAccessor"
]
}
+3 -5
View File
@@ -25,12 +25,10 @@
],
"accessWidener": "camtweaks.accesswidener",
"depends": {
"fabricloader": ">=0.16.14",
"minecraft": "~1.21.6",
"fabricloader": ">=0.17.3",
"minecraft": "~1.21.10",
"java": ">=21",
"fabric-api": "*"
},
"suggests": {
"another-mod": "*"
}
"suggests": {}
}