This commit is contained in:
retuci0 committed 2026-05-09 20:55:38 +02:00
1 parent b2bc2b36ab
commit 321505657c
30 files changed
+389 -259

No files matched your search

+7 -3
View File
@@ -1,15 +1,19 @@
# v5.0!!! # v5.1
## novedades ## novedades
### adiciones ### adiciones
- panel individual para cada categoría de módulos
#### módulos nuevos: #### módulos nuevos:
### arreglos / mejoras ### arreglos / mejoras
- añadido el grupo de ajustes `módulo` para distinguir los ajustes individuales de cada módulo con los comunes;
y añadido la opción de notificar el alternado de estado de un módulo mediante widgets de notificaciones
- varios arreglos relacionados con la config.
- cambiado `manos` de categoría: de "jugador" a "renderizado"
- `don quijote` ya funciona correctamente, en cuanto a los amigos
## problemas reconocidos ## problemas reconocidos
- lo de siempre. - lo de siempre.
+1 -1
View File
@@ -10,6 +10,6 @@ discord_rpc_version=1.0.3
neutrino_version=1.1.0 neutrino_version=1.1.0
jdk_version=25 jdk_version=25
mod_version=5.0 mod_version=5.1
maven_group=me.retucio maven_group=me.retucio
archives_base_name=sputnik archives_base_name=sputnik
@@ -24,7 +24,6 @@ import me.retucio.sputnik.ui.screen.UpdateScreen;
import me.retucio.sputnik.ui.widgets.buttons.settings.BindButton; import me.retucio.sputnik.ui.widgets.buttons.settings.BindButton;
import me.retucio.sputnik.ui.widgets.buttons.SettingButton; import me.retucio.sputnik.ui.widgets.buttons.SettingButton;
import me.retucio.sputnik.ui.widgets.buttons.settings.TextButton; import me.retucio.sputnik.ui.widgets.buttons.settings.TextButton;
import me.retucio.sputnik.ui.widgets.misc.NotificationWidget;
import me.retucio.sputnik.ui.widgets.panels.settings.ClientSettingsPanel; import me.retucio.sputnik.ui.widgets.panels.settings.ClientSettingsPanel;
import me.retucio.sputnik.ui.widgets.panels.SettingsPanel; import me.retucio.sputnik.ui.widgets.panels.SettingsPanel;
import me.retucio.sputnik.ui.widgets.Button; import me.retucio.sputnik.ui.widgets.Button;
@@ -56,8 +55,9 @@ import org.lwjgl.glfw.GLFW;
public class Sputnik implements ClientModInitializer { public class Sputnik implements ClientModInitializer {
// cosas necesarias
public static final Sputnik INSTANCE = new Sputnik(); public static final Sputnik INSTANCE = new Sputnik();
// cosas del mod
public static final EventBus EVENT_BUS = new EventBus(); public static final EventBus EVENT_BUS = new EventBus();
public static final Logger LOGGER = LogManager.getLogger(Sputnik.class); public static final Logger LOGGER = LogManager.getLogger(Sputnik.class);
public static final long LAUNCH_TIME = System.currentTimeMillis(); public static final long LAUNCH_TIME = System.currentTimeMillis();
@@ -85,7 +85,7 @@ public class Sputnik implements ClientModInitializer {
mc = Minecraft.getInstance(); mc = Minecraft.getInstance();
ConfigManager.load(); ConfigManager.load();
VersionChecker.check(); VersionChecker.INSTANCE.check();
EVENT_BUS.subscribe(this); EVENT_BUS.subscribe(this);
@@ -250,9 +250,9 @@ public class Sputnik implements ClientModInitializer {
@EventListener @EventListener
// notificar al usuario de que hay una actualización disponible, si la hay // notificar al usuario de que hay una actualización disponible, si la hay
public void onSetScreen(OpenScreenEvent event) { public void onSetScreen(OpenScreenEvent event) {
if (VersionChecker.shouldShowScreen && event.getScreen() instanceof TitleScreen) { if (VersionChecker.INSTANCE.shouldShowScreen && event.getScreen() instanceof TitleScreen) {
event.cancel(); event.cancel();
VersionChecker.shouldShowScreen = false; VersionChecker.INSTANCE.shouldShowScreen = false;
mc.execute(() -> mc.screen = new UpdateScreen()); mc.execute(() -> mc.screen = new UpdateScreen());
} }
} }
@@ -100,7 +100,7 @@ public class ClientConfig {
extendablePanels.put(event.getPanel().category.toString(), new PanelData( extendablePanels.put(event.getPanel().category.toString(), new PanelData(
event.getPanel().getX(), event.getPanel().getX(),
event.getPanel().getY(), event.getPanel().getY(),
event.getPanel().extended)); event.getPanel().isExtended()));
ConfigManager.save(); ConfigManager.save();
} }
@@ -109,7 +109,7 @@ public class ClientConfig {
extendablePanels.replace(event.getPanel().category.toString(), new PanelData( extendablePanels.replace(event.getPanel().category.toString(), new PanelData(
event.getPanel().getX(), event.getPanel().getX(),
event.getPanel().getY(), event.getPanel().getY(),
event.getPanel().extended)); event.getPanel().isExtended()));
ConfigManager.save(); ConfigManager.save();
} }
@@ -118,7 +118,7 @@ public class ClientConfig {
extendablePanels.put("ajustes", new PanelData( extendablePanels.put("ajustes", new PanelData(
ClickGui.INSTANCE.getClientSettingsPanel().getX(), ClickGui.INSTANCE.getClientSettingsPanel().getX(),
ClickGui.INSTANCE.getClientSettingsPanel().getY(), ClickGui.INSTANCE.getClientSettingsPanel().getY(),
ClickGui.INSTANCE.getClientSettingsPanel().extended)); ClickGui.INSTANCE.getClientSettingsPanel().isExtended()));
ConfigManager.save(); ConfigManager.save();
} }
@@ -127,7 +127,7 @@ public class ClientConfig {
extendablePanels.replace("ajustes", new PanelData( extendablePanels.replace("ajustes", new PanelData(
ClickGui.INSTANCE.getClientSettingsPanel().getX(), ClickGui.INSTANCE.getClientSettingsPanel().getX(),
ClickGui.INSTANCE.getClientSettingsPanel().getY(), ClickGui.INSTANCE.getClientSettingsPanel().getY(),
ClickGui.INSTANCE.getClientSettingsPanel().extended)); ClickGui.INSTANCE.getClientSettingsPanel().isExtended()));
ConfigManager.save(); ConfigManager.save();
} }
@@ -136,7 +136,7 @@ public class ClientConfig {
extendablePanels.put("amigos", new PanelData( extendablePanels.put("amigos", new PanelData(
ClickGui.INSTANCE.getFriendsPanel().getX(), ClickGui.INSTANCE.getFriendsPanel().getX(),
ClickGui.INSTANCE.getFriendsPanel().getY(), ClickGui.INSTANCE.getFriendsPanel().getY(),
ClickGui.INSTANCE.getFriendsPanel().extended)); ClickGui.INSTANCE.getFriendsPanel().isExtended()));
ConfigManager.save(); ConfigManager.save();
} }
@@ -145,7 +145,7 @@ public class ClientConfig {
extendablePanels.replace("amigos", new PanelData( extendablePanels.replace("amigos", new PanelData(
ClickGui.INSTANCE.getFriendsPanel().getX(), ClickGui.INSTANCE.getFriendsPanel().getX(),
ClickGui.INSTANCE.getFriendsPanel().getY(), ClickGui.INSTANCE.getFriendsPanel().getY(),
ClickGui.INSTANCE.getFriendsPanel().extended)); ClickGui.INSTANCE.getFriendsPanel().isExtended()));
ConfigManager.save(); ConfigManager.save();
} }
@@ -247,10 +247,10 @@ public class ConfigManager {
panelData = config.extendablePanels.get(mp.category.toString()); panelData = config.extendablePanels.get(mp.category.toString());
} }
if (panel instanceof ClientSettingsPanel) { if (panel instanceof ClientSettingsPanel) {
panelData = config.extendablePanels.get("S"); panelData = config.extendablePanels.get("ajustes");
} }
if (panel instanceof FriendsPanel) { if (panel instanceof FriendsPanel) {
panelData = config.extendablePanels.get("F"); panelData = config.extendablePanels.get("amigos");
} }
if (panelData != null) { if (panelData != null) {
@@ -258,13 +258,13 @@ public class ConfigManager {
panel.setY(panelData.y()); panel.setY(panelData.y());
if (panel instanceof ModulePanel mPanel) { if (panel instanceof ModulePanel mPanel) {
mPanel.extended = panelData.extended(); mPanel.setExtended(panelData.extended());
} }
if (panel instanceof ClientSettingsPanel sPanel) { if (panel instanceof ClientSettingsPanel sPanel) {
sPanel.extended = panelData.extended(); sPanel.setExtended(panelData.extended());
} }
if (panel instanceof FriendsPanel fPanel) { if (panel instanceof FriendsPanel fPanel) {
fPanel.extended = panelData.extended(); fPanel.setExtended(panelData.extended());
} }
} }
} }
@@ -5,7 +5,7 @@ import com.mojang.blaze3d.vertex.PoseStack;
import me.retucio.sputnik.event.render.RenderHeldItemEvent; import me.retucio.sputnik.event.render.RenderHeldItemEvent;
import me.retucio.sputnik.event.render.RenderArmEvent; import me.retucio.sputnik.event.render.RenderArmEvent;
import me.retucio.sputnik.module.ModuleManager; import me.retucio.sputnik.module.ModuleManager;
import me.retucio.sputnik.module.modules.player.HandView; import me.retucio.sputnik.module.modules.render.HandView;
import net.minecraft.client.player.AbstractClientPlayer; import net.minecraft.client.player.AbstractClientPlayer;
import net.minecraft.client.renderer.ItemInHandRenderer; import net.minecraft.client.renderer.ItemInHandRenderer;
import net.minecraft.client.renderer.SubmitNodeCollector; import net.minecraft.client.renderer.SubmitNodeCollector;
@@ -9,6 +9,7 @@ import me.retucio.sputnik.module.setting.settings.BooleanSetting;
import me.retucio.sputnik.module.setting.settings.EnumSetting; import me.retucio.sputnik.module.setting.settings.EnumSetting;
import me.retucio.sputnik.module.setting.settings.KeySetting; import me.retucio.sputnik.module.setting.settings.KeySetting;
import me.retucio.sputnik.module.setting.Setting; import me.retucio.sputnik.module.setting.Setting;
import me.retucio.sputnik.ui.hud.HudRenderer;
import me.retucio.sputnik.util.ChatUtil; import me.retucio.sputnik.util.ChatUtil;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
@@ -29,29 +30,52 @@ public class Module {
private boolean saveSettings = true; private boolean saveSettings = true;
private boolean searchMatch = true; private boolean searchMatch = true;
// ajustes que están en todos los módulos
protected KeySetting bind = new KeySetting(
"tecla",
"tecla asignada al módulo, ESC para desactivar",
GLFW.GLFW_KEY_UNKNOWN
);
// dejar al usuario elegir si el módulo debería apagarse tras soltar su tecla asignada, o si la tecla debería alternar su estado // dejar al usuario elegir si el módulo debería apagarse tras soltar su tecla asignada, o si la tecla debería alternar su estado
protected EnumSetting<KeyModes> keyMode = new EnumSetting<>("modo de tecla", "cómo interpretar la tecla configurada", KeyModes.class, KeyModes.TOGGLE); protected EnumSetting<KeyMode> keyMode = new EnumSetting<>(
protected KeySetting bind = new KeySetting("tecla", "tecla asignada al módulo, ESC para desactivar", GLFW.GLFW_KEY_UNKNOWN); "modo de tecla",
protected BooleanSetting notify = new BooleanSetting("notificar", "notificar en el chat al activar / desactivar", true); "cómo interpretar la tecla configurada",
KeyMode.class, KeyMode.TOGGLE
);
protected BooleanSetting notify = new BooleanSetting(
"notificar",
"notificar al activar / desactivar",
true
);
protected EnumSetting<NotifyMode> notifyMode = new EnumSetting<>(
"modo de notificación",
"cómo notificar cuando se activa / desactiva",
NotifyMode.class, NotifyMode.WIDGET
);
protected final List<SettingGroup> sgs = new ArrayList<>(); protected final List<SettingGroup> sgs = new ArrayList<>();
protected final SettingGroup sgModule = addSg(new SettingGroup("módulo", false));
protected final SettingGroup sgGeneral = addSg(new SettingGroup("general", true)); protected final SettingGroup sgGeneral = addSg(new SettingGroup("general", true));
protected Minecraft mc = Minecraft.getInstance(); protected static final Minecraft mc = Minecraft.getInstance();
public Module(String name, String description, Category category) { public Module(String name, String description, Category category) {
this.name = name; this.name = name;
this.description = description; this.description = description;
this.category = category; this.category = category;
sgGeneral.addAll(bind, keyMode, notify); sgModule.addAll(bind, keyMode, notify, notifyMode);
} }
public Module(String name, String description, Category category, int key) { public Module(String name, String description, Category category, int key) {
this.name = name; this.name = name;
this.description = description; this.description = description;
this.category = category; this.category = category;
sgGeneral.addAll(bind, keyMode, notify); sgModule.addAll(bind, keyMode, notify, notifyMode);
this.bind.setDefaultValue(key); this.bind.setDefaultValue(key);
// puto marcos // puto marcos
@@ -69,6 +93,10 @@ public class Module {
return sg; return sg;
} }
public void removeSg(SettingGroup sg) {
sgs.remove(sg);
}
public List<SettingGroup> getSgs() { public List<SettingGroup> getSgs() {
return sgs; return sgs;
} }
@@ -86,6 +114,10 @@ public class Module {
return sgGeneral; return sgGeneral;
} }
public SettingGroup getSgModule() {
return sgModule;
}
public List<Setting<?>> getSettings() { public List<Setting<?>> getSettings() {
List<Setting<?>> settings = new ArrayList<>(); List<Setting<?>> settings = new ArrayList<>();
sgs.forEach(sg -> sg.forEach(settings::add)); sgs.forEach(sg -> sg.forEach(settings::add));
@@ -102,27 +134,33 @@ public class Module {
} }
public void onEnable() { public void onEnable() {
if (notify.getValue()) ChatUtil.info(getName() + " fue activado"); if (notify.getValue()) {
for (Method method : getClass().getDeclaredMethods()) if (notifyMode.is(NotifyMode.CHAT)) ChatUtil.info(getName() + " fue activado");
else HudRenderer.pushNotification(getName() + " fue activado", getName() + "fue activado.");
}
for (Method method : getClass().getDeclaredMethods()) {
if (method.isAnnotationPresent(EventListener.class)) { if (method.isAnnotationPresent(EventListener.class)) {
Sputnik.EVENT_BUS.subscribe(this); Sputnik.EVENT_BUS.subscribe(this);
break; break;
}
} }
Sputnik.EVENT_BUS.post(new ToggleModuleEvent(this));
} }
public void onDisable() { public void onDisable() {
if (notify.getValue()) ChatUtil.info(getName() + " fue desactivado"); if (notifyMode.is(NotifyMode.CHAT)) ChatUtil.info(getName() + " fue desactivado");
if (Sputnik.EVENT_BUS.isSubscribed(this)) else HudRenderer.pushNotification(getName() + " fue desactivado", getName() + "fue desactivado.");
if (Sputnik.EVENT_BUS.isSubscribed(this)) {
Sputnik.EVENT_BUS.unsubscribe(this); Sputnik.EVENT_BUS.unsubscribe(this);
Sputnik.EVENT_BUS.post(new ToggleModuleEvent(this)); }
} }
// tick (ejecutado 20 veces por segundo) // tick (ejecutado 20 veces por segundo)
public void onTick() {} public void onTick() {}
// getters y setters // getters y setters
public String getName() { public String getName() {
return name; return name;
} }
@@ -156,7 +194,7 @@ public class Module {
} }
public boolean shouldToggleOnBindRelease() { public boolean shouldToggleOnBindRelease() {
return keyMode.is(KeyModes.HOLD); return keyMode.is(KeyMode.HOLD);
} }
public boolean shouldSaveSettings() { public boolean shouldSaveSettings() {
@@ -192,13 +230,22 @@ public class Module {
this.searchMatch = searchMatch; this.searchMatch = searchMatch;
} }
public enum KeyModes { public enum KeyMode {
HOLD("mantener"), HOLD("mantener"),
TOGGLE("alternar"); TOGGLE("alternar");
// ojalá hubiera una manera de evitar repetirse con esto pero no la hay (creo) ... // ojalá hubiera una manera de evitar repetirse con esto pero no la hay (creo) ...
private final String name; private final String name;
KeyModes(String name) { this.name = name; } KeyMode(String name) { this.name = name; }
@Override public String toString() { return name; }
}
public enum NotifyMode {
CHAT("por chat"),
WIDGET("por widget");
private final String name;
NotifyMode(String name) { this.name = name; }
@Override public String toString() { return name; } @Override public String toString() { return name; }
} }
} }
@@ -39,8 +39,8 @@ public class Freelook extends Module {
Category.CAMERA, Category.CAMERA,
GLFW.GLFW_KEY_B); GLFW.GLFW_KEY_B);
keyMode.setDefaultValue(KeyModes.HOLD); keyMode.setDefaultValue(KeyMode.HOLD);
keyMode.setValue(KeyModes.HOLD); keyMode.setValue(KeyMode.HOLD);
notify.setDefaultValue(false); notify.setDefaultValue(false);
notify.setValue(false); notify.setValue(false);
@@ -51,8 +51,8 @@ public class Zoom extends Module {
Category.CAMERA, Category.CAMERA,
GLFW.GLFW_KEY_F); GLFW.GLFW_KEY_F);
keyMode.setDefaultValue(KeyModes.HOLD); keyMode.setDefaultValue(KeyMode.HOLD);
keyMode.setValue(KeyModes.HOLD); keyMode.setValue(KeyMode.HOLD);
notify.setDefaultValue(false); notify.setDefaultValue(false);
notify.setValue(false); notify.setValue(false);
@@ -114,7 +114,7 @@ public class SpearKill extends Module {
mc.player.getBoundingBox().expandTowards(lookVec.scale(rayLength)), mc.player.getBoundingBox().expandTowards(lookVec.scale(rayLength)),
e -> e instanceof LivingEntity e -> e instanceof LivingEntity
&& e.isAlive() && e != mc.player && e.isAlive() && e != mc.player
&& (!ignoreFriends.getValue() || FriendManager.INSTANCE.isFriend(e))); && (!ignoreFriends.getValue() || !FriendManager.INSTANCE.isFriend(e)));
candidates.sort(Comparator.comparingDouble(e -> candidates.sort(Comparator.comparingDouble(e ->
eyePos.distanceToSqr(e.getBoundingBox().getCenter()))); eyePos.distanceToSqr(e.getBoundingBox().getCenter())));
@@ -20,7 +20,7 @@ public class HitboxDesync extends Module {
public HitboxDesync() { public HitboxDesync() {
super("desync de hitbox", "exploit chino", Category.MOVEMENT); super("desync de hitbox", "exploit chino", Category.MOVEMENT);
keyMode.setDefaultValue(KeyModes.HOLD); keyMode.setDefaultValue(KeyMode.HOLD);
} }
@Override @Override
@@ -26,7 +26,7 @@ import org.lwjgl.glfw.GLFW;
public class AirPlace extends Module { public class AirPlace extends Module {
private final SettingGroup sgScroll = addSg(new SettingGroup("scrolleo", true)); private final SettingGroup sgScroll = addSg(new SettingGroup("scrolleo", true));
private final SettingGroup sgRender = addSg(new SettingGroup("extractRenderState", true)); private final SettingGroup sgRender = addSg(new SettingGroup("renderizado", true));
// general // general
@@ -19,7 +19,7 @@ public class KeyPearl extends Module {
public KeyPearl() { public KeyPearl() {
super("tecla de perla", "lanza una perla con una tecla", Category.PLAYER); super("tecla de perla", "lanza una perla con una tecla", Category.PLAYER);
keyMode.setValue(KeyModes.HOLD); keyMode.setValue(KeyMode.HOLD);
} }
private int prevSlot = -1; private int prevSlot = -1;
@@ -64,7 +64,7 @@ public class NoFall extends Module {
private final NumberSetting distance = sgGeneral.add(new NumberSetting( private final NumberSetting distance = sgGeneral.add(new NumberSetting(
"distancia", "distancia",
"distancia mínima de caída para aplicar el amortiguamiento", "distancia mínima de caída para aplicar la amortiguación",
3, 3,
3, 3,
23, 23,
@@ -1,4 +1,4 @@
package me.retucio.sputnik.module.modules.player; package me.retucio.sputnik.module.modules.render;
import com.github.retucio.neutrino.EventListener; import com.github.retucio.neutrino.EventListener;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
@@ -97,9 +97,11 @@ public class HandView extends Module {
0, -180, 180, 1)); 0, -180, 180, 1));
public HandView() { public HandView() {
super("manos", super(
"manos",
"modifica la manera en la que se renderizan las manos", "modifica la manera en la que se renderizan las manos",
Category.PLAYER); Category.RENDER
);
} }
@EventListener @EventListener
@@ -72,7 +72,7 @@ public abstract class Setting<T> {
} }
public void setValue(T value) { public void setValue(T value) {
if (this.value != value) { if (!this.value.equals(value)) {
this.value = value; this.value = value;
fireUpdateEvent(); fireUpdateEvent();
@@ -12,7 +12,7 @@ import java.util.List;
public class SettingGroup implements Iterable<Setting<?>> { public class SettingGroup implements Iterable<Setting<?>> {
private Module module; private Module module;
private final String name; private String name;
private boolean extended; private boolean extended;
final List<Setting<?>> settings = new ArrayList<>(1); final List<Setting<?>> settings = new ArrayList<>(1);
@@ -56,6 +56,8 @@ public class SettingGroup implements Iterable<Setting<?>> {
return name; return name;
} }
public void setName(String name) { this.name = name; }
public boolean isExtended() { public boolean isExtended() {
return extended; return extended;
} }
@@ -27,7 +27,6 @@ import me.retucio.sputnik.ui.widgets.Widget;
import me.retucio.sputnik.ui.widgets.misc.ScrollBarWidget; import me.retucio.sputnik.ui.widgets.misc.ScrollBarWidget;
import me.retucio.sputnik.ui.widgets.misc.SearchBarWidget; import me.retucio.sputnik.ui.widgets.misc.SearchBarWidget;
import me.retucio.sputnik.ui.widgets.panels.settings.FriendSettingsPanel; import me.retucio.sputnik.ui.widgets.panels.settings.FriendSettingsPanel;
import me.retucio.sputnik.util.ChatUtil;
import me.retucio.sputnik.util.KeyUtil; import me.retucio.sputnik.util.KeyUtil;
import me.retucio.sputnik.util.MiscUtil; import me.retucio.sputnik.util.MiscUtil;
@@ -43,7 +42,6 @@ import org.jspecify.annotations.NonNull;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
@@ -76,8 +74,6 @@ public class ClickGui extends Screen {
super(Component.literal("interfaz")); super(Component.literal("interfaz"));
Sputnik.EVENT_BUS.subscribe(this); Sputnik.EVENT_BUS.subscribe(this);
settingsPanels.add(clientSettingsPanel);
int x = 4; int x = 4;
for (Category category : Category.values()) { for (Category category : Category.values()) {
modulePanels.add(new ModulePanel(category, x, 40, 100, 20)); modulePanels.add(new ModulePanel(category, x, 40, 100, 20));
@@ -99,6 +95,7 @@ public class ClickGui extends Screen {
// actualizar la posición de renderizado vertical de los paneles cada tick // actualizar la posición de renderizado vertical de los paneles cada tick
friendsPanel.updateRenderY(scrollOffset); friendsPanel.updateRenderY(scrollOffset);
clientSettingsPanel.updateRenderY(scrollOffset);
for (ModulePanel mp : modulePanels) { for (ModulePanel mp : modulePanels) {
mp.updateRenderY(scrollOffset); mp.updateRenderY(scrollOffset);
} }
@@ -125,6 +122,9 @@ public class ClickGui extends Screen {
friendsPanel.render(gui, mouseX, mouseY, delta); friendsPanel.render(gui, mouseX, mouseY, delta);
friendsPanel.updatePosition(mouseX, mouseY); friendsPanel.updatePosition(mouseX, mouseY);
clientSettingsPanel.render(gui, mouseX, mouseY, delta);
clientSettingsPanel.updatePosition(mouseX, mouseY);
filterSearchResults(); filterSearchResults();
renderBottomGradient(gui, scrollOffset); renderBottomGradient(gui, scrollOffset);
@@ -152,13 +152,25 @@ public class ClickGui extends Screen {
private int calculateContentHeight() { private int calculateContentHeight() {
int bottom = mc.getWindow().getGuiScaledHeight(); int bottom = mc.getWindow().getGuiScaledHeight();
for (ModulePanel mp : modulePanels) { for (ModulePanel mp : modulePanels) {
bottom = mp.getY() + mp.getH() + mp.getTotalHeight(); int mpBottom = mp.getY() + mp.getH();
if (mp.isExtended()) mpBottom += mp.getTotalHeight();
bottom = Math.max(bottom, mpBottom);
} }
for (SettingsPanel sp : settingsPanels) { for (SettingsPanel sp : settingsPanels) {
bottom = Math.max(bottom, sp.getY() + sp.getH() + sp.getTotalHeight()); bottom = Math.max(bottom, sp.getY() + sp.getH() + sp.getTotalHeight());
} }
int friendsBottom = friendsPanel.getY() + friendsPanel.getH()
+ (friendsPanel.isExtended() ? friendsPanel.getTotalHeight() : 0);
bottom = Math.max(bottom, friendsBottom);
int clientBottom = clientSettingsPanel.getY() + clientSettingsPanel.getH()
+ (clientSettingsPanel.isExtended() ? clientSettingsPanel.getTotalHeight() : 0);
bottom = Math.max(bottom, clientBottom);
return bottom + 20; // padding return bottom + 20; // padding
} }
@@ -167,15 +179,14 @@ public class ClickGui extends Screen {
int x = (int) click.x(); int x = (int) click.x();
int y = (int) click.y(); int y = (int) click.y();
ChatUtil.info(x + " " + y);
miscWidgets.forEach(w -> w.mouseClicked( miscWidgets.forEach(w -> w.mouseClicked(
x, y, click.button() x, y, click.button()
)); ));
// detectar clics sobre los marcos // detectar clics sobre los paneles
friendsPanel.mouseClicked(x, y, click.button()); friendsPanel.mouseClicked(x, y, click.button());
for (ModulePanel mp : new ArrayList<>(modulePanels)) { clientSettingsPanel.mouseClicked(x, y, click.button());
for (ModulePanel mp : modulePanels.reversed()) {
mp.mouseClicked(x, y, click.button()); mp.mouseClicked(x, y, click.button());
} }
for (SettingsPanel sp : new ArrayList<>(settingsPanels)) { for (SettingsPanel sp : new ArrayList<>(settingsPanels)) {
@@ -193,9 +204,10 @@ public class ClickGui extends Screen {
miscWidgets.forEach(w -> w.mouseReleased( miscWidgets.forEach(w -> w.mouseReleased(
x, y, click.button())); x, y, click.button()));
// registrar cuándo se suelta el clic, en cada marco respectivamente // registrar cuándo se suelta el clic, en cada panel respectivamente
friendsPanel.mouseReleased(x, y, click.button()); friendsPanel.mouseReleased(x, y, click.button());
for (ModulePanel mp : new ArrayList<>(modulePanels)) { clientSettingsPanel.mouseReleased(x, y, click.button());
for (ModulePanel mp : modulePanels.reversed()) {
mp.mouseReleased(x, y, click.button()); mp.mouseReleased(x, y, click.button());
} }
for (SettingsPanel sp : new ArrayList<>(settingsPanels)) { for (SettingsPanel sp : new ArrayList<>(settingsPanels)) {
@@ -211,6 +223,8 @@ public class ClickGui extends Screen {
(int) click.x(), (int) click.x(),
(int) click.y())); (int) click.y()));
// MPs?
for (SettingsPanel sp : new ArrayList<>(settingsPanels)) for (SettingsPanel sp : new ArrayList<>(settingsPanels))
sp.mouseDragged((int) click.x(), (int) click.y()); sp.mouseDragged((int) click.x(), (int) click.y());
@@ -230,7 +244,7 @@ public class ClickGui extends Screen {
@EventListener @EventListener
public void onMouseMiddleButton(MouseClickEvent event) { public void onMouseMiddleButton(MouseClickEvent event) {
// mover todos los marcos a un punto visible al presionar shift + la rueda del ratón // mover todos los paneles a un punto visible al presionar shift + la rueda del ratón
if (Sputnik.mc.screen != this || event.getButton() != 2 || !KeyUtil.isKeyDown(GLFW.GLFW_KEY_LEFT_SHIFT)) return; if (Sputnik.mc.screen != this || event.getButton() != 2 || !KeyUtil.isKeyDown(GLFW.GLFW_KEY_LEFT_SHIFT)) return;
int h = Sputnik.mc.getWindow().getGuiScaledHeight(); int h = Sputnik.mc.getWindow().getGuiScaledHeight();
@@ -241,14 +255,17 @@ public class ClickGui extends Screen {
if (correction != 0) { if (correction != 0) {
modulePanels.forEach(mp -> mp.setY(mp.getY() + correction)); modulePanels.forEach(mp -> mp.setY(mp.getY() + correction));
settingsPanels.forEach(sp -> sp.setY(sp.getY() + correction)); settingsPanels.forEach(sp -> sp.setY(sp.getY() + correction));
friendsPanel.setY(friendsPanel.getY() + correction);
clientSettingsPanel.setY(clientSettingsPanel.getY() + correction);
} }
} }
public void filterSearchResults() { public void filterSearchResults() {
if (!clientSettings.searchBar.getValue()) return; if (!clientSettings.searchBar.getValue()) return;
String searchInput = searchBar.getSearchInput().trim(); String searchInput = searchBar.getSearchInput().trim();
if (!clientSettings.matchCase.getValue()) searchInput = searchInput.toLowerCase(); if (!clientSettings.matchCase.getValue()) {
searchInput = searchInput.toLowerCase();
}
for (ModulePanel mp : modulePanels) { for (ModulePanel mp : modulePanels) {
for (Button b : mp.getButtons()) { for (Button b : mp.getButtons()) {
@@ -319,6 +336,26 @@ public class ClickGui extends Screen {
friend.setSearchMatch(name.contains(searchInput) || uuid.contains(searchInput)); friend.setSearchMatch(name.contains(searchInput) || uuid.contains(searchInput));
} }
for (Button b : clientSettingsPanel.getButtons()) {
if (!(b instanceof SettingButton<?> sb)) continue;
Setting<?> setting = sb.getSetting();
if (searchInput.isEmpty()) {
setting.setSearchMatch(true);
continue;
}
String name = MiscUtil.removeAccentMarks(setting.getName());
String desc = MiscUtil.removeAccentMarks(setting.getDescription());
if (!clientSettings.matchCase.getValue()) {
name = name.toLowerCase();
desc = desc.toLowerCase();
}
setting.setSearchMatch(name.contains(searchInput) || desc.contains(searchInput));
}
} }
public SettingsPanel getSettingsPanelOfModule(Module module) { public SettingsPanel getSettingsPanelOfModule(Module module) {
@@ -463,27 +500,12 @@ public class ClickGui extends Screen {
// getters y setters de widgets // getters y setters de widgets
public List<ModulePanel> getModulePanels() { public List<ModulePanel> getModulePanels() { return modulePanels; }
return modulePanels; public List<SettingsPanel> getSettingsPanels() { return settingsPanels; }
} public ClientSettingsPanel getClientSettingsPanel() { return clientSettingsPanel; }
public FriendsPanel getFriendsPanel() { return friendsPanel; }
public ClientSettingsPanel getClientSettingsPanel() { public SearchBarWidget getSearchBar() { return searchBar; }
return clientSettingsPanel; public ScrollBarWidget getScrollBar() { return scrollBar; }
}
public FriendsPanel getFriendsPanel() {
return friendsPanel;
}
public List<Widget> getMiscWidgets() { return miscWidgets; }
public List<SettingsPanel> getSettingsPanels() {
return settingsPanels;
}
public SearchBarWidget getSearchBar() {
return searchBar;
}
public void setAnyFocused(boolean anyFocused) { public void setAnyFocused(boolean anyFocused) {
this.anyFocused = anyFocused; this.anyFocused = anyFocused;
@@ -31,7 +31,7 @@ public class UpdateScreen extends Screen {
); );
private final Component outdatedText = Component.literal("version desactualizada: " + Sputnik.MOD_VERSION); private final Component outdatedText = Component.literal("version desactualizada: " + Sputnik.MOD_VERSION);
private final Component updateText = Component.literal("descarga la última versión (" + VersionChecker.getLatestVersion() + ") desde aquí:"); private final Component updateText = Component.literal("descarga la última versión (" + VersionChecker.INSTANCE.getLatestVersion() + ") desde aquí:");
private final Button idgafButton = Button.builder( private final Button idgafButton = Button.builder(
Component.literal("me la pela"), Component.literal("me la pela"),
@@ -2,6 +2,7 @@ package me.retucio.sputnik.ui.widgets.buttons.settings;
import me.retucio.sputnik.module.Category; import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module; import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.setting.SettingGroup;
import me.retucio.sputnik.module.setting.settings.BooleanSetting; import me.retucio.sputnik.module.setting.settings.BooleanSetting;
import me.retucio.sputnik.module.setting.settings.OptionSetting; import me.retucio.sputnik.module.setting.settings.OptionSetting;
import me.retucio.sputnik.ui.widgets.buttons.SettingButton; import me.retucio.sputnik.ui.widgets.buttons.SettingButton;
@@ -67,6 +68,8 @@ public class ChooseButton<T> extends SettingButton<OptionSetting<T>> {
} }
private void rebuildDummy() { private void rebuildDummy() {
dummy.removeSg(dummy.getSgModule());
dummy.getSgGeneral().setName("opciones");
dummy.getSgGeneral().getSettings().clear(); dummy.getSgGeneral().getSettings().clear();
optionButtons.clear(); optionButtons.clear();
@@ -83,7 +83,8 @@ public class ListButton<T> extends SettingButton<ListSetting<T>> {
} }
private void rebuildDummy() { private void rebuildDummy() {
dummy.getSettings().clear(); dummy.removeSg(dummy.getSgModule());
dummy.getSgGeneral().setName("opciones");
dummy.getSgGeneral().getSettings().clear(); dummy.getSgGeneral().getSettings().clear();
optionButtons.clear(); optionButtons.clear();
@@ -0,0 +1,32 @@
package me.retucio.sputnik.ui.widgets.panels;
import me.retucio.sputnik.ui.widgets.Button;
import me.retucio.sputnik.ui.widgets.Panel;
import net.minecraft.client.gui.GuiGraphicsExtractor;
import net.minecraft.network.chat.Component;
public abstract class CloseablePanel<B extends Button> extends Panel<B> {
protected static final int PADDING = 4;
public CloseablePanel(String title, int x, int y, int w, int h) {
super(title, x, y, w, h);
}
// dibujar la "x"
protected void drawCloseButton(GuiGraphicsExtractor gui, int mouseX, int mouseY, int color) {
gui.text(mc.font, Component.literal("×"),
x + w - mc.font.width("×") - 2 * PADDING,
renderY + (h / 2) - (mc.font.lineHeight / 2),
color, true);
}
protected boolean isCloseButtonHovered(int mouseX, int mouseY) {
int closeX = x + w - mc.font.width("×") - 2 * PADDING;
int closeY = renderY + (h / 2) - (mc.font.lineHeight / 2);
return mouseX >= closeX && mouseX <= closeX + mc.font.width("×") &&
mouseY >= closeY && mouseY <= closeY + mc.font.lineHeight;
}
public abstract void onClose();
}
@@ -0,0 +1,45 @@
package me.retucio.sputnik.ui.widgets.panels;
import me.retucio.sputnik.ui.widgets.Button;
import me.retucio.sputnik.ui.widgets.Panel;
import net.minecraft.client.gui.GuiGraphicsExtractor;
import net.minecraft.network.chat.Component;
public abstract class ExtendablePanel<B extends Button> extends Panel<B> {
protected boolean extended;
public ExtendablePanel(String title, int x, int y, int w, int h) {
super(title, x, y, w, h);
this.extended = true;
}
protected void drawExpandCollapse(GuiGraphicsExtractor gui, int mouseX, int mouseY) {
String symbol = extended ? "-" : "+";
int textWidth = mc.font.width(symbol);
gui.text(mc.font, Component.literal(symbol),
x + w - textWidth - 8,
renderY + (h / 2) - (mc.font.lineHeight / 2),
-1, true);
}
protected boolean isExpandButtonHovered(int mouseX, int mouseY) {
String symbol = extended ? "-" : "+";
int textWidth = mc.font.width(symbol);
int buttonX = x + w - textWidth - 8;
int buttonY = renderY + (h / 2) - (mc.font.lineHeight / 2);
return mouseX >= buttonX && mouseX <= buttonX + textWidth &&
mouseY >= buttonY && mouseY <= buttonY + mc.font.lineHeight;
}
public void toggleExtended() {
extended = !extended;
}
public boolean isExtended() {
return extended;
}
public void setExtended(boolean extended) {
this.extended = extended;
}
}
@@ -4,30 +4,24 @@ import com.github.retucio.neutrino.EventListener;
import me.retucio.sputnik.Sputnik; import me.retucio.sputnik.Sputnik;
import me.retucio.sputnik.event.sputnik.FriendEvent; import me.retucio.sputnik.event.sputnik.FriendEvent;
import me.retucio.sputnik.event.sputnik.FriendPanelEvent; import me.retucio.sputnik.event.sputnik.FriendPanelEvent;
import me.retucio.sputnik.event.sputnik.ModulePanelEvent;
import me.retucio.sputnik.friend.Friend; import me.retucio.sputnik.friend.Friend;
import me.retucio.sputnik.friend.FriendManager; import me.retucio.sputnik.friend.FriendManager;
import me.retucio.sputnik.ui.screen.ClickGui; import me.retucio.sputnik.ui.screen.ClickGui;
import me.retucio.sputnik.ui.widgets.Panel;
import me.retucio.sputnik.ui.widgets.buttons.FriendButton; import me.retucio.sputnik.ui.widgets.buttons.FriendButton;
import me.retucio.sputnik.ui.widgets.buttons.ModuleButton;
import me.retucio.sputnik.util.Colors; import me.retucio.sputnik.util.Colors;
import net.minecraft.ChatFormatting;
import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.gui.GuiGraphicsExtractor;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import java.util.List; import java.util.List;
public class FriendsPanel extends Panel<FriendButton> { public class FriendsPanel extends ExtendablePanel<FriendButton> {
public boolean extended;
private int offset; private int offset;
public FriendsPanel(int x, int y, int w, int h) { public FriendsPanel(int x, int y, int w, int h) {
super("amigos", x, y, w, h); super("amigos", x, y, w, h);
dragging = false; dragging = false;
extended = true;
Sputnik.EVENT_BUS.subscribe(this); Sputnik.EVENT_BUS.subscribe(this);
@@ -40,12 +34,9 @@ public class FriendsPanel extends Panel<FriendButton> {
@Override @Override
protected void updateWidth() { protected void updateWidth() {
// asegurarse de que todos los botones caben en el panel, haciendo
// que la anchura se ajuste al texto más largo
int maxWidth = mc.font.width(title) + mc.font.width(" +"); int maxWidth = mc.font.width(title) + mc.font.width(" +");
for (FriendButton button : buttons) { for (FriendButton button : buttons) {
String text = button.getFriend().getName(); int textWidth = mc.font.width(button.getFriend().getName());
int textWidth = mc.font.width(text);
maxWidth = Math.max(maxWidth, textWidth); maxWidth = Math.max(maxWidth, textWidth);
} }
this.w = maxWidth + 22; this.w = maxWidth + 22;
@@ -54,36 +45,27 @@ public class FriendsPanel extends Panel<FriendButton> {
@Override @Override
public void render(GuiGraphicsExtractor gui, int mouseX, int mouseY, float delta) { public void render(GuiGraphicsExtractor gui, int mouseX, int mouseY, float delta) {
updateWidth(); updateWidth();
gui.fill(x, renderY, x + w, renderY + h, Colors.mainColor.getRGB()); // cabeza del panel gui.fill(x, renderY, x + w, renderY + h, Colors.mainColor.getRGB());
// título del panel
gui.text(mc.font, Component.literal(title), gui.text(mc.font, Component.literal(title),
x + 8, x + 8,
renderY + (h / 2) - (mc.font.lineHeight / 2), renderY + (h / 2) - (mc.font.lineHeight / 2),
-1, true); -1, true);
gui.text(mc.font, extended ? "-" : "+", drawExpandCollapse(gui, mouseX, mouseY);
x + w - mc.font.width("+") - 8, // '+' y '-' tienen la misma anchura, o sea que no importa cuál use
renderY + (h / 2) - (mc.font.lineHeight / 2),
-1, true);
List<FriendButton> visibleButtons = buttons.stream() List<FriendButton> visibleButtons = buttons.stream()
.filter(fb -> fb.getFriend().isSearchMatch()) .filter(fb -> fb.getFriend().isSearchMatch())
.toList(); .toList();
// dibujar los botones solo si está extendido
if (extended) { if (extended) {
totalHeight = visibleButtons.size() * h + 3; totalHeight = visibleButtons.size() * h + 3;
gui.fill( // fondo para los botones gui.fill(x, renderY + h + 1, x + w, renderY + h + totalHeight, Colors.panelBgColor.getRGB());
x, renderY + h + 1,
x + w, renderY + h + totalHeight,
Colors.panelBgColor.getRGB());
// dibujar los botones para cada módulo int buttonY = renderY + h + 1;
int buttonY = renderY + h + 1; for (FriendButton friendButton : visibleButtons) {
for (FriendButton moduleButton : visibleButtons) { friendButton.setOffset(buttonY - renderY);
moduleButton.setOffset(buttonY - renderY); friendButton.render(gui, mouseX, mouseY, delta);
moduleButton.render(gui, mouseX, mouseY, delta);
buttonY += h; buttonY += h;
} }
} else { } else {
@@ -93,19 +75,18 @@ public class FriendsPanel extends Panel<FriendButton> {
@Override @Override
public void mouseClicked(int mouseX, int mouseY, int button) { public void mouseClicked(int mouseX, int mouseY, int button) {
// registrar clics
if (isHovered(mouseX, mouseY) && ClickGui.INSTANCE.trySelect(this)) { if (isHovered(mouseX, mouseY) && ClickGui.INSTANCE.trySelect(this)) {
if (button == 0) { // clic izquierdo para arrastrarlo if (button == 0) {
dragging = true; dragging = true;
dragX = mouseX - x; dragX = mouseX - x;
dragY = mouseY - y; dragY = mouseY - y;
} else if (button == 1) { // clic derecho para extenderlo } else if (button == 1) {
extended = !extended; toggleExtended();
Sputnik.EVENT_BUS.post(new FriendPanelEvent.Extend()); Sputnik.EVENT_BUS.post(new FriendPanelEvent.Extend());
} }
} }
if (!extended) return; // solo dejar clicar en los botones si el marco está extendido if (!extended) return;
List<FriendButton> visibleFriendButtons = buttons.stream() List<FriendButton> visibleFriendButtons = buttons.stream()
.filter(fb -> fb.getFriend().isSearchMatch()) .filter(fb -> fb.getFriend().isSearchMatch())
@@ -119,26 +100,21 @@ public class FriendsPanel extends Panel<FriendButton> {
@Override @Override
public void mouseReleased(int mouseX, int mouseY, int button) { public void mouseReleased(int mouseX, int mouseY, int button) {
ClickGui.INSTANCE.unselect(this); ClickGui.INSTANCE.unselect(this);
if (button == 0 && dragging) { if (button == 0 && dragging) dragging = false;
dragging = false;
}
List<FriendButton> visibleFriendButtons = buttons.stream() List<FriendButton> visibleFriendButtons = buttons.stream()
.filter(fb -> fb.getFriend().isSearchMatch()) .filter(fb -> fb.getFriend().isSearchMatch())
.toList(); .toList();
for (FriendButton friendButton : visibleFriendButtons) { for (FriendButton friendButton : visibleFriendButtons) {
if (friendButton.isHovered(mouseX, mouseY)) { if (friendButton.isHovered(mouseX, mouseY))
friendButton.mouseReleased(mouseX, mouseY, button); friendButton.mouseReleased(mouseX, mouseY, button);
}
} }
if (isHovered(mouseX, mouseY)) { if (isHovered(mouseX, mouseY))
Sputnik.EVENT_BUS.post(new FriendPanelEvent.Move()); Sputnik.EVENT_BUS.post(new FriendPanelEvent.Move());
}
} }
// actualizar la posición al arrastrar el panel
public void updatePosition(double mouseX, double mouseY) { public void updatePosition(double mouseX, double mouseY) {
if (dragging) { if (dragging) {
x = (int) (mouseX - dragX); x = (int) (mouseX - dragX);
@@ -158,10 +134,9 @@ public class FriendsPanel extends Panel<FriendButton> {
public FriendButton getButtonOfFriend(Friend friend) { public FriendButton getButtonOfFriend(Friend friend) {
for (FriendButton button : buttons) { for (FriendButton button : buttons) {
if (button.getFriend().getUuid().equals(friend.getUuid())) { if (button.getFriend().getUuid().equals(friend.getUuid()))
return button; return button;
}
} }
return null; return null;
} }
} }
@@ -7,10 +7,8 @@ import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.ModuleManager; import me.retucio.sputnik.module.ModuleManager;
import me.retucio.sputnik.ui.screen.ClickGui; import me.retucio.sputnik.ui.screen.ClickGui;
import me.retucio.sputnik.ui.widgets.buttons.ModuleButton; import me.retucio.sputnik.ui.widgets.buttons.ModuleButton;
import me.retucio.sputnik.ui.widgets.Panel;
import me.retucio.sputnik.util.Colors; import me.retucio.sputnik.util.Colors;
import net.minecraft.ChatFormatting;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.gui.GuiGraphicsExtractor;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
@@ -18,18 +16,15 @@ import java.util.List;
// panel para los módulos // panel para los módulos
public class ModulePanel extends Panel<ModuleButton> { public class ModulePanel extends ExtendablePanel<ModuleButton> {
public boolean extended;
public final Category category; public final Category category;
public ModulePanel(Category category, int x, int y, int w, int h) { public ModulePanel(Category category, int x, int y, int w, int h) {
super(category.toString(), x, y, w, h); super(category.toString(), x, y, w, h);
this.category = category; this.category = category;
dragging = false; dragging = false;
extended = true;
// determinar el saliente para cada botón de módulo
int offset = h; int offset = h;
for (Module module : ModuleManager.INSTANCE.getModules()) { for (Module module : ModuleManager.INSTANCE.getModules()) {
if (!module.getCategory().equals(this.category)) continue; if (!module.getCategory().equals(this.category)) continue;
@@ -40,12 +35,9 @@ public class ModulePanel extends Panel<ModuleButton> {
@Override @Override
protected void updateWidth() { protected void updateWidth() {
// asegurarse de que todos los botones caben en el panel, haciendo
// que la anchura se ajuste al texto más largo
int maxWidth = mc.font.width(title); int maxWidth = mc.font.width(title);
for (ModuleButton button : buttons) { for (ModuleButton button : buttons) {
String text = button.getModule().getName(); int textWidth = mc.font.width(button.getModule().getName());
int textWidth = mc.font.width(text);
maxWidth = Math.max(maxWidth, textWidth); maxWidth = Math.max(maxWidth, textWidth);
} }
this.w = maxWidth + 22; this.w = maxWidth + 22;
@@ -54,33 +46,24 @@ public class ModulePanel extends Panel<ModuleButton> {
@Override @Override
public void render(GuiGraphicsExtractor gui, int mouseX, int mouseY, float delta) { public void render(GuiGraphicsExtractor gui, int mouseX, int mouseY, float delta) {
updateWidth(); updateWidth();
gui.fill(x, renderY, x + w, renderY + h, Colors.mainColor.getRGB()); // cabeza del marco gui.fill(x, renderY, x + w, renderY + h, Colors.mainColor.getRGB());
// título del marco
gui.text(mc.font, Component.literal(title), gui.text(mc.font, Component.literal(title),
x + 8, x + 8,
renderY + (h / 2) - (mc.font.lineHeight / 2), renderY + (h / 2) - (mc.font.lineHeight / 2),
-1, true); -1, true);
gui.text(mc.font, extended ? "-" : "+", drawExpandCollapse(gui, mouseX, mouseY);
x + w - mc.font.width("+") - 8, // '+' y '-' tienen la misma anchura, o sea que no importa cuál use
renderY + (h / 2) - (mc.font.lineHeight / 2),
-1, true);
List<ModuleButton> visibleButtons = buttons.stream() List<ModuleButton> visibleButtons = buttons.stream()
.filter(mb -> mb.getModule().isSearchMatch()) .filter(mb -> mb.getModule().isSearchMatch())
.toList(); .toList();
// dibujar sus módulos solo si está extendido
if (extended) { if (extended) {
totalHeight = visibleButtons.size() * h + 3; totalHeight = visibleButtons.size() * h + 3;
gui.fill( // fondo para los botones gui.fill(x, renderY + h + 1, x + w, renderY + h + totalHeight, Colors.panelBgColor.getRGB());
x, renderY + h + 1,
x + w, renderY + h + totalHeight,
Colors.panelBgColor.getRGB());
// dibujar los botones para cada módulo int buttonY = renderY + h + 1;
int buttonY = renderY + h + 1;
for (ModuleButton moduleButton : visibleButtons) { for (ModuleButton moduleButton : visibleButtons) {
moduleButton.setOffset(buttonY - renderY); moduleButton.setOffset(buttonY - renderY);
moduleButton.render(gui, mouseX, mouseY, delta); moduleButton.render(gui, mouseX, mouseY, delta);
@@ -93,19 +76,18 @@ public class ModulePanel extends Panel<ModuleButton> {
@Override @Override
public void mouseClicked(int mouseX, int mouseY, int button) { public void mouseClicked(int mouseX, int mouseY, int button) {
// registrar clics
if (isHovered(mouseX, mouseY) && ClickGui.INSTANCE.trySelect(this)) { if (isHovered(mouseX, mouseY) && ClickGui.INSTANCE.trySelect(this)) {
if (button == 0) { // clic izquierdo para arrastrarlo if (button == 0) {
dragging = true; dragging = true;
dragX = mouseX - x; dragX = mouseX - x;
dragY = mouseY - y; dragY = mouseY - y;
} else if (button == 1) { // clic derecho para extenderlo } else if (button == 1) {
extended = !extended; toggleExtended();
Sputnik.EVENT_BUS.post(new ModulePanelEvent.Extend(this)); Sputnik.EVENT_BUS.post(new ModulePanelEvent.Extend(this));
} }
} }
if (!extended) return; // solo dejar clicar en los módulos si el marco está extendido if (!extended) return;
List<ModuleButton> visibleModuleButtons = buttons.stream() List<ModuleButton> visibleModuleButtons = buttons.stream()
.filter(mb -> mb.getModule().isSearchMatch()) .filter(mb -> mb.getModule().isSearchMatch())
@@ -116,30 +98,24 @@ public class ModulePanel extends Panel<ModuleButton> {
} }
} }
// detectar cuándo se suelta el clic
@Override @Override
public void mouseReleased(int mouseX, int mouseY, int button) { public void mouseReleased(int mouseX, int mouseY, int button) {
ClickGui.INSTANCE.unselect(this); ClickGui.INSTANCE.unselect(this);
if (button == 0 && dragging) { if (button == 0 && dragging) dragging = false;
dragging = false;
}
List<ModuleButton> visibleModuleButtons = buttons.stream() List<ModuleButton> visibleModuleButtons = buttons.stream()
.filter(mb -> mb.getModule().isSearchMatch()) .filter(mb -> mb.getModule().isSearchMatch())
.toList(); .toList();
for (ModuleButton moduleButton : visibleModuleButtons) { for (ModuleButton moduleButton : visibleModuleButtons) {
if (moduleButton.isHovered(mouseX, mouseY)) { if (moduleButton.isHovered(mouseX, mouseY))
moduleButton.mouseReleased(mouseX, mouseY, button); moduleButton.mouseReleased(mouseX, mouseY, button);
}
} }
if (isHovered(mouseX, mouseY)) { if (isHovered(mouseX, mouseY))
Sputnik.EVENT_BUS.post(new ModulePanelEvent.Move(this)); Sputnik.EVENT_BUS.post(new ModulePanelEvent.Move(this));
}
} }
// actualizar la posición al arrastrar el panel
public void updatePosition(double mouseX, double mouseY) { public void updatePosition(double mouseX, double mouseY) {
if (dragging) { if (dragging) {
x = (int) (mouseX - dragX); x = (int) (mouseX - dragX);
@@ -18,15 +18,16 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
// marco para los botones de los ajustes de cada módulo // panel para los botones de los ajustes de cada módulo
public class SettingsPanel extends Panel<SettingButton<? extends Setting<?>>> { public class SettingsPanel extends CloseablePanel<SettingButton<? extends Setting<?>>> {
private Module module; protected Module module;
protected List<SettingGroup> settingGroups; protected List<SettingGroup> settingGroups;
protected static final int PADDING = 4; // para ser consistente public boolean drawHeader = true;
public SettingsPanel(Module module, int x, int y, int w, int h) { public SettingsPanel(Module module, int x, int y, int w, int h) {
super("ajustes de " + module.getName(), x, y, w, h); super("ajustes de " + module.getName(), x, y, w, h);
this.module = module; this.module = module;
this.settingGroups = module.getSgs(); this.settingGroups = module.getSgs();
@@ -41,23 +42,25 @@ public class SettingsPanel extends Panel<SettingButton<? extends Setting<?>>> {
public void render(GuiGraphicsExtractor gui, int mouseX, int mouseY, float delta) { public void render(GuiGraphicsExtractor gui, int mouseX, int mouseY, float delta) {
updateWidth(); updateWidth();
// cabezal
int centerX = x + w / 2; int centerX = x + w / 2;
int centerY = renderY + h / 2; int centerY = renderY + h / 2;
int titleX = x + 2 * PADDING;
int titleY = centerY - mc.font.lineHeight / 2;
int headerColor = module.isEnabled() if (drawHeader) {
? Colors.enabledToggleButtonColor.getRGB() int titleX = x + 2 * PADDING;
: Colors.disabledToggleButtonColor.getRGB(); int titleY = centerY - mc.font.lineHeight / 2;
int closeButtonColor = isCloseButtonHovered(mouseX, mouseY) int headerColor = module.isEnabled()
? Color.RED.getRGB() ? Colors.enabledToggleButtonColor.getRGB()
: -1; : Colors.disabledToggleButtonColor.getRGB();
gui.fill(x, renderY, x + w, renderY + h, headerColor); int closeButtonColor = isCloseButtonHovered(mouseX, mouseY)
gui.text(mc.font, title, titleX, titleY, -1, true); ? Color.RED.getRGB()
gui.text(mc.font, "×", x + w - mc.font.width("×") - 2 * PADDING, titleY, closeButtonColor, true); : -1;
gui.fill(x, renderY, x + w, renderY + h, headerColor);
gui.text(mc.font, title, titleX, titleY, -1, true);
drawCloseButton(gui, mouseX, mouseY, closeButtonColor);
}
// filtrar botones visibles // filtrar botones visibles
visibleButtons = buttons.stream() visibleButtons = buttons.stream()
@@ -154,29 +157,23 @@ public class SettingsPanel extends Panel<SettingButton<? extends Setting<?>>> {
} }
} }
@Override
public void drawTooltips(GuiGraphicsExtractor gui, int mouseX, int mouseY) {
for (SettingButton<?> sb : visibleButtons)
sb.drawTooltip(gui, mouseX, mouseY);
}
@Override @Override
public void mouseClicked(int mouseX, int mouseY, int button) { public void mouseClicked(int mouseX, int mouseY, int button) {
if (isCloseButtonHovered(mouseX, mouseY)) {
onClose();
return;
}
if (isHovered(mouseX, mouseY) && ClickGui.INSTANCE.trySelect(this)) { if (isHovered(mouseX, mouseY) && ClickGui.INSTANCE.trySelect(this)) {
if (isCloseButtonHovered(mouseX, mouseY)) {
ClickGui.INSTANCE.closeSettingsPanel(this.module);
return;
}
if (button == 0) { if (button == 0) {
dragging = true; dragging = true;
dragX = mouseX - x; dragX = mouseX - x;
dragY = mouseY - y; dragY = mouseY - y;
} else if (button == 1) { } else if (button == 1) {
ClickGui.INSTANCE.closeSettingsPanel(module); onClose();
} }
} }
// al hacer clic en los cabezales de los grupos de ajustes
for (int i = 0; i < settingGroups.size(); i++) { for (int i = 0; i < settingGroups.size(); i++) {
SettingGroup group = settingGroups.get(i); SettingGroup group = settingGroups.get(i);
if (hasVisibleSettingsInGroup(group) && isGroupHeaderHovered(mouseX, mouseY, i)) { if (hasVisibleSettingsInGroup(group) && isGroupHeaderHovered(mouseX, mouseY, i)) {
@@ -186,9 +183,8 @@ public class SettingsPanel extends Panel<SettingButton<? extends Setting<?>>> {
} }
} }
for (SettingButton<?> sb : visibleButtons) { for (SettingButton<?> sb : visibleButtons)
sb.mouseClicked(mouseX, mouseY, button); sb.mouseClicked(mouseX, mouseY, button);
}
} }
@Override @Override
@@ -395,4 +391,9 @@ public class SettingsPanel extends Panel<SettingButton<? extends Setting<?>>> {
public void setSettingGroups(List<SettingGroup> settingGroups) { public void setSettingGroups(List<SettingGroup> settingGroups) {
this.settingGroups = settingGroups; this.settingGroups = settingGroups;
} }
@Override
public void onClose() {
ClickGui.INSTANCE.closeSettingsPanel(this.module);
}
} }
@@ -3,45 +3,45 @@ package me.retucio.sputnik.ui.widgets.panels.settings;
import me.retucio.sputnik.Sputnik; import me.retucio.sputnik.Sputnik;
import me.retucio.sputnik.event.sputnik.ClientSettingsPanelEvent; import me.retucio.sputnik.event.sputnik.ClientSettingsPanelEvent;
import me.retucio.sputnik.module.modules.client.ClientSettingsModule; import me.retucio.sputnik.module.modules.client.ClientSettingsModule;
import me.retucio.sputnik.module.setting.SettingGroup;
import me.retucio.sputnik.ui.widgets.panels.SettingsPanel;
import me.retucio.sputnik.ui.screen.ClickGui; import me.retucio.sputnik.ui.screen.ClickGui;
import me.retucio.sputnik.ui.widgets.buttons.SettingButton; import me.retucio.sputnik.ui.widgets.panels.SettingsPanel;
import me.retucio.sputnik.util.Colors; import me.retucio.sputnik.util.Colors;
import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.gui.GuiGraphicsExtractor;
public class ClientSettingsPanel extends SettingsPanel { public class ClientSettingsPanel extends SettingsPanel {
public static final ClientSettingsModule clientSettings = new ClientSettingsModule(); public static final ClientSettingsModule clientSettings = new ClientSettingsModule();
public boolean extended = false; private boolean extended = false;
public ClientSettingsPanel(int x, int y, int w, int h) { public ClientSettingsPanel(int x, int y, int w, int h) {
super(clientSettings, x, y, w, h); super(clientSettings, x, y, w, h);
title = "ajustes del mod"; this.title = "ajustes del mod";
this.drawHeader = false; // disable the original header
} }
@Override @Override
public void render(GuiGraphicsExtractor gui, int mouseX, int mouseY, float delta) { public void render(GuiGraphicsExtractor gui, int mouseX, int mouseY, float delta) {
updateWidth(); updateWidth();
// botones, fondo, etc. // Draw our own custom header (no close button, with +/-
if (extended) {
super.render(gui, mouseX, mouseY, delta);
}
// cabezal
gui.fill(x, renderY, x + w, renderY + h, Colors.mainColor.getRGB()); gui.fill(x, renderY, x + w, renderY + h, Colors.mainColor.getRGB());
gui.text(mc.font, title, gui.text(mc.font, title,
x + 8, x + 8,
renderY + (h / 2) - (mc.font.lineHeight / 2), renderY + (h / 2) - (mc.font.lineHeight / 2),
-1, true); -1, true);
gui.text(mc.font, extended ? "-" : "+", String symbol = extended ? "-" : "+";
x + w - mc.font.width("+") - 8, int textWidth = mc.font.width(symbol);
gui.text(mc.font, symbol,
x + w - textWidth - 8,
renderY + (h / 2) - (mc.font.lineHeight / 2), renderY + (h / 2) - (mc.font.lineHeight / 2),
-1, true); -1, true);
// Only draw the rest of the panel (content) if extended
if (extended) {
// Call super.render() – but since drawHeader=false, it will only draw the content
super.render(gui, mouseX, mouseY, delta);
}
} }
@Override @Override
@@ -54,38 +54,53 @@ public class ClientSettingsPanel extends SettingsPanel {
} else if (button == 1) { } else if (button == 1) {
extended = !extended; extended = !extended;
Sputnik.EVENT_BUS.post(new ClientSettingsPanelEvent.Extend()); Sputnik.EVENT_BUS.post(new ClientSettingsPanelEvent.Extend());
}
}
// solo dejar clicar en los ajustes si el marco está extendido
if (!extended) return;
for (int i = 0; i < settingGroups.size(); i++) {
SettingGroup group = settingGroups.get(i);
if (hasVisibleSettingsInGroup(group) && isGroupHeaderHovered(mouseX, mouseY, i)) {
group.setExtended(!group.isExtended());
updateVisibleButtonsForGroup(group);
return; return;
} }
} }
for (SettingButton<?> sb : buttons) { if (extended) {
sb.mouseClicked(mouseX, mouseY, button); super.mouseClicked(mouseX, mouseY, button);
} }
} }
@Override @Override
public void mouseReleased(int mouseX, int mouseY, int button) { public void mouseReleased(int mouseX, int mouseY, int button) {
ClickGui.INSTANCE.unselect(this); ClickGui.INSTANCE.unselect(this);
if (button == 0 && dragging) if (button == 0 && dragging) {
dragging = false;
Sputnik.EVENT_BUS.post(new ClientSettingsPanelEvent.Move()); Sputnik.EVENT_BUS.post(new ClientSettingsPanelEvent.Move());
}
super.mouseReleased(mouseX, mouseY, button); if (extended) {
super.mouseReleased(mouseX, mouseY, button);
}
} }
@Override @Override
public void drawTooltips(GuiGraphicsExtractor gui, int mouseX, int mouseY) { public void mouseDragged(int mouseX, int mouseY) {
if (!extended) return; if (extended) {
super.drawTooltips(gui, mouseX, mouseY); super.mouseDragged(mouseX, mouseY);
}
} }
}
@Override
public void mouseScrolled(double amount) {
if (extended) {
super.mouseScrolled(amount);
}
}
@Override
public void onKey(int key, int action) {
if (extended) {
super.onKey(key, action);
}
}
public boolean isExtended() {
return extended;
}
public void setExtended(boolean extended) {
this.extended = extended;
}
}
@@ -32,23 +32,22 @@ public class MiscUtil {
} }
} }
public static void copyVector(Vector3d destination, Vec3 source) { public static void copyVector(Vector3d dst, Vec3 src) {
destination.x = source.x; dst.x = src.x;
destination.y = source.y; dst.y = src.y;
destination.z = source.z; dst.z = src.z;
} }
@SuppressWarnings("unchecked") public static <T extends Number> T getHighest(List<T> list) {
public static <T> T getHighest(List<T> list) { if (list.getFirst() == null) return null;
if (list.getFirst() == null || !(list.getFirst() instanceof Number value)) return null; T maxValue = list.getFirst();
Number maxValue = value;
for (T t : list) { for (T t : list) {
if (((Number) t).doubleValue() > maxValue.doubleValue()) { if (t.doubleValue() > maxValue.doubleValue()) {
maxValue = (Number) t; maxValue = t;
} }
} }
return (T) maxValue; return maxValue;
} }
public static String getCurrentFormattedTime() { public static String getCurrentFormattedTime() {
@@ -11,15 +11,17 @@ import java.time.Duration;
public class VersionChecker { public class VersionChecker {
private static final URI PROPERTIES_URL = getFileURI(); public static final VersionChecker INSTANCE = new VersionChecker();
public static boolean updateAvailable = false; private final URI PROPERTIES_URL = getFileURI();
public static String latestRemoteVersion = null; private final String CURRENT_VERSION = Sputnik.MOD_VERSION;
public static String currentVersion = Sputnik.MOD_VERSION;
public static boolean shouldShowScreen = false; private boolean updateAvailable = false;
private String latestRemoteVersion = null;
public static void check() { public boolean shouldShowScreen = false;
public void check() {
try { try {
HttpClient client = HttpClient.newHttpClient(); HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder() HttpRequest request = HttpRequest.newBuilder()
@@ -35,17 +37,17 @@ public class VersionChecker {
if (latestRemoteVersion != null) { if (latestRemoteVersion != null) {
String remoteVersion = cleanVersion(latestRemoteVersion); String remoteVersion = cleanVersion(latestRemoteVersion);
String localVersion = cleanVersion(currentVersion); String localVersion = cleanVersion(CURRENT_VERSION);
if (compareVersions(localVersion, remoteVersion) == -1) { if (compareVersions(localVersion, remoteVersion) == -1) {
updateAvailable = true; updateAvailable = true;
Sputnik.LOGGER.info("actualización disponible. local: {}, más reciente: {}", Sputnik.LOGGER.info("actualización disponible. local: {}, más reciente: {}",
currentVersion, latestRemoteVersion); CURRENT_VERSION, latestRemoteVersion);
shouldShowScreen = true; shouldShowScreen = true;
} else if (compareVersions(localVersion, remoteVersion) == 0){ } else if (compareVersions(localVersion, remoteVersion) == 0){
Sputnik.LOGGER.info("el mod está al día: v{}", currentVersion); Sputnik.LOGGER.info("el mod está al día: v{}", CURRENT_VERSION);
} else { } else {
Sputnik.LOGGER.info("mod en estado de desarrollo: v{}", currentVersion); Sputnik.LOGGER.info("mod en estado de desarrollo: v{}", CURRENT_VERSION);
} }
} }
} else { } else {
@@ -135,7 +137,11 @@ public class VersionChecker {
return null; return null;
} }
public static String getLatestVersion() { public String getLatestVersion() {
return latestRemoteVersion; return latestRemoteVersion;
} }
public boolean isUpdateAvailable() {
return updateAvailable;
}
} }
@@ -13,10 +13,10 @@ public class DrawUtil {
} }
public static void drawCircle(GuiGraphicsExtractor gui, int x, int y, int radius, int color) { public static void drawCircle(GuiGraphicsExtractor gui, int x, int y, int radius, int color) {
for (int i = -radius; i <= radius; i++) for (int dy = -radius; dy <= radius; dy++) {
for (int j = -radius; j <= radius; j++) int dx = (int) Math.sqrt(radius * radius - dy * dy);
if (i * i + j * j <= radius * radius) gui.fill(x - dx, y + dy, x + dx + 1, y + dy + 1, color);
gui.fill(x + i, y + j, x + i + 1, y + j + 1, color); }
} }
public static void drawCheckerBoard(GuiGraphicsExtractor gui, int x, int y, int width, int height, int checkerSize, int color1, int color2) { public static void drawCheckerBoard(GuiGraphicsExtractor gui, int x, int y, int width, int height, int checkerSize, int color1, int color2) {