diff --git a/cambios.md b/cambios.md index ea4c262..c386615 100644 --- a/cambios.md +++ b/cambios.md @@ -1,18 +1,16 @@ -# v4.7 +# v4.8 ## novedades ### adiciones -- sistema de amigos +- panel para gestionar los amigos, y la habilidad de añadirles motes #### módulos nuevos: -- amigos: añade o elimina amigos con la rueda del ratón, para evitar atacarles por accidente - ### arreglos / mejoras -- `destello de enchants.` ya funciona en items 2d +- `puntos de desconexión` ya renderiza la caja correctamente ## problemas reconocidos diff --git a/credits.txt b/credits.txt index d9b8397..d9ebebe 100644 --- a/credits.txt +++ b/credits.txt @@ -1,4 +1,4 @@ -Meteor Client: https://github.com/MeteorDevelopment/meteor-client | https://meteorclient.com +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 @@ -9,7 +9,7 @@ bypass-resource-pack: https://github.com/emilyy-dev/bypass-resource-pack elytra-recast: https://github.com/InLieuOfLuna/elytra-recast/ SpearHax: https://github.com/etianl/spearHax/ ProjectileTrajectoryPreview: https://github.com/maDU59/ProjectilesTrajectoryPreview -DupersUnited public addon: https://discord.gg/dupes | https://dupers.wtf +DupersUnited public addon: https://discord.gg/dupes | https://dupers.wtf probablemente más pero como tengo demencia se me olvida si quieres que te acredite o quite tu código de mi mod, mándame un mensaje en discord (username: retucio) y sin problemas :) \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 3ddad52..2fe11a1 100644 --- a/gradle.properties +++ b/gradle.properties @@ -10,6 +10,6 @@ discord_rpc_version=1.0.3 neutrino_version=1.1.0 jdk_version=25 -mod_version=4.7 +mod_version=4.8 maven_group=me.retucio archives_base_name=sputnik \ No newline at end of file diff --git a/src/main/java/me/retucio/sputnik/config/ClientConfig.java b/src/main/java/me/retucio/sputnik/config/ClientConfig.java index b079f2c..c094d35 100644 --- a/src/main/java/me/retucio/sputnik/config/ClientConfig.java +++ b/src/main/java/me/retucio/sputnik/config/ClientConfig.java @@ -4,6 +4,7 @@ import com.github.retucio.neutrino.EventListener; import me.retucio.sputnik.event.sputnik.*; import me.retucio.sputnik.module.setting.settings.*; import me.retucio.sputnik.ui.screen.ClickGui; +import me.retucio.sputnik.ui.widgets.panels.FriendsPanel; import me.retucio.sputnik.util.ChatUtil; import java.io.Serial; @@ -130,6 +131,24 @@ public class ClientConfig { ConfigManager.save(); } + @EventListener + public void onExtendFriendsPanel(FriendPanelEvent.Extend event) { + extendablePanels.put("F", new PanelData( + ClickGui.INSTANCE.getFriendsPanel().getX(), + ClickGui.INSTANCE.getFriendsPanel().getY(), + ClickGui.INSTANCE.getFriendsPanel().extended)); + ConfigManager.save(); + } + + @EventListener + public void onMoveFriendsPanel(FriendPanelEvent.Move event) { + extendablePanels.replace("F", new PanelData( + ClickGui.INSTANCE.getFriendsPanel().getX(), + ClickGui.INSTANCE.getFriendsPanel().getY(), + ClickGui.INSTANCE.getFriendsPanel().extended)); + ConfigManager.save(); + } + @EventListener public void onAddFriend(FriendEvent.Add event) { String uuid = event.getFriend().getUuid().toString(); diff --git a/src/main/java/me/retucio/sputnik/config/ConfigManager.java b/src/main/java/me/retucio/sputnik/config/ConfigManager.java index 7ff91db..5f52b7b 100644 --- a/src/main/java/me/retucio/sputnik/config/ConfigManager.java +++ b/src/main/java/me/retucio/sputnik/config/ConfigManager.java @@ -10,6 +10,7 @@ import me.retucio.sputnik.module.ModuleManager; import me.retucio.sputnik.module.setting.*; import me.retucio.sputnik.module.setting.settings.*; import me.retucio.sputnik.ui.widgets.Panel; +import me.retucio.sputnik.ui.widgets.panels.FriendsPanel; import me.retucio.sputnik.ui.widgets.panels.ModulePanel; import me.retucio.sputnik.ui.screen.ClickGui; import me.retucio.sputnik.ui.widgets.panels.settings.ClientSettingsPanel; @@ -117,12 +118,12 @@ public class ConfigManager { save(); } - public static void setPanelPosition(SettingsPanel frame) { + public static void setPanelPosition(SettingsPanel panel) { ensureConfig(); - if (!config.settingsPanels.containsKey(frame.getModule().getName())) - config.settingsPanels.put(frame.getModule().getName(), new int[] {frame.getX(), frame.getY()}); + if (!config.settingsPanels.containsKey(panel.getModule().getName())) + config.settingsPanels.put(panel.getModule().getName(), new int[] {panel.getX(), panel.getY()}); else - config.settingsPanels.replace(frame.getModule().getName(), new int[] {frame.getX(), frame.getY()}); + config.settingsPanels.replace(panel.getModule().getName(), new int[] {panel.getX(), panel.getY()}); save(); } @@ -231,6 +232,7 @@ public class ConfigManager { private static void applyExtendablePanels() { applyExtendablePanel(ClickGui.INSTANCE.getModulesPanel()); applyExtendablePanel(ClickGui.INSTANCE.getClientSettingsPanel()); + applyExtendablePanel(ClickGui.INSTANCE.getFriendsPanel()); Sputnik.LOGGER.info("posiciones de marcos extendibles aplicadas"); ClickGui.INSTANCE.refreshListButtons(); @@ -238,20 +240,30 @@ public class ConfigManager { private static void applyExtendablePanel(Panel panel) { ClientConfig.PanelData panelData = null; - if (panel instanceof ModulePanel) - panelData = config.extendablePanels.get("M"); - if (panel instanceof ClientSettingsPanel) + if (panel instanceof ModulePanel) { + panelData = config.extendablePanels.get("M"); + } + if (panel instanceof ClientSettingsPanel) { panelData = config.extendablePanels.get("S"); + } + if (panel instanceof FriendsPanel) { + panelData = config.extendablePanels.get("F"); + } if (panelData != null) { panel.setX(panelData.x()); panel.setY(panelData.y()); - if (panel instanceof ModulePanel mFrame) - mFrame.extended = panelData.extended(); - if (panel instanceof ClientSettingsPanel sFrame) - sFrame.extended = panelData.extended(); + if (panel instanceof ModulePanel mPanel) { + mPanel.extended = panelData.extended(); + } + if (panel instanceof ClientSettingsPanel sPanel) { + sPanel.extended = panelData.extended(); + } + if (panel instanceof FriendsPanel fPanel) { + fPanel.extended = panelData.extended(); + } } } diff --git a/src/main/java/me/retucio/sputnik/event/sputnik/FriendPanelEvent.java b/src/main/java/me/retucio/sputnik/event/sputnik/FriendPanelEvent.java new file mode 100644 index 0000000..565a54f --- /dev/null +++ b/src/main/java/me/retucio/sputnik/event/sputnik/FriendPanelEvent.java @@ -0,0 +1,9 @@ +package me.retucio.sputnik.event.sputnik; + +import com.github.retucio.neutrino.Event; + +public class FriendPanelEvent { + + public static class Extend extends Event {} // al extenderlo / contraerlo + public static class Move extends Event {} // al cambiarlo de posición +} \ No newline at end of file diff --git a/src/main/java/me/retucio/sputnik/friend/Friend.java b/src/main/java/me/retucio/sputnik/friend/Friend.java index 3d9cba0..60964c3 100644 --- a/src/main/java/me/retucio/sputnik/friend/Friend.java +++ b/src/main/java/me/retucio/sputnik/friend/Friend.java @@ -15,6 +15,8 @@ public class Friend { private String name; private final UUID uuid; + private boolean searchMatch; + public Friend(UUID uuid) { this.uuid = uuid; } @@ -38,6 +40,14 @@ public class Friend { return player; } + public boolean isSearchMatch() { + return searchMatch; + } + + public void setSearchMatch(boolean searchMatch) { + this.searchMatch = searchMatch; + } + public enum Status { SUCCESS, ALREADY_BEFRIENDED, diff --git a/src/main/java/me/retucio/sputnik/mixin/mixins/player/PlayerMixin.java b/src/main/java/me/retucio/sputnik/mixin/mixins/player/PlayerMixin.java index 0746fb3..39bf8d3 100644 --- a/src/main/java/me/retucio/sputnik/mixin/mixins/player/PlayerMixin.java +++ b/src/main/java/me/retucio/sputnik/mixin/mixins/player/PlayerMixin.java @@ -2,6 +2,7 @@ package me.retucio.sputnik.mixin.mixins.player; import me.retucio.sputnik.Sputnik; import me.retucio.sputnik.event.interact.ClipAtLedgeEvent; +import me.retucio.sputnik.friend.FriendManager; import me.retucio.sputnik.module.ModuleManager; import me.retucio.sputnik.module.modules.render.Nametags; @@ -54,7 +55,12 @@ public abstract class PlayerMixin extends LivingEntity { : "") + ChatFormatting.RESET + "]"; - return original.copy().append(text); + // mote de amigo + Component name = FriendManager.INSTANCE.isFriend((Player) (Object) this) && nametags.friendNick.getValue() + ? Component.literal(FriendManager.INSTANCE.get(uuid).getName()) + : original; + + return name.copy().append(text); } @Inject(method = "isStayingOnGroundSurface", at = @At("HEAD"), cancellable = true) diff --git a/src/main/java/me/retucio/sputnik/module/modules/network/LogoutSpots.java b/src/main/java/me/retucio/sputnik/module/modules/network/LogoutSpots.java index 06d0042..8795b33 100644 --- a/src/main/java/me/retucio/sputnik/module/modules/network/LogoutSpots.java +++ b/src/main/java/me/retucio/sputnik/module/modules/network/LogoutSpots.java @@ -233,8 +233,8 @@ public class LogoutSpots extends Module { AABB box = player.getBoundingBox(); this.xWidth = box.getXsize(); - this.zWidth = box.getYsize(); - this.height = box.getZsize(); + this.height = box.getYsize(); + this.zWidth = box.getZsize(); this.uuid = player.getUUID(); this.name = player.getName().getString(); diff --git a/src/main/java/me/retucio/sputnik/module/modules/render/Nametags.java b/src/main/java/me/retucio/sputnik/module/modules/render/Nametags.java index f73fb48..6fa24a1 100644 --- a/src/main/java/me/retucio/sputnik/module/modules/render/Nametags.java +++ b/src/main/java/me/retucio/sputnik/module/modules/render/Nametags.java @@ -31,6 +31,8 @@ import net.minecraft.world.level.entity.UniquelyIdentifyable; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; @@ -60,6 +62,7 @@ public class Nametags extends Module { public final BooleanSetting alwaysVisible = sgGeneral.add(new BooleanSetting("siempre mostrar nametags", "mostrar nametag cuando el jugador está agachado o es invisible", false)); public final BooleanSetting showSelf = sgGeneral.add(new BooleanSetting("mostrar propio", "mostrar nametag propio", false)); + public final BooleanSetting friendNick = sgGeneral.add(new BooleanSetting("motes", "usar los motes de amigos", true)); public final BooleanSetting countItems = sgInfo.add(new BooleanSetting("contar items", "muestra cuánto de un item hay en un stack dropeado", true)); public final BooleanSetting showProjectileDamage = sgInfo.add(new BooleanSetting("daño del proyectil", "muestra cuánto daño hace un proyectil en su nametag", true)); diff --git a/src/main/java/me/retucio/sputnik/ui/screen/ClickGui.java b/src/main/java/me/retucio/sputnik/ui/screen/ClickGui.java index 381514d..cf54b1e 100644 --- a/src/main/java/me/retucio/sputnik/ui/screen/ClickGui.java +++ b/src/main/java/me/retucio/sputnik/ui/screen/ClickGui.java @@ -6,13 +6,16 @@ import me.retucio.sputnik.event.input.KeyEvent; import me.retucio.sputnik.event.input.MouseClickEvent; import me.retucio.sputnik.event.input.MouseScrollEvent; import me.retucio.sputnik.event.sputnik.SettingsPanelEvent; +import me.retucio.sputnik.friend.Friend; import me.retucio.sputnik.module.Category; import me.retucio.sputnik.module.Module; import me.retucio.sputnik.module.setting.Setting; import me.retucio.sputnik.module.setting.settings.ColorSetting; +import me.retucio.sputnik.ui.widgets.buttons.FriendButton; import me.retucio.sputnik.ui.widgets.buttons.settings.ListButton; import me.retucio.sputnik.ui.widgets.buttons.ModuleButton; import me.retucio.sputnik.ui.widgets.buttons.SettingButton; +import me.retucio.sputnik.ui.widgets.panels.FriendsPanel; import me.retucio.sputnik.ui.widgets.panels.settings.ClientSettingsPanel; import me.retucio.sputnik.ui.widgets.panels.settings.ColorPickerPanel; import me.retucio.sputnik.ui.widgets.panels.ModulePanel; @@ -22,6 +25,7 @@ import me.retucio.sputnik.ui.widgets.Panel; import me.retucio.sputnik.ui.widgets.Widget; import me.retucio.sputnik.ui.widgets.misc.ScrollBarWidget; import me.retucio.sputnik.ui.widgets.misc.SearchBarWidget; +import me.retucio.sputnik.ui.widgets.panels.settings.FriendSettingsPanel; import me.retucio.sputnik.util.KeyUtil; import me.retucio.sputnik.util.MiscUtil; @@ -57,9 +61,10 @@ public class ClickGui extends Screen { private final ModulePanel modulesPanel = new ModulePanel(20, 30, 100, 20); private final List settingsPanels = new ArrayList<>(); private final ClientSettingsPanel clientSettingsPanel = new ClientSettingsPanel(200, 30, 100, 20); + private final FriendsPanel friendsPanel = new FriendsPanel(770, 30, 100, 20); private final ScrollBarWidget scrollBar = new ScrollBarWidget(); - private final SearchBarWidget searchBar = new SearchBarWidget(340, 16, 320, 20); + private final SearchBarWidget searchBar = new SearchBarWidget(500, 30, 320, 20); private final List miscWidgets = Arrays.asList(scrollBar, searchBar); public ClickGui() { @@ -82,6 +87,7 @@ public class ClickGui extends Screen { // actualizar la posición de renderizado vertical de los marcos cada tick modulesPanel.updateRenderY(scrollOffset); + friendsPanel.updateRenderY(scrollOffset); for (SettingsPanel sp : settingsPanels) sp.updateRenderY(scrollOffset); @@ -95,8 +101,12 @@ public class ClickGui extends Screen { modulesPanel.render(gui, mouseX, mouseY, delta); modulesPanel.updatePosition(mouseX, mouseY); - for (SettingsPanel sp : settingsPanels) + for (SettingsPanel sp : settingsPanels) { sp.drawTooltips(gui, mouseX, mouseY); + } + + friendsPanel.render(gui, mouseX, mouseY, delta); + friendsPanel.updatePosition(mouseX, mouseY); filterSearchResults(); @@ -133,31 +143,37 @@ public class ClickGui extends Screen { @Override public boolean mouseClicked(MouseButtonEvent click, boolean doubled) { + int x = (int) click.x(); + int y = (int) click.y(); + miscWidgets.forEach(w -> w.mouseClicked( - (int) click.x(), - (int) click.y(), - click.button() + x, y, click.button() )); // detectar clics sobre los marcos - modulesPanel.mouseClicked((int) click.x(), (int) click.y(), click.button()); - for (SettingsPanel sp : new ArrayList<>(settingsPanels)) - sp.mouseClicked((int) click.x(), (int) click.y(), click.button()); + modulesPanel.mouseClicked(x, y, click.button()); + friendsPanel.mouseClicked(x, y, click.button()); + for (SettingsPanel sp : new ArrayList<>(settingsPanels)) { + sp.mouseClicked(x, y, click.button()); + } return super.mouseClicked(click, doubled); } @Override public boolean mouseReleased(MouseButtonEvent click) { + int x = (int) click.x(); + int y = (int) click.y(); + miscWidgets.forEach(w -> w.mouseReleased( - (int) click.x(), - (int) click.y(), - click.button())); + x, y, click.button())); // registrar cuándo se suelta el clic, en cada marco respectivamente - modulesPanel.mouseReleased((int) click.x(), (int) click.y(), click.button()); - for (SettingsPanel sp : new ArrayList<>(settingsPanels)) - sp.mouseReleased((int) click.x(), (int) click.y(), click.button()); + modulesPanel.mouseReleased(x, y, click.button()); + friendsPanel.mouseReleased(x, y, click.button()); + for (SettingsPanel sp : new ArrayList<>(settingsPanels)) { + sp.mouseReleased(x, y, click.button()); + } return super.mouseReleased(click); } @@ -207,7 +223,7 @@ public class ClickGui extends Screen { if (!clientSettings.matchCase.getValue()) searchInput = searchInput.toLowerCase(); for (Button b : modulesPanel.getButtons()) { - if (!(b instanceof ModuleButton mb)) return; + if (!(b instanceof ModuleButton mb)) continue; Module module = mb.getModule(); if (getCategoryFilter() != Category.ALL) { @@ -238,7 +254,7 @@ public class ClickGui extends Screen { for (SettingsPanel sp : settingsPanels) { for (Button b : sp.getButtons()) { - if (!(b instanceof SettingButton sb)) return; + if (!(b instanceof SettingButton sb)) continue; Setting setting = sb.getSetting(); if (searchInput.isEmpty()) { @@ -259,6 +275,26 @@ public class ClickGui extends Screen { setting.setSearchMatch(name.contains(searchInput) || description.contains(searchInput) || sgName.contains(searchInput)); } } + + for (Button b : friendsPanel.getButtons()) { + if (!(b instanceof FriendButton fb)) continue; + Friend friend = fb.getFriend(); + + if (searchInput.isEmpty()) { + friend.setSearchMatch(true); + continue; + } + + String name = MiscUtil.removeAccentMarks(friend.getName()); + String uuid = MiscUtil.removeAccentMarks(friend.getUuid().toString()); + + if (!clientSettings.matchCase.getValue()) { + name = name.toLowerCase(); + uuid = uuid.toLowerCase(); + } + + friend.setSearchMatch(name.contains(searchInput) || uuid.contains(searchInput)); + } } public SettingsPanel getSettingsPanelOfModule(Module module) { @@ -337,6 +373,33 @@ public class ClickGui extends Screen { } } + public boolean isFriendSettingsPanelOpen(Friend friend) { + for (SettingsPanel sp : getSettingsPanels()) { + if (sp instanceof FriendSettingsPanel fsp) { + if (fsp.getFriend().getUuid().equals(friend.getUuid())) return true; + } + } + return false; + } + + public void openFriendSettingsPanel(Friend friend, int x, int y) { + FriendSettingsPanel panel = new FriendSettingsPanel(friend, x + 80, y + 5, 153, 20); + if (isFriendSettingsPanelOpen(friend)) { + closeFriendSettingsPanel(friend); + return; + } + settingsPanels.add(panel); + } + + public void closeFriendSettingsPanel(Friend friend) { + for (SettingsPanel sp : getSettingsPanels()) { + if (sp instanceof FriendSettingsPanel fsp && fsp.getFriend().getUuid().equals(friend.getUuid())) { + settingsPanels.remove(fsp); + break; + } + } + } + public void refreshListButtons() { for (SettingsPanel panel : settingsPanels) for (Button button : panel.getButtons()) @@ -392,6 +455,10 @@ public class ClickGui extends Screen { return clientSettingsPanel; } + public FriendsPanel getFriendsPanel() { + return friendsPanel; + } + public List getMiscWidgets() { return miscWidgets; } public List getSettingsPanels() { diff --git a/src/main/java/me/retucio/sputnik/ui/widgets/buttons/FriendButton.java b/src/main/java/me/retucio/sputnik/ui/widgets/buttons/FriendButton.java new file mode 100644 index 0000000..d8bad6c --- /dev/null +++ b/src/main/java/me/retucio/sputnik/ui/widgets/buttons/FriendButton.java @@ -0,0 +1,75 @@ +package me.retucio.sputnik.ui.widgets.buttons; + +import me.retucio.sputnik.friend.Friend; +import me.retucio.sputnik.module.Module; +import me.retucio.sputnik.ui.screen.ClickGui; +import me.retucio.sputnik.ui.widgets.panels.FriendsPanel; +import me.retucio.sputnik.ui.widgets.panels.ModulePanel; +import me.retucio.sputnik.ui.widgets.Button; +import me.retucio.sputnik.util.Colors; +import net.minecraft.client.gui.GuiGraphicsExtractor; +import net.minecraft.network.chat.Component; + + +// clase para el botón para cada módulo +public class FriendButton extends Button { + + private final Friend friend; + public final int height = 18; + + public FriendButton(Friend friend, FriendsPanel parent, int offset) { + super(parent, offset); + this.friend = friend; + } + + @Override + public void render(GuiGraphicsExtractor gui, int mouseX, int mouseY, float delta) { + gui.fill( // dibujar el contorno del botón + parent.getX() + 2, parent.getRenderY() + offset + 3, + parent.getX() + parent.getW() - 2 , parent.getRenderY() + height + offset, + determineColor(mouseX, mouseY)); + + gui.text( // dibujar el nombre del amigo + mc.font, friend.getName(), + parent.getX() + 5, parent.getRenderY() + offset + (height / 2) - (mc.font.lineHeight / 2) + 2, + -1, true); + + // dibujar "tooltips" (cajas de texto) al pasar el puntero encima del botón, para mostrar su UUID + if (isHovered(mouseX, mouseY)) { + drawTooltip(gui, mouseX, mouseY); + } + } + + @Override + public void drawTooltip(GuiGraphicsExtractor gui, int mouseX, int mouseY) { + gui.setTooltipForNextFrame(Component.literal(friend.getUuid().toString()), mouseX, mouseY + 20); + } + + @Override + public void mouseClicked(int mouseX, int mouseY, int button) { + if (isHovered(mouseX, mouseY) && ClickGui.INSTANCE.trySelect(this)) { + ClickGui.INSTANCE.openFriendSettingsPanel(friend, mouseX, mouseY); + } + } + + // verifica si el puntero del ratón se encuentra sobre el botón + @Override + public boolean isHovered(int mouseX, int mouseY) { + return ClickGui.INSTANCE.canSelect(this) + && mouseX > parent.getX() + && mouseX < parent.getX() + parent.getW() + && mouseY > parent.getRenderY() + offset + && mouseY < parent.getRenderY() + height + offset; + } + + public int determineColor(double mouseX, double mouseY) { + // determina el color del botón, dependiendo de si está el puntero encima + return isHovered((int) mouseX, (int) mouseY) + ? Colors.buttonColor.brighter().getRGB() + : Colors.buttonColor.getRGB(); + } + + public Friend getFriend() { + return friend; + } +} diff --git a/src/main/java/me/retucio/sputnik/ui/widgets/panels/FriendsPanel.java b/src/main/java/me/retucio/sputnik/ui/widgets/panels/FriendsPanel.java new file mode 100644 index 0000000..6cf5297 --- /dev/null +++ b/src/main/java/me/retucio/sputnik/ui/widgets/panels/FriendsPanel.java @@ -0,0 +1,167 @@ +package me.retucio.sputnik.ui.widgets.panels; + +import com.github.retucio.neutrino.EventListener; +import me.retucio.sputnik.Sputnik; +import me.retucio.sputnik.event.sputnik.FriendEvent; +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.FriendManager; +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.ModuleButton; +import me.retucio.sputnik.util.Colors; +import net.minecraft.ChatFormatting; +import net.minecraft.client.gui.GuiGraphicsExtractor; +import net.minecraft.network.chat.Component; + +import java.util.List; + + +public class FriendsPanel extends Panel { + + public boolean extended; + private int offset; + + public FriendsPanel(int x, int y, int w, int h) { + super("amigos", x, y, w, h); + dragging = false; + extended = true; + + Sputnik.EVENT_BUS.subscribe(this); + + offset = h; + for (Friend friend : FriendManager.INSTANCE.getFriends()) { + buttons.add(new FriendButton(friend, this, offset)); + offset += h; + } + } + + @Override + 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(" +"); + for (FriendButton button : buttons) { + String text = button.getFriend().getName(); + int textWidth = mc.font.width(text); + maxWidth = Math.max(maxWidth, textWidth); + } + this.w = maxWidth + 22; + } + + @Override + public void render(GuiGraphicsExtractor gui, int mouseX, int mouseY, float delta) { + updateWidth(); + gui.fill(x, renderY, x + w, renderY + h, Colors.mainColor.getRGB()); // cabeza del panel + + // título del panel + gui.text(mc.font, Component.literal(title), + x + 8, + renderY + (h / 2) - (mc.font.lineHeight / 2), + -1, true); + + gui.text(mc.font, extended ? "-" : "+", + 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 visibleButtons = buttons.stream() + .filter(fb -> fb.getFriend().isSearchMatch()) + .toList(); + + // dibujar los botones solo si está extendido + if (extended) { + totalHeight = visibleButtons.size() * h + 3; + gui.fill( // fondo para los botones + x, renderY + h + 1, + x + w, renderY + h + totalHeight, + Colors.panelBgColor.getRGB()); + + // dibujar los botones para cada módulo + int buttonY = renderY + h + 1; + for (FriendButton moduleButton : visibleButtons) { + moduleButton.setOffset(buttonY - renderY); + moduleButton.render(gui, mouseX, mouseY, delta); + buttonY += h; + } + } else { + totalHeight = 0; + } + } + + @Override + public void mouseClicked(int mouseX, int mouseY, int button) { + // registrar clics + if (isHovered(mouseX, mouseY) && ClickGui.INSTANCE.trySelect(this)) { + if (button == 0) { // clic izquierdo para arrastrarlo + dragging = true; + dragX = mouseX - x; + dragY = mouseY - y; + } else if (button == 1) { // clic derecho para extenderlo + extended = !extended; + Sputnik.EVENT_BUS.post(new FriendPanelEvent.Extend()); + } + } + + if (!extended) return; // solo dejar clicar en los botones si el marco está extendido + + List visibleFriendButtons = buttons.stream() + .filter(fb -> fb.getFriend().isSearchMatch()) + .toList(); + + for (FriendButton friendButton : visibleFriendButtons) { + friendButton.mouseClicked(mouseX, mouseY, button); + } + } + + @Override + public void mouseReleased(int mouseX, int mouseY, int button) { + ClickGui.INSTANCE.unselect(this); + if (button == 0 && dragging) { + dragging = false; + } + + List visibleFriendButtons = buttons.stream() + .filter(fb -> fb.getFriend().isSearchMatch()) + .toList(); + + for (FriendButton friendButton : visibleFriendButtons) { + if (friendButton.isHovered(mouseX, mouseY)) { + friendButton.mouseReleased(mouseX, mouseY, button); + } + } + + if (isHovered(mouseX, mouseY)) { + Sputnik.EVENT_BUS.post(new FriendPanelEvent.Move()); + } + } + + // actualizar la posición al arrastrar el panel + public void updatePosition(double mouseX, double mouseY) { + if (dragging) { + x = (int) (mouseX - dragX); + y = (int) (mouseY - dragY); + } + } + + @EventListener + private void onAddFriend(FriendEvent.Add event) { + buttons.add(new FriendButton(event.getFriend(), this, offset)); + } + + @EventListener + private void onRemoveFriend(FriendEvent.Remove event) { + buttons.remove(getButtonOfFriend(event.getFriend())); + } + + public FriendButton getButtonOfFriend(Friend friend) { + for (FriendButton button : buttons) { + if (button.getFriend().getUuid().equals(friend.getUuid())) { + return button; + } + } + return null; + } +} diff --git a/src/main/java/me/retucio/sputnik/ui/widgets/panels/ModulePanel.java b/src/main/java/me/retucio/sputnik/ui/widgets/panels/ModulePanel.java index 113ceb7..f4f0a01 100644 --- a/src/main/java/me/retucio/sputnik/ui/widgets/panels/ModulePanel.java +++ b/src/main/java/me/retucio/sputnik/ui/widgets/panels/ModulePanel.java @@ -16,13 +16,11 @@ import net.minecraft.network.chat.Component; import java.util.List; -// marco para los módulos +// panel para los módulos public class ModulePanel extends Panel { public boolean extended; - public Minecraft mc = Minecraft.getInstance(); - public ModulePanel(int x, int y, int w, int h) { super("módulos", x, y, w, h); dragging = false; @@ -38,8 +36,8 @@ public class ModulePanel extends Panel { @Override protected void updateWidth() { - // asegurarse de que todos los botones caben en el marco, haciendo que la anchura se ajuste al texto más largo - + // 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); for (ModuleButton button : buttons) { String text = button.getModule().getName(); @@ -109,31 +107,35 @@ public class ModulePanel extends Panel { .filter(mb -> mb.getModule().isSearchMatch()) .toList(); - for (ModuleButton moduleButton : visibleModuleButtons) + for (ModuleButton moduleButton : visibleModuleButtons) { moduleButton.mouseClicked(mouseX, mouseY, button); + } } // detectar cuándo se suelta el clic @Override public void mouseReleased(int mouseX, int mouseY, int button) { ClickGui.INSTANCE.unselect(this); - if (button == 0 && dragging) + if (button == 0 && dragging) { dragging = false; + } List visibleModuleButtons = buttons.stream() .filter(mb -> mb.getModule().isSearchMatch()) .toList(); for (ModuleButton moduleButton : visibleModuleButtons) { - if (moduleButton.isHovered(mouseX, mouseY)) + if (moduleButton.isHovered(mouseX, mouseY)) { moduleButton.mouseReleased(mouseX, mouseY, button); + } } - if (isHovered(mouseX, mouseY)) + if (isHovered(mouseX, mouseY)) { Sputnik.EVENT_BUS.post(new ModulePanelEvent.Move()); + } } - // actualizar la posición al arrastrar el marco + // actualizar la posición al arrastrar el panel public void updatePosition(double mouseX, double mouseY) { if (dragging) { x = (int) (mouseX - dragX); diff --git a/src/main/java/me/retucio/sputnik/ui/widgets/panels/SettingsPanel.java b/src/main/java/me/retucio/sputnik/ui/widgets/panels/SettingsPanel.java index aa6dd40..bdb8730 100644 --- a/src/main/java/me/retucio/sputnik/ui/widgets/panels/SettingsPanel.java +++ b/src/main/java/me/retucio/sputnik/ui/widgets/panels/SettingsPanel.java @@ -23,7 +23,7 @@ public class SettingsPanel extends Panel>> { private Module module; protected List settingGroups; - private static final int PADDING = 4; // para ser consistente + protected static final int PADDING = 4; // para ser consistente public SettingsPanel(Module module, int x, int y, int w, int h) { super("ajustes de " + module.getName(), x, y, w, h); diff --git a/src/main/java/me/retucio/sputnik/ui/widgets/panels/settings/ColorPickerPanel.java b/src/main/java/me/retucio/sputnik/ui/widgets/panels/settings/ColorPickerPanel.java index 18d365d..cac6f65 100644 --- a/src/main/java/me/retucio/sputnik/ui/widgets/panels/settings/ColorPickerPanel.java +++ b/src/main/java/me/retucio/sputnik/ui/widgets/panels/settings/ColorPickerPanel.java @@ -332,19 +332,19 @@ public class ColorPickerPanel extends SettingsPanel { if (colorSetting != null) { if (isSBPickerHovered(mouseX, mouseY)) { pickingSaturationBrightness = true; - updateColorFromPicker((int) mouseX, (int) mouseY); + updateColorFromPicker(mouseX, mouseY); } if (!colorSetting.isRainbow() && isHuePickerHovered(mouseX, mouseY)) { pickingHue = true; - updateColorFromPicker((int) mouseX, (int) mouseY); + updateColorFromPicker(mouseX, mouseY); } } // opacidad if (isAlphaPickerHovered(mouseX, mouseY)) { pickingAlpha = true; - updateColorFromPicker((int) mouseX, (int) mouseY); + updateColorFromPicker(mouseX, mouseY); } for (SettingButton sb : visibleButtons) diff --git a/src/main/java/me/retucio/sputnik/ui/widgets/panels/settings/FriendSettingsPanel.java b/src/main/java/me/retucio/sputnik/ui/widgets/panels/settings/FriendSettingsPanel.java new file mode 100644 index 0000000..b6a0374 --- /dev/null +++ b/src/main/java/me/retucio/sputnik/ui/widgets/panels/settings/FriendSettingsPanel.java @@ -0,0 +1,96 @@ +package me.retucio.sputnik.ui.widgets.panels.settings; + +import me.retucio.sputnik.config.ConfigManager; +import me.retucio.sputnik.friend.Friend; +import me.retucio.sputnik.friend.FriendManager; +import me.retucio.sputnik.module.Category; +import me.retucio.sputnik.module.Module; +import me.retucio.sputnik.module.ModuleManager; +import me.retucio.sputnik.module.modules.client.Friends; +import me.retucio.sputnik.module.setting.settings.StringSetting; +import me.retucio.sputnik.ui.screen.ClickGui; +import me.retucio.sputnik.ui.widgets.buttons.settings.TextButton; +import me.retucio.sputnik.ui.widgets.panels.SettingsPanel; +import me.retucio.sputnik.util.Colors; +import net.minecraft.client.gui.GuiGraphicsExtractor; + + +public class FriendSettingsPanel extends SettingsPanel { + + private final Friend friend; + private final StringSetting nickname; + public final Module dummyModule; + + private int removeButtonY; + + public FriendSettingsPanel(Friend friend, int x, int y, int w, int h) { + super(ModuleManager.INSTANCE.getModuleByClass(Friends.class), x, y, w, h); + + this.friend = friend; + + dummyModule = new Module(friend.getName(), "gestiona a " + friend.getName(), Category.CLIENT) { + @Override public void onEnable() {} + @Override public void onDisable() {} + }; + + dummyModule.getSettings().forEach(s -> s.visibility(false)); + dummyModule.shouldSaveSettings(false); + + setModule(dummyModule); + + nickname = new StringSetting("nombre", "con qué nombre guardar al amigo", friend.getName(), 40); + dummyModule.getSgGeneral().add(nickname); + nickname.onUpdate(name -> { + friend.setName(name); + ConfigManager.getConfig().friends.put(friend.getUuid().toString(), name); + ConfigManager.save(); + }); + + buttons.clear(); + addButton(new TextButton(nickname, this, h)); + + setSettingGroups(dummyModule.getSgs()); + } + + @Override + public void render(GuiGraphicsExtractor gui, int mx, int my, float delta) { + super.render(gui, mx, my, delta); + + removeButtonY = renderY + h + totalHeight + PADDING; + int buttonH = h - h / 4; + + gui.fill(x, removeButtonY, x + w, removeButtonY + buttonH + PADDING, Colors.panelBgColor.getRGB()); + + int color = isRemoveButtonHovered(mx, my) + ? Colors.disabledToggleButtonColor.brighter().getRGB() + : Colors.disabledToggleButtonColor.getRGB(); + + gui.fill(x + PADDING, removeButtonY, x + w - PADDING, removeButtonY + buttonH, color); + + String label = "eliminar amigo"; + gui.text(mc.font, label, + x + w / 2 - mc.font.width(label) / 2, + removeButtonY + (buttonH - mc.font.lineHeight) / 2, + -1, true); + } + + @Override + public void mouseClicked(int mouseX, int mouseY, int button) { + super.mouseClicked(mouseX, mouseY, button); + + if (button == 0 && isRemoveButtonHovered(mouseX, mouseY)) { + FriendManager.INSTANCE.remove(friend); + ClickGui.INSTANCE.closeSettingsPanel(dummyModule); + } + } + + private boolean isRemoveButtonHovered(int mouseX, int mouseY) { + int buttonH = h - h / 4; + return mouseX > x + PADDING && mouseX < x + w - PADDING + && mouseY > removeButtonY && mouseY < removeButtonY + buttonH; + } + + public Friend getFriend() { + return friend; + } +} \ No newline at end of file