Last active
November 7, 2024 18:23
-
-
Save Ensamisten/ca6ca46d303c47a3084b325fe9149dea to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package io.github.ensamisten.gui; | |
| import com.mojang.blaze3d.systems.RenderSystem; | |
| import io.github.ensamisten.config.ModuleConfig; | |
| import io.github.ensamisten.config.icecream.IceCreamConfig; | |
| import io.github.ensamisten.config.icecream.IceCreamConfigManager; | |
| import io.github.ensamisten.module.Extension; | |
| import io.github.ensamisten.module.ModuleManager; | |
| import io.github.ensamisten.module.movement.Stare; | |
| import io.github.ensamisten.module.player.CopyChat; | |
| import io.github.ensamisten.module.render.Title; | |
| import net.fabricmc.api.EnvType; | |
| import net.fabricmc.api.Environment; | |
| import net.minecraft.client.MinecraftClient; | |
| import net.minecraft.client.gui.DrawContext; | |
| import net.minecraft.client.gui.screen.Screen; | |
| import net.minecraft.client.gui.screen.option.GameOptionsScreen; | |
| import net.minecraft.client.gui.widget.ButtonWidget; | |
| import net.minecraft.client.gui.widget.OptionListWidget; | |
| import net.minecraft.client.gui.widget.TextFieldWidget; | |
| import net.minecraft.client.option.GameOptions; | |
| import net.minecraft.client.option.SimpleOption; | |
| import net.minecraft.client.util.InputUtil; | |
| import net.minecraft.text.Text; | |
| import net.minecraft.util.Formatting; | |
| import java.util.*; | |
| @Environment(EnvType.CLIENT) | |
| public class AllyshipOptionsScreen extends GameOptionsScreen { | |
| private static final Text TITLE_TEXT = Text.translatable("controls.keybinds.title"); | |
| private static final int BUTTON_WIDTH = 80; | |
| private static final int BUTTON_HEIGHT = 20; | |
| private static final int DROPDOWN_WIDTH = BUTTON_WIDTH; // Match dropdown width to category button width | |
| private static final int BORDER_PADDING = 4; | |
| private static final int MAX_VISIBLE_ITEMS = 8; // Maximum number of visible items in a dropdown | |
| private final Map<String, DropdownContainer> dropdowns = new HashMap<>(); | |
| private final Map<String, ButtonWidget> categoryButtons = new HashMap<>(); // Store category buttons | |
| // Variables for dragging functionality | |
| private ButtonWidget draggedButton = null; | |
| private double initialClickX, initialClickY; | |
| private double dragOffsetX, dragOffsetY; | |
| private boolean isDragging = false; | |
| private final double dragThreshold = 5.0; // Pixels to distinguish click vs drag | |
| private final MinecraftClient client; | |
| private OptionListWidget list; | |
| SimpleOption<Integer> killAuraDelayOption; | |
| public AllyshipOptionsScreen(Screen parent, GameOptions gameOptions) { | |
| super(parent, gameOptions, TITLE_TEXT); | |
| this.client = MinecraftClient.getInstance(); | |
| this.textRenderer = this.client.textRenderer; // Initialize textRenderer | |
| // Define main options | |
| dropdowns.put("combat", new DropdownContainer("combat", createDropdownItems(List.of("KillAura", "Stare", "Reach", "AutoTotem")))); | |
| dropdowns.put("movement", new DropdownContainer("movement", createDropdownItems(List.of( | |
| "Flight", "BoatFly", "Carousel", "Speed", "JetPack", "Jesus", | |
| "NoFall", "AntiKnockback", "CreativeFly", "AutoJump", "AutoWalk", | |
| "Spider", "Glide", "AutoSwim", "AutoLadder", "Blink", "Vclip", | |
| "NoClip", "AutoTrapdoor" | |
| )))); | |
| dropdowns.put("exploit", new DropdownContainer("exploit", createDropdownItems(List.of("ClientSpoofer")))); | |
| dropdowns.put("render", new DropdownContainer("render", createDropdownItems(List.of("Fullbright", "Lookout", "Title")))); | |
| dropdowns.put("player", new DropdownContainer("player", createDropdownItems(List.of("CopyChat", "FriendGuard")))); // Add FriendGuard here | |
| dropdowns.put("world", new DropdownContainer("world", createDropdownItems(List.of()))); | |
| } | |
| private List<DropdownItem> createDropdownItems(List<String> names) { | |
| List<DropdownItem> items = new ArrayList<>(); | |
| for (String name : names) { | |
| if (name.equals("Flight")) { | |
| // Example: "Flight" has sub-options | |
| items.add(new DropdownItem(name, createDropdownItems(List.of("SubOption1", "SubOption2", "SubOption3")), null)); | |
| } else if (name.equals("ClientSpoofer")) { | |
| // Create the main "ClientSpoofer" item | |
| DropdownItem clientSpooferItem = new DropdownItem(name, null, null); | |
| // Create the "Flavour" sub-item with parent | |
| DropdownItem flavourItem = new DropdownItem("Flavour", null, clientSpooferItem); | |
| // Assign subOptions to clientSpooferItem | |
| clientSpooferItem.subOptions = List.of(flavourItem); | |
| items.add(clientSpooferItem); | |
| } else if (name.equals("Title")) { | |
| // Create "Title" item with text field | |
| DropdownItem titleItem = new DropdownItem(name, null, null); | |
| items.add(titleItem); | |
| } else { | |
| items.add(new DropdownItem(name, null, null)); // No sub-options | |
| } | |
| } | |
| return items; | |
| } | |
| @Override | |
| protected void init() { | |
| this.list = this.addDrawableChild(new OptionListWidget(this.client, this.width, this)); | |
| int buttonY = 60; | |
| int buttonSpacing = 10; | |
| int startX = 20; | |
| int currentX = startX; | |
| // Add category buttons | |
| for (String category : dropdowns.keySet()) { | |
| ButtonWidget button = createCategoryButton(category, currentX, buttonY); | |
| this.addDrawableChild(button); | |
| categoryButtons.put(category, button); // Store button reference for later use | |
| currentX += BUTTON_WIDTH + buttonSpacing; | |
| } | |
| } | |
| @Override | |
| protected void addOptions() { | |
| // Optional implementation if needed | |
| } | |
| /** | |
| * Creates a category button. | |
| */ | |
| private ButtonWidget createCategoryButton(String text, int x, int y) { | |
| return ButtonWidget.builder(Text.literal(text), button -> toggleDropdown(text.toLowerCase(), button)) | |
| .dimensions(x, y, BUTTON_WIDTH, BUTTON_HEIGHT) | |
| .build(); | |
| } | |
| /** | |
| * Toggles the visibility of a dropdown based on the category. | |
| */ | |
| private void toggleDropdown(String category, ButtonWidget button) { | |
| DropdownContainer dropdown = dropdowns.get(category); | |
| if (dropdown != null) { | |
| dropdown.toggle(); | |
| } | |
| } | |
| @Override | |
| public boolean mouseClicked(double mouseX, double mouseY, int button) { | |
| // Check if a category button was clicked | |
| for (ButtonWidget categoryButton : categoryButtons.values()) { | |
| if (categoryButton.isMouseOver(mouseX, mouseY)) { | |
| draggedButton = categoryButton; | |
| initialClickX = mouseX; | |
| initialClickY = mouseY; | |
| dragOffsetX = mouseX - categoryButton.getX(); | |
| dragOffsetY = mouseY - categoryButton.getY(); | |
| return true; | |
| } | |
| } | |
| // Delegate to dropdowns | |
| for (DropdownContainer dropdown : dropdowns.values()) { | |
| if (dropdown.isVisible() && dropdown.mouseClicked(mouseX, mouseY, button)) { | |
| return true; | |
| } | |
| } | |
| return super.mouseClicked(mouseX, mouseY, button); | |
| } | |
| @Override | |
| public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) { | |
| if (draggedButton != null) { | |
| double distance = Math.hypot(mouseX - initialClickX, mouseY - initialClickY); | |
| if (!isDragging && distance > dragThreshold) { | |
| isDragging = true; | |
| } | |
| if (isDragging) { | |
| int newX = (int) (mouseX - dragOffsetX); | |
| int newY = (int) (mouseY - dragOffsetY); | |
| String category = draggedButton.getMessage().getString().toLowerCase(); | |
| DropdownContainer dropdown = dropdowns.get(category); | |
| if (dropdown != null && dropdown.isVisible()) { | |
| // Get the dropdown's desired height | |
| int dropdownHeight = dropdown.getDesiredHeight(); | |
| // Limit the dropdown height to maximum visible items | |
| dropdownHeight = Math.min(dropdownHeight, MAX_VISIBLE_ITEMS * BUTTON_HEIGHT); | |
| // Calculate the maximum Y position to ensure the dropdown fits below the button | |
| int maxY = this.height - BUTTON_HEIGHT - dropdownHeight - BORDER_PADDING; | |
| // Keep buttons within screen bounds | |
| newX = Math.max(0, Math.min(this.width - BUTTON_WIDTH, newX)); | |
| newY = Math.max(0, Math.min(maxY, newY)); | |
| } else { | |
| // Allow unrestricted movement when dropdown is not visible | |
| // Ensure the button remains within the screen bounds | |
| newX = Math.max(-BUTTON_WIDTH, Math.min(this.width, newX)); | |
| newY = Math.max(-BUTTON_HEIGHT, Math.min(this.height, newY)); | |
| } | |
| draggedButton.setX(newX); | |
| draggedButton.setY(newY); | |
| // Update dropdown position if it's visible | |
| if (dropdown != null && dropdown.isVisible()) { | |
| dropdown.setPosition(newX, newY); | |
| } | |
| return true; | |
| } | |
| } | |
| return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY); | |
| } | |
| @Override | |
| public boolean mouseReleased(double mouseX, double mouseY, int button) { | |
| if (draggedButton != null) { | |
| if (!isDragging) { | |
| // If not dragging, it's a click, so toggle the dropdown | |
| String category = draggedButton.getMessage().getString().toLowerCase(); | |
| toggleDropdown(category, draggedButton); | |
| } | |
| draggedButton = null; | |
| isDragging = false; | |
| return true; | |
| } | |
| return super.mouseReleased(mouseX, mouseY, button); | |
| } | |
| @Override | |
| public boolean mouseScrolled(double mouseX, double mouseY, double horizontalAmount, double verticalAmount) { | |
| for (DropdownContainer dropdown : dropdowns.values()) { | |
| if (dropdown.isVisible() && dropdown.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount)) { | |
| return true; | |
| } | |
| } | |
| return super.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount); | |
| } | |
| @Override | |
| public boolean keyPressed(int keyCode, int scanCode, int modifiers) { | |
| for (DropdownContainer dropdown : dropdowns.values()) { | |
| if (dropdown.isVisible() && dropdown.keyPressed(keyCode, scanCode, modifiers)) { | |
| return true; | |
| } | |
| } | |
| return super.keyPressed(keyCode, scanCode, modifiers); | |
| } | |
| @Override | |
| public boolean charTyped(char chr, int modifiers) { | |
| for (DropdownContainer dropdown : dropdowns.values()) { | |
| if (dropdown.isVisible() && dropdown.charTyped(chr, modifiers)) { | |
| return true; | |
| } | |
| } | |
| return super.charTyped(chr, modifiers); | |
| } | |
| // Override the renderBackground method to prevent background blur | |
| @Override | |
| public void renderBackground(DrawContext context, int mouseX, int mouseY, float delta) { | |
| // Do nothing to keep the background fully transparent | |
| } | |
| @Override | |
| public void render(DrawContext context, int mouseX, int mouseY, float delta) { | |
| // Render category buttons | |
| for (ButtonWidget categoryButton : categoryButtons.values()) { | |
| categoryButton.render(context, mouseX, mouseY, delta); | |
| } | |
| // Render other dropdowns | |
| updateDropdownPositions(); | |
| for (DropdownContainer dropdown : dropdowns.values()) { | |
| if (dropdown.isVisible()) { | |
| dropdown.render(context, mouseX, mouseY, delta); | |
| } | |
| } | |
| // Render tooltips and other elements if necessary | |
| super.render(context, mouseX, mouseY, delta); | |
| } | |
| /** | |
| * Updates the positions of visible dropdowns to stick to their category buttons. | |
| */ | |
| private void updateDropdownPositions() { | |
| for (Map.Entry<String, DropdownContainer> entry : dropdowns.entrySet()) { | |
| String category = entry.getKey(); | |
| DropdownContainer dropdown = entry.getValue(); | |
| if (dropdown.isVisible()) { | |
| ButtonWidget button = categoryButtons.get(category); | |
| if (button != null) { | |
| int dropdownX = button.getX(); | |
| int dropdownY = button.getY(); | |
| dropdown.setPosition(dropdownX, dropdownY); | |
| } | |
| } | |
| } | |
| } | |
| /** | |
| * Toggles a module's enabled state. | |
| */ | |
| private void toggleModule(String moduleName) { | |
| Extension module = ModuleManager.getInstance().getModuleByName(moduleName); | |
| if (module != null) { | |
| module.toggle(); | |
| ModuleConfig.set(moduleName, module.isEnabled()); | |
| ModuleConfig.save(); | |
| } | |
| } | |
| /** | |
| * Inner class representing the dropdown container for each category. | |
| */ | |
| private class DropdownContainer { | |
| private final String category; | |
| private final List<DropdownItem> items; | |
| private boolean visible = false; | |
| private int posX, posY; | |
| private int scrollOffset = 0; | |
| public DropdownContainer(String category, List<DropdownItem> items) { | |
| this.category = category; | |
| this.items = items; | |
| } | |
| public int getHeight() { | |
| int maxContainerHeight = MAX_VISIBLE_ITEMS * BUTTON_HEIGHT; | |
| int screenHeight = MinecraftClient.getInstance().getWindow().getScaledHeight(); | |
| int maxHeightBelowButton = screenHeight - posY - BORDER_PADDING; | |
| int maxHeight = Math.min(maxContainerHeight, maxHeightBelowButton); | |
| maxHeight = Math.max(maxHeight, BUTTON_HEIGHT); // Ensure at least one button height | |
| return Math.min(getDesiredHeight(), maxHeight); | |
| } | |
| public int getDesiredHeight() { | |
| return calculateTotalHeight(); | |
| } | |
| /** | |
| * Toggles the visibility of the dropdown. | |
| */ | |
| public void toggle() { | |
| this.visible = !this.visible; | |
| updateItemPositions(); | |
| } | |
| /** | |
| * Checks if the dropdown is visible. | |
| */ | |
| public boolean isVisible() { | |
| return visible; | |
| } | |
| /** | |
| * Sets the position of the dropdown. | |
| */ | |
| public void setPosition(int x, int y) { | |
| this.posX = x; | |
| this.posY = y + BUTTON_HEIGHT; // Always open downward | |
| updateItemPositions(); | |
| } | |
| /** | |
| * Updates the positions and visibility of dropdown items based on the current scroll offset. | |
| */ | |
| private void updateItemPositions() { | |
| int currentY = posY - scrollOffset; | |
| for (DropdownItem item : items) { | |
| boolean isItemVisible = currentY + item.getTotalHeight() > posY && currentY < posY + getHeight(); | |
| item.setVisible(isItemVisible); | |
| item.setPosition(this.posX, currentY); | |
| currentY += item.getTotalHeight(); | |
| if (item.hasSubOptions() && item.isSubOptionsVisible()) { | |
| for (DropdownItem subItem : item.getSubOptions()) { | |
| boolean isSubItemVisible = currentY + subItem.getTotalHeight() > posY && currentY < posY + getHeight(); | |
| subItem.setVisible(isSubItemVisible); | |
| subItem.setPosition(this.posX, currentY); | |
| currentY += subItem.getTotalHeight(); | |
| } | |
| } | |
| } | |
| } | |
| /** | |
| * Handles mouse scrolling within the dropdown. | |
| */ | |
| public boolean mouseScrolled(double mouseX, double mouseY, double horizontalAmount, double verticalAmount) { | |
| if (!visible) return false; | |
| int dropdownTop = posY; | |
| int dropdownBottom = posY + getHeight(); | |
| if (mouseX < posX || mouseX > posX + DROPDOWN_WIDTH || mouseY < dropdownTop || mouseY > dropdownBottom) { | |
| return false; | |
| } | |
| int scrollAmount = (int) (verticalAmount * BUTTON_HEIGHT); | |
| scrollOffset = Math.max(0, Math.min(scrollOffset - scrollAmount, getMaxScrollOffset())); | |
| updateItemPositions(); | |
| return true; | |
| } | |
| /** | |
| * Calculates the maximum scroll offset based on total content height. | |
| */ | |
| private int getMaxScrollOffset() { | |
| int totalHeight = calculateTotalHeight(); | |
| return Math.max(0, totalHeight - getHeight()); | |
| } | |
| /** | |
| * Handles mouse clicks within the dropdown. | |
| */ | |
| public boolean mouseClicked(double mouseX, double mouseY, int button) { | |
| if (!visible) return false; | |
| int dropdownTop = posY; | |
| int dropdownBottom = posY + getHeight(); | |
| // Check if the click is within the dropdown's clipping region | |
| if (mouseX < posX || mouseX > posX + DROPDOWN_WIDTH || mouseY < dropdownTop || mouseY > dropdownBottom) { | |
| return false; | |
| } | |
| for (DropdownItem item : items) { | |
| if (item.isVisible()) { | |
| if (item.mouseClicked(mouseX, mouseY, button)) { | |
| return true; | |
| } | |
| } | |
| } | |
| return false; | |
| } | |
| public boolean keyPressed(int keyCode, int scanCode, int modifiers) { | |
| for (DropdownItem item : items) { | |
| if (item.isVisible() && item.keyPressed(keyCode, scanCode, modifiers)) { | |
| return true; | |
| } | |
| } | |
| return false; | |
| } | |
| public boolean charTyped(char chr, int modifiers) { | |
| for (DropdownItem item : items) { | |
| if (item.isVisible() && item.charTyped(chr, modifiers)) { | |
| return true; | |
| } | |
| } | |
| return false; | |
| } | |
| /** | |
| * Renders the dropdown within a clipping region to prevent overflow. | |
| */ | |
| public void render(DrawContext context, int mouseX, int mouseY, float delta) { | |
| if (!visible) return; | |
| int renderPosY = posY; | |
| //enableScissor(posX, renderPosY, DROPDOWN_WIDTH, getHeight()); | |
| context.fill(posX, renderPosY, posX + DROPDOWN_WIDTH, renderPosY + getHeight(), 0x80000000); | |
| for (DropdownItem item : items) { | |
| if (item.isVisible()) { | |
| item.render(context, mouseX, mouseY, delta); | |
| } | |
| } | |
| //disableScissor(); | |
| } | |
| /** | |
| * Helper method to enable scissor box for clipping. | |
| */ | |
| private void enableScissor(int x, int y, int width, int height) { | |
| MinecraftClient mc = MinecraftClient.getInstance(); | |
| double scale = mc.getWindow().getScaleFactor(); | |
| int windowHeight = mc.getWindow().getHeight(); // in pixels | |
| int scissorX = (int) (x * scale); | |
| int scissorY = windowHeight - (int) ((y + height) * scale); | |
| int scissorWidth = (int) (width * scale); | |
| int scissorHeight = (int) (height * scale); | |
| // Adjust scissorY and scissorHeight if necessary | |
| if (scissorY < 0) { | |
| scissorHeight += scissorY; | |
| scissorY = 0; | |
| } | |
| if (scissorY + scissorHeight > windowHeight) { | |
| scissorHeight = windowHeight - scissorY; | |
| } | |
| // Ensure scissorHeight is not negative | |
| if (scissorHeight < 0) { | |
| scissorHeight = 0; | |
| } | |
| RenderSystem.enableScissor(scissorX, scissorY, scissorWidth, scissorHeight); | |
| } | |
| /** | |
| * Helper method to disable scissor box. | |
| */ | |
| private void disableScissor() { | |
| RenderSystem.disableScissor(); | |
| } | |
| /** | |
| * Calculates the total height of all dropdown items, including sub-options and text fields. | |
| */ | |
| private int calculateTotalHeight() { | |
| int height = 0; | |
| for (DropdownItem item : items) { | |
| height += item.getTotalHeight(); | |
| if (item.hasSubOptions() && item.isSubOptionsVisible()) { | |
| for (DropdownItem subItem : item.getSubOptions()) { | |
| height += subItem.getTotalHeight(); | |
| } | |
| } | |
| } | |
| return height; | |
| } | |
| } | |
| /** | |
| * Inner class representing individual dropdown items, which can optionally have sub-options. | |
| */ | |
| private class DropdownItem { | |
| private String name; | |
| private List<DropdownItem> subOptions; | |
| private boolean subOptionsVisible = false; | |
| private boolean visible = false; | |
| private int posX, posY; | |
| private final DropdownItem parent; | |
| // Add TextFieldWidget for CopyChat | |
| private TextFieldWidget textField; | |
| private boolean textFieldVisible = false; | |
| public DropdownItem(String name, List<DropdownItem> subOptions, DropdownItem parent) { | |
| this.name = name; | |
| this.subOptions = subOptions; | |
| this.parent = parent; | |
| if (name.equals("CopyChat") || name.equals("Stare") || name.equals("Title")) { | |
| // Initialize the TextFieldWidget for both CopyChat and Stare | |
| this.textField = new TextFieldWidget(textRenderer, posX, posY + BUTTON_HEIGHT, DROPDOWN_WIDTH, BUTTON_HEIGHT, Text.literal("Enter Target")); | |
| this.textField.setVisible(false); | |
| // Set the initial value if available | |
| if (name.equals("CopyChat")) { | |
| String targetPlayerName = CopyChat.getTargetPlayerName(); | |
| if (targetPlayerName != null) { | |
| this.textField.setText(targetPlayerName); | |
| } | |
| } else if (name.equals("Stare")) { | |
| String targetEntityType = Stare.getTargetEntityType(); // Add a getter method for Stare target entity type | |
| if (targetEntityType != null) { | |
| this.textField.setText(targetEntityType); | |
| } | |
| } else if (name.equals("Title")) { | |
| // Set the initial value if available | |
| Title titleModule = (Title) ModuleManager.getInstance().getModuleByName("Title"); | |
| if (titleModule != null && titleModule.getCustomTitle() != null) { | |
| this.textField.setText(titleModule.getCustomTitle()); | |
| } | |
| } | |
| // Add to the screen's children to receive input events | |
| addSelectableChild(this.textField); | |
| } | |
| } | |
| /** | |
| * Checks if the item has sub-options. | |
| */ | |
| public boolean hasSubOptions() { | |
| return subOptions != null && !subOptions.isEmpty(); | |
| } | |
| /** | |
| * Retrieves the list of sub-options. | |
| */ | |
| public List<DropdownItem> getSubOptions() { | |
| return subOptions; | |
| } | |
| /** | |
| * Toggles the visibility of sub-options. | |
| */ | |
| public void toggleSubOptions() { | |
| if (hasSubOptions()) { | |
| subOptionsVisible = !subOptionsVisible; | |
| } | |
| } | |
| /** | |
| * Checks if sub-options are visible. | |
| */ | |
| public boolean isSubOptionsVisible() { | |
| return subOptionsVisible; | |
| } | |
| /** | |
| * Sets the position of the dropdown item. | |
| */ | |
| public void setPosition(int x, int y) { | |
| this.posX = x; | |
| this.posY = y; | |
| if (name.equals("CopyChat") || name.equals("Stare") || name.equals("Title") && textField != null) { | |
| textField.setX(x); | |
| textField.setY(y + BUTTON_HEIGHT); | |
| } | |
| } | |
| /** | |
| * Sets the visibility of the dropdown item. | |
| */ | |
| public void setVisible(boolean visible) { | |
| this.visible = visible; | |
| if (name.equals("CopyChat") || name.equals("Stare") || name.equals("Title") && textField != null) { | |
| textField.setVisible(textFieldVisible && visible); | |
| } | |
| } | |
| /** | |
| * Checks if the dropdown item is visible. | |
| */ | |
| public boolean isVisible() { | |
| return visible; | |
| } | |
| /** | |
| * Calculates the total height of this item, including text field if visible. | |
| */ | |
| public int getTotalHeight() { | |
| int totalHeight = BUTTON_HEIGHT; | |
| if (textFieldVisible && textField != null) { | |
| totalHeight += BUTTON_HEIGHT; | |
| } | |
| return totalHeight; | |
| } | |
| /** | |
| * Checks if the mouse is over this dropdown item. | |
| */ | |
| public boolean isMouseOver(double mouseX, double mouseY) { | |
| int totalHeight = getTotalHeight(); | |
| return mouseX >= posX && mouseX <= posX + DROPDOWN_WIDTH | |
| && mouseY >= posY && mouseY <= posY + totalHeight; | |
| } | |
| /** | |
| * Handles mouse clicks for this dropdown item. | |
| */ | |
| public boolean mouseClicked(double mouseX, double mouseY, int button) { | |
| if (textFieldVisible && textField != null && textField.isMouseOver(mouseX, mouseY)) { | |
| return textField.mouseClicked(mouseX, mouseY, button); | |
| } | |
| if (isMouseOver(mouseX, mouseY)) { | |
| if (button == 0) { // Left-click | |
| onLeftClick(); | |
| return true; | |
| } else if (button == 1) { // Right-click | |
| onRightClick(); | |
| return true; | |
| } | |
| } | |
| // Delegate to sub-options | |
| if (hasSubOptions() && isSubOptionsVisible()) { | |
| for (DropdownItem subItem : subOptions) { | |
| if (subItem.mouseClicked(mouseX, mouseY, button)) { | |
| return true; | |
| } | |
| } | |
| } | |
| return false; | |
| } | |
| /** | |
| * Handles key presses for the text field. | |
| */ | |
| public boolean keyPressed(int keyCode, int scanCode, int modifiers) { | |
| if (textFieldVisible && textField != null && textField.isFocused()) { | |
| if (keyCode == InputUtil.GLFW_KEY_ENTER || keyCode == InputUtil.GLFW_KEY_KP_ENTER) { | |
| // Save the player name | |
| onSaveTextField(); | |
| return true; | |
| } else { | |
| return textField.keyPressed(keyCode, scanCode, modifiers); | |
| } | |
| } | |
| return false; | |
| } | |
| /** | |
| * Handles character typing for the text field. | |
| */ | |
| public boolean charTyped(char chr, int modifiers) { | |
| if (textFieldVisible && textField != null && textField.isFocused()) { | |
| return textField.charTyped(chr, modifiers); | |
| } | |
| return false; | |
| } | |
| /** | |
| * Handles left-click actions. | |
| */ | |
| private void onLeftClick() { | |
| if (name.equals("Flavour") && parent != null && parent.name.equals("ClientSpoofer")) { | |
| // Cycle through the flavours | |
| cycleFlavour(); | |
| } else { | |
| toggleModule(name); | |
| } | |
| } | |
| /** | |
| * Handles right-click actions. | |
| */ | |
| private void onRightClick() { | |
| if (name.equals("CopyChat") || name.equals("Stare") || name.equals("Title")) { | |
| // Toggle the text field visibility | |
| textFieldVisible = !textFieldVisible; | |
| if (textField != null) { | |
| textField.setVisible(textFieldVisible && visible); | |
| if (textFieldVisible) { | |
| // Set focus to the text field | |
| setFocused(textField); | |
| textField.setFocused(true); | |
| } else { | |
| // Remove focus | |
| textField.setFocused(false); | |
| setFocused(null); | |
| } | |
| } | |
| // Update positions to account for the text field | |
| for (DropdownContainer dropdown : dropdowns.values()) { | |
| dropdown.updateItemPositions(); | |
| } | |
| } else if (hasSubOptions()) { | |
| toggleSubOptions(); | |
| } | |
| } | |
| /** | |
| * Handles saving the player name from the text field. | |
| */ | |
| private void onSaveTextField() { | |
| String inputText = textField.getText().trim(); | |
| if (!inputText.isEmpty()) { | |
| if (name.equals("CopyChat")) { | |
| CopyChat.setTargetPlayerName(inputText); | |
| client.player.sendMessage(Text.literal(Formatting.GREEN + "Now copying chat from: " + inputText), false); | |
| } else if (name.equals("Stare")) { | |
| Stare.setTargetEntityType(inputText); // Add a setter method for Stare target entity type | |
| client.player.sendMessage(Text.literal(Formatting.GREEN + "Now staring at entity type: " + inputText), false); | |
| } else if (name.equals("Title")) { | |
| Title titleModule = (Title) ModuleManager.getInstance().getModuleByName("Title"); | |
| if (titleModule != null) { | |
| titleModule.setCustomTitle(inputText); | |
| client.player.sendMessage(Text.literal(Formatting.GREEN + "Window title updated to: " + inputText), false); | |
| } | |
| } | |
| } else { | |
| client.player.sendMessage(Text.literal(Formatting.RED + "Please enter a valid target."), false); | |
| } | |
| textFieldVisible = false; | |
| textField.setVisible(false); | |
| textField.setFocused(false); | |
| setFocused(null); | |
| // Update positions to account for the text field being hidden | |
| for (DropdownContainer dropdown : dropdowns.values()) { | |
| dropdown.updateItemPositions(); | |
| } | |
| } | |
| /** | |
| * Cycles through the available flavours for ClientSpoofer. | |
| */ | |
| private void cycleFlavour() { | |
| // Get the current flavour | |
| IceCreamConfig.Flavour currentFlavour = IceCreamConfig.getInstance().getFlavour(); | |
| // Get all flavours | |
| IceCreamConfig.Flavour[] flavours = IceCreamConfig.Flavour.values(); | |
| // Find the index of the current flavour | |
| int index = Arrays.asList(flavours).indexOf(currentFlavour); | |
| // Move to the next flavour | |
| index = (index + 1) % flavours.length; | |
| // Set the new flavour | |
| IceCreamConfig.getInstance().setFlavour(flavours[index]); | |
| IceCreamConfigManager.saveConfig(); | |
| } | |
| /** | |
| * Renders the dropdown item. | |
| */ | |
| public void render(DrawContext context, int mouseX, int mouseY, float delta) { | |
| int color; | |
| String displayName = name; | |
| if (name.equals("Flavour") && parent != null && parent.name.equals("ClientSpoofer")) { | |
| IceCreamConfig.Flavour currentFlavour = IceCreamConfig.getInstance().getFlavour(); | |
| displayName = currentFlavour.name(); | |
| color = 0xAAAAAA; | |
| } else { | |
| Extension module = ModuleManager.getInstance().getModuleByName(name); | |
| color = (module != null && module.isEnabled()) ? 0x55FF55 : 0xAAAAAA; | |
| } | |
| // Draw the button text | |
| context.drawCenteredTextWithShadow(textRenderer, displayName, posX + DROPDOWN_WIDTH / 2, posY + (BUTTON_HEIGHT - 8) / 2, color); | |
| // Render the text field if visible | |
| if (textFieldVisible && textField != null) { | |
| textField.render(context, mouseX, mouseY, delta); | |
| } | |
| // Render sub-options if any | |
| if (hasSubOptions() && isSubOptionsVisible() && subOptions != null) { | |
| for (DropdownItem subItem : subOptions) { | |
| if (subItem.isVisible()) { | |
| subItem.render(context, mouseX, mouseY, delta); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment