package wtf.tokyoware.client.screen.clickgui;
import lombok.Getter;
import lombok.experimental.Accessors;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.settings.KeyBinding;
import net.minecraft.util.text.StringTextComponent;
import net.mojang.blaze3d.matrix.MatrixStack;
import org.joml.Vector2f;
import wtf.tokyoware.client.Tokyoware;
import wtf.tokyoware.client.api.interfaces.IMinecraft;
import wtf.tokyoware.client.api.interfaces.IMouse;
import wtf.tokyoware.client.api.interfaces.IWindow;
import wtf.tokyoware.client.screen.clickgui.component.Panel;
import wtf.tokyoware.client.screen.clickgui.component.category.CategoryComponent;
import wtf.tokyoware.client.screen.clickgui.component.module.ModuleComponent;
import wtf.tokyoware.client.screen.clickgui.component.setting.impl.StringSettingComponent;
import wtf.tokyoware.client.utils.animation.Animation;
import wtf.tokyoware.client.utils.keyboard.Keyboard;
import wtf.tokyoware.client.utils.math.ScaleMath;
import wtf.tokyoware.client.utils.other.SoundUtil;
import wtf.tokyoware.client.utils.render.color.ColorUtil;
import wtf.tokyoware.client.utils.render.draw.RectUtil;
import wtf.tokyoware.client.utils.render.font.Font;
import wtf.tokyoware.client.utils.render.font.Fonts;
import wtf.tokyoware.client.utils.render.text.TextAlign;
import wtf.tokyoware.client.utils.render.text.TextBox;
@Getter
@Accessors(fluent = true)
public class ClickGuiScreen extends Screen implements IMinecraft, IWindow, IMouse {
private boolean exit = false;
private final Animation alpha = new Animation();
private final Animation scale = new Animation();
private final float categoryWidth = 110, categoryHeight = 20, categoryOffset = 10;
private final Panel panel = new Panel(this);
private final TextBox searchField = new TextBox(new Vector2f(), Fonts.SF_MEDIUM, 10, ColorUtil.getColor(255, 255, 255), TextAlign.CENTER, "Поиск: ", 0, false, false);
private boolean hasResized = false;
public ClickGuiScreen() {
super(StringTextComponent.EMPTY);
}
@Override
public void resize(Minecraft minecraft, int width, int height) {
super.resize(minecraft, width, height);
this.panel.resize(minecraft, width, height);
hasResized = true;
}
@Override
protected void init() {
super.init();
SoundUtil.playSound("guiopen.wav", 0.75);
Tokyoware.inst().configManager().set();
searchField.setText("");
searchField.setSelected(false);
alpha.set(1.0);
scale.set(1.0);
exit = false;
hasResized = false;
int width = mc.getMainWindow().getScaledWidth();
int height = mc.getMainWindow().getScaledHeight();
this.panel.resize(mc, width, height);
panel.init();
}
@Override
public void render(MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) {
if (!hasResized) {
resize(mc, mc.getMainWindow().getScaledWidth(), mc.getMainWindow().getScaledHeight());
}
Vector2f mouse = ScaleMath.getMouse(mouseX, mouseY);
int finalMouseX = (int) mouse.x;
int finalMouseY = (int) mouse.y;
draw(matrixStack, finalMouseX, finalMouseY, partialTicks);
}
public void draw(MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) {
this.mouseCheck();
this.closeCheck();
RectUtil.drawRect(matrixStack, 0, 0, scaled().x, scaled().y, ColorUtil.getColor(0, 0, 0, 0.5f));
if (!searchField.isSelected()) {
renderSearchField(matrixStack);
}
this.drawPanel(matrixStack, mouseX, mouseY, partialTicks);
renderHoveredModuleDescription(matrixStack, mouseX, mouseY);
if (searchField.isSelected()) {
renderSearchField(matrixStack);
}
}
private void renderHoveredModuleDescription(MatrixStack matrixStack, int mouseX, int mouseY) {
for (CategoryComponent category : panel.getCategoryComponents()) {
if (!category.isExactlyHovered(mouseX, mouseY)) continue;
float contentStartY = category.position().y + category.size().y;
float contentEndY = contentStartY + category.getMaxVisibleHeight();
for (ModuleComponent module : category.getModuleComponents()) {
if (Tokyoware.inst().clickGui().searchCheck(module.getModule().getName())) continue;
float moduleTopY = module.position().y;
float moduleBottomY = moduleTopY + module.size().y;
boolean isModuleVisible = (moduleBottomY > contentStartY) && (moduleTopY < contentEndY);
if (!isModuleVisible) continue;
if (module.isHovered() && !module.getModule().getDescription().isEmpty()) {
String description = module.getModule().getDescription();
float centerX = scaled().x / 2f;
float topY = 50f;
float maxWidth = scaled().x * 0.8f;
Font font = Fonts.SF_MEDIUM;
float fontSize = 10f;
float textWidth = font.getWidth(description, fontSize);
if (textWidth > maxWidth) {
String[] words = description.split(" ");
StringBuilder currentLine = new StringBuilder();
float lineHeight = fontSize * 1.5f;
float currentY = topY;
for (String word : words) {
String testLine = currentLine.length() > 0 ? currentLine + " " + word : word;
if (font.getWidth(testLine, fontSize) <= maxWidth) {
if (currentLine.length() > 0) currentLine.append(" ");
currentLine.append(word);
} else {
font.drawCenter(matrixStack, currentLine.toString(), centerX, currentY,
ColorUtil.getColor(255, 255, 255, 1.0f), fontSize);
currentY += lineHeight;
currentLine = new StringBuilder(word);
}
}
if (currentLine.length() > 0) {
font.drawCenter(matrixStack, currentLine.toString(), centerX, currentY,
ColorUtil.getColor(255, 255, 255, 1.0f), fontSize);
}
} else {
font.drawCenter(matrixStack, description, centerX, topY,
ColorUtil.getColor(255, 255, 255, 1.0f), fontSize);
}
return;
}
}
}
}
private void renderSearchField(MatrixStack matrixStack) {
searchField.setEmptyText("Поиск функции");
float searchFieldHeight = searchField.getFontSize() * 2.1F;
double searchFieldX = (scaled().x / 2F);
double searchFieldY = (scaled().y - (scaled().y / 6F));
float searchWidth = isSearching() ? searchField.getFont().getWidth(searchField.getText(), searchField.getFontSize()) + 20F : searchField.getFont().getWidth(searchField.getEmptyText(), searchField.getFontSize()) + 20F;
searchField.position.set(searchFieldX, searchFieldY + ((searchFieldHeight / 2F) - (searchField.getFontSize() / 2F)));
searchField.setWidth(150);
searchField.setColor(ColorUtil.getColor(128, 1.0f));
int color = ColorUtil.getColor(0, 0, 0, 0.5f);
int shadowColor = ColorUtil.getColor(0, 0, 0, 0.25f);
boolean bloom = false;
float round = 5, shadow = 6;
RectUtil.drawRoundedRectShadowed(matrixStack, searchFieldX - (searchWidth / 2F), searchFieldY, searchWidth, searchFieldHeight, round, shadow, shadowColor, shadowColor, shadowColor, shadowColor, bloom, true, true, true);
RectUtil.drawRoundedRectShadowed(matrixStack, searchFieldX - (searchWidth / 2F), searchFieldY, searchWidth, searchFieldHeight, round, 0.5F, color, color, color, color, false, false, true, true);
searchField.draw(matrixStack);
}
private void drawPanel(MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) {
panel.render(matrixStack, mouseX, mouseY, partialTicks);
}
@Override
public boolean mouseClicked(double mouseX, double mouseY, int button) {
Vector2f mouse = ScaleMath.getMouse(mouseX, mouseY);
int finalMouseX = (int) mouse.x;
int finalMouseY = (int) mouse.y;
if (!exit) {
if (isHover(mouseX, mouseY, searchField.position.x - 75, searchField.position.y - searchField.getFontSize() / 2, 150, searchField.getFontSize() * 2.5)) {
searchField.setSelected(true);
return true;
}
if (searchField.isSelected() && !isHover(mouseX, mouseY, searchField.position.x - 75, searchField.position.y - searchField.getFontSize() / 2, 150, searchField.getFontSize() * 2.5)) {
searchField.setSelected(false);
}
if (!searchField.isSelected()) {
panel.mouseClicked(finalMouseX, finalMouseY, button);
}
}
return super.mouseClicked(mouseX, mouseY, button);
}
@Override
public boolean mouseReleased(double mouseX, double mouseY, int button) {
Vector2f mouse = ScaleMath.getMouse(mouseX, mouseY);
int finalMouseX = (int) mouse.x;
int finalMouseY = (int) mouse.y;
if (!searchField.isSelected()) {
panel.mouseReleased(finalMouseX, finalMouseY, button);
}
return super.mouseReleased(mouseX, mouseY, button);
}
@Override
public boolean mouseScrolled(double mouseX, double mouseY, double delta) {
if (exit || searchField.isSelected()) {
return super.mouseScrolled(mouseX, mouseY, delta);
}
Vector2f mouse = ScaleMath.getMouse(mouseX, mouseY);
int finalMouseX = (int) mouse.x;
int finalMouseY = (int) mouse.y;
boolean foundHoveredCategory = false;
for (CategoryComponent category : panel.getCategoryComponents()) {
if (category.isExactlyHovered(finalMouseX, finalMouseY)) {
foundHoveredCategory = true;
if (category.getCalculatedTotalModuleHeight() > category.getMaxVisibleHeight()) {
category.getCategoryScroll().setTarget(
category.getCategoryScroll().getTarget() + (float) (delta * 10));
return true;
}
break;
}
}
if (!foundHoveredCategory) {
return true;
}
return super.mouseScrolled(mouseX, mouseY, delta);
}
@Override
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
if (!exit) {
if (searchField.isSelected() && keyCode == Keyboard.KEY_DELETE.getKey()) {
searchField.setSelected(false);
return true;
}
if (Keyboard.isKeyDown(Keyboard.KEY_LEFT_CONTROL.getKey()) && keyCode == Keyboard.KEY_F.getKey()) {
searchField.setSelected(!searchField.isSelected());
}
searchField.keyPressed(keyCode);
if (!searchField.isSelected()) {
panel.keyPressed(keyCode, scanCode, modifiers);
}
}
return super.keyPressed(keyCode, scanCode, modifiers);
}
@Override
public boolean keyReleased(int keyCode, int scanCode, int modifiers) {
panel.keyReleased(keyCode, scanCode, modifiers);
return super.keyReleased(keyCode, scanCode, modifiers);
}
@Override
public boolean charTyped(char codePoint, int modifiers) {
if (!exit) {
searchField.charTyped(codePoint);
if (!searchField.isSelected()) {
panel.charTyped(codePoint, modifiers);
}
}
return super.charTyped(codePoint, modifiers);
}
@Override
public boolean shouldCloseOnEsc() {
boolean noneMatch = panel.getCategoryComponents().stream().noneMatch(category -> category.getModuleComponents().stream().anyMatch(ModuleComponent::isBinding));
if (!exit && noneMatch) {
alpha.set(0.0);
scale.set(0.0);
exit = true;
SoundUtil.playSound("guiclose.wav", 0.75);
mc.mouseHelper.forceGrabMouse(false);
mc.displayScreen(null);
return true;
}
return true;
}
@Override
public boolean isPauseScreen() {
return false;
}
@Override
public void onClose() {
super.onClose();
Tokyoware.inst().configManager().set();
panel.onClose();
searchField.setText("");
searchField.setSelected(false);
}
private void mouseCheck() {
boolean noneMatch = panel.getCategoryComponents()
.stream()
.noneMatch(category -> category.getModuleComponents()
.stream()
.anyMatch(module -> module.settingComponents
.stream()
.anyMatch(settingComponent -> settingComponent instanceof StringSettingComponent component && component.textBox.selected)
)
);
if (!Minecraft.IS_RUNNING_ON_MAC && noneMatch) {
KeyBinding.updateKeyBindState();
}
if (mc.mouseHelper.isMouseGrabbed()) {
mc.mouseHelper.ungrabMouse();
}
}
private void closeCheck() {
boolean noneMatch = panel.getCategoryComponents().stream().noneMatch(category -> category.getModuleComponents().stream().anyMatch(ModuleComponent::isBinding));
if (exit && noneMatch) {
mc.displayScreen(null);
exit = false;
}
}
public boolean isSearching() {
return !searchField.isEmpty();
}
public String getSearchText() {
return searchField.getText();
}
public boolean searchCheck(String text) {
return isSearching() && !text
.replaceAll(" ", "")
.trim()
.toLowerCase()
.contains(getSearchText()
.replaceAll(" ", "")
.trim()
.toLowerCase());
}
}