aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/de/torui/coflsky/gui/bingui
diff options
context:
space:
mode:
authormatthias-luger <58751503+matthias-luger@users.noreply.github.com>2023-02-17 17:32:26 +0100
committerGitHub <noreply@github.com>2023-02-17 17:32:26 +0100
commit8f3bce7d6fe41e85f2654f7557bbb564305e58b5 (patch)
tree4bae9237e3c0b87bf27e5f590f4c0ca91b145cab /src/main/java/de/torui/coflsky/gui/bingui
parente43d5685fdf0d436d5836d06c5d3f15da674e7df (diff)
downloadCOFL-8f3bce7d6fe41e85f2654f7557bbb564305e58b5.tar.gz
COFL-8f3bce7d6fe41e85f2654f7557bbb564305e58b5.tar.bz2
COFL-8f3bce7d6fe41e85f2654f7557bbb564305e58b5.zip
Add TFM Purchase UI to Mod (#78)
* Add TFM Purchase UI to Mod * fix up opening flips by hotkey fix up flip message in tfm ui * readded check if the auction should be drawn mod doesnt crash anymore if a non flip auction is opened * added /cofl set gui command changed gui title * added /fc toggle command dont store toggle locally * rename purchaseOverlay config removed unused code renamed gui command to /cofl set ahbuygui * fix message not available if flip opened by mouse fix old message shown for non flip auctions * added /cofl setGui command added cofl purchase gui * Add sound on flip * Fixed new flip sound Optimized cofl gui Removed flickering of default mc gui Move mouse to middle on screen open * remove unused code * remove debug code * don't open guis if not in skyblock * fix sound being null * fix bed flips fix opening /cofl blocked * remove logging * Rewrote cofl gui to render before the chest gui opens * - fix bed flips - invalidate best flips after open * - fix scrolling * - fix description not updating - case insensitive commands - fix up , at the end of the message * - add gui if item was already bought - fix bug that invalidated too many flips - added missing "break" * fix merge error * add .vscode to gitignore formatting * fix formatting issue * - remove comment - remove emty line
Diffstat (limited to 'src/main/java/de/torui/coflsky/gui/bingui')
-rw-r--r--src/main/java/de/torui/coflsky/gui/bingui/BinGuiCurrent.java415
-rw-r--r--src/main/java/de/torui/coflsky/gui/bingui/BinGuiManager.java19
-rw-r--r--src/main/java/de/torui/coflsky/gui/bingui/BuyState.java8
-rw-r--r--src/main/java/de/torui/coflsky/gui/bingui/helper/ColorPallet.java25
-rw-r--r--src/main/java/de/torui/coflsky/gui/bingui/helper/GuiUtilsClone.java349
-rw-r--r--src/main/java/de/torui/coflsky/gui/bingui/helper/RenderUtils.java367
6 files changed, 1183 insertions, 0 deletions
diff --git a/src/main/java/de/torui/coflsky/gui/bingui/BinGuiCurrent.java b/src/main/java/de/torui/coflsky/gui/bingui/BinGuiCurrent.java
new file mode 100644
index 0000000..ef5ec9c
--- /dev/null
+++ b/src/main/java/de/torui/coflsky/gui/bingui/BinGuiCurrent.java
@@ -0,0 +1,415 @@
+package de.torui.coflsky.gui.bingui;
+
+
+import de.torui.coflsky.CoflSky;
+import de.torui.coflsky.gui.GUIType;
+import de.torui.coflsky.gui.bingui.helper.ColorPallet;
+import de.torui.coflsky.gui.bingui.helper.RenderUtils;
+import de.torui.coflsky.handlers.EventHandler;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.GuiScreen;
+import net.minecraft.client.gui.inventory.GuiChest;
+import net.minecraft.command.NumberInvalidException;
+import net.minecraft.init.Items;
+import net.minecraft.inventory.ContainerChest;
+import net.minecraft.inventory.IInventory;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemArmor;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.nbt.NBTTagList;
+import net.minecraft.util.ChatComponentText;
+import net.minecraft.util.EnumChatFormatting;
+import net.minecraft.util.ResourceLocation;
+import net.minecraftforge.client.event.ClientChatReceivedEvent;
+import net.minecraftforge.client.event.GuiOpenEvent;
+import net.minecraftforge.client.event.GuiScreenEvent;
+import net.minecraftforge.common.MinecraftForge;
+import net.minecraftforge.fml.common.eventhandler.EventPriority;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+import net.minecraftforge.fml.common.gameevent.TickEvent;
+import org.lwjgl.input.Mouse;
+
+import java.awt.event.MouseWheelEvent;
+import java.util.Base64;
+import java.util.List;
+import java.util.Locale;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class BinGuiCurrent extends GuiChest {
+ private String message;
+ private String[] lore;
+ private ItemStack itemStack;
+ private String buyText = "Buy(You can click anywhere)";
+ private BuyState buyState = BuyState.INIT;
+ private int pixelsScrolled = 0;
+ private boolean wasMouseDown;
+ private boolean isRendered = false;
+ private boolean hasInitialMouseSet = false;
+
+ // set if the auction was already bought
+ private String buyer = null;
+
+ private static final Pattern CAN_BUY_IN_MATCHER = Pattern.compile("Can buy in: (.*)");
+ private static final Pattern BUYER_MATCHER = Pattern.compile("Buyer: (.*)");
+
+ private GuiChest chestGui;
+
+ public BinGuiCurrent(IInventory playerInventory, IInventory chestInventory, String message, String extraData) {
+ super(chestInventory, playerInventory);
+ this.message = message;
+ this.lore = new String[]{"Loading..."};
+ if (extraData.length() >= 32) {
+ itemStack = getSkull("Name", "00000000-0000-0000-0000-000000000000", extraData);
+ } else {
+ itemStack = new ItemStack(getItemByText(extraData));
+ //if it is an armor item, we color it black
+ if (itemStack.getItem() == null) return;
+ if (itemStack.getItem() instanceof ItemArmor && (itemStack.getItem() == Items.leather_helmet || itemStack.getItem() == Items.leather_chestplate || itemStack.getItem() == Items.leather_leggings || itemStack.getItem() == Items.leather_boots)) {
+ ((ItemArmor) itemStack.getItem()).setColor(itemStack, 0);
+ }
+ }
+ MinecraftForge.EVENT_BUS.register(this);
+ }
+
+ private boolean shouldSkip(GuiScreen screen) {
+ return !(screen instanceof GuiChest) || CoflSky.config.purchaseOverlay != GUIType.COFL || !EventHandler.isInSkyblock;
+ }
+
+ @SubscribeEvent(priority = EventPriority.HIGHEST)
+ public void onGuiOpen(GuiOpenEvent event) {
+
+ if (event.gui == null) {
+ resetGUI();
+ }
+
+ isRendered = false;
+ GuiScreen gui = event.gui;
+
+ if (message == null || message.isEmpty()) {
+ return;
+ }
+
+ if (shouldSkip(gui)) {
+ return;
+ }
+
+ GuiChest chest = (GuiChest) gui;
+
+ IInventory inventory = ((ContainerChest) chest.inventorySlots).getLowerChestInventory();
+ if (inventory == null) return;
+
+ String guiName = inventory.getDisplayName().getUnformattedText().trim();
+ if (guiName.equalsIgnoreCase("BIN Auction View") || guiName.equalsIgnoreCase("Confirm Purchase")) {
+ this.chestGui = (GuiChest) event.gui;
+ this.inventorySlots = ((GuiChest) event.gui).inventorySlots;
+ event.gui = this;
+ }
+ }
+
+ @SubscribeEvent(priority = EventPriority.HIGHEST)
+ public void onDrawGuiScreen(GuiScreenEvent.DrawScreenEvent.Pre event) {
+ isRendered = false;
+ GuiScreen gui = event.gui;
+
+ if (message == null || message.isEmpty()) {
+ return;
+ }
+
+ if (shouldSkip(gui)) {
+ return;
+ }
+
+ GuiChest chest = (GuiChest) gui;
+
+ IInventory inventory = ((ContainerChest) chest.inventorySlots).getLowerChestInventory();
+ if (inventory == null) return;
+
+ String guiName = inventory.getDisplayName().getUnformattedText().trim();
+ if (guiName.equalsIgnoreCase("auction view")) {
+ return;
+ }
+
+ ItemStack item = inventory.getStackInSlot(13);
+ if (item == null) return;
+
+ String[] tooltip = item.getTooltip(mc.thePlayer, false).toArray(new String[0]);
+
+ itemStack = item;
+
+ if (guiName.equalsIgnoreCase("BIN Auction View")) {
+ lore = tooltip;
+ buyer = isAlreadyBought(tooltip);
+ }
+ if (guiName.equalsIgnoreCase("BIN Auction View") && buyState == BuyState.PURCHASE) {
+ if (waitingForBed(chest)) {
+ Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("[§1C§6oflnet§f]§7: §cBed is not purchasable yet."));
+ buyState = BuyState.INIT;
+ } else {
+ mc.playerController.windowClick(this.chestGui.inventorySlots.windowId, 31, 2, 3, mc.thePlayer);
+ wasMouseDown = false;
+ buyState = BuyState.CONFIRM;
+ }
+ } else if (guiName.equalsIgnoreCase("Confirm Purchase") && buyState == BuyState.BUYING) {
+ mc.playerController.windowClick(this.chestGui.inventorySlots.windowId, 11, 2, 3, mc.thePlayer);
+ resetGUI();
+ }
+ }
+
+ @Override
+ public void drawScreen(int mouseX, int mouseY, float partialTicks) {
+ Mouse.setGrabbed(false);
+ isRendered = true;
+
+ int screenWidth = this.width;
+ int screenHeight = this.height;
+
+ int width = mc.fontRendererObj.getStringWidth(message) > 500 ? mc.fontRendererObj.getStringWidth(message) + 5 : 500;
+ int height = 300;
+
+ //RenderUtils.drawRoundedRect(screenWidth / 2, 10 + 5 + 14 + 5 + (height - 100) + 5, (width - 10) / 2 + 20, 60, 5, ColorPallet.SUCCESS.getColor());
+ if (!hasInitialMouseSet) {
+ Mouse.setCursorPosition(mc.displayWidth / 2, mc.displayHeight / 2);
+ hasInitialMouseSet = true;
+ }
+
+ //if (lore.length > 25) {
+ // height = 300 + (lore.length - 25) * 10;
+ //}
+
+ //first i draw the main background
+ RenderUtils.drawRoundedRect(screenWidth / 2 - width / 2, 10, width, height, 10, ColorPallet.PRIMARY.getColor());
+
+ //next i draw the title
+ RenderUtils.drawRoundedRect(screenWidth / 2 - width / 2 + 5, 10 + 5, (width - 10), 14, 5, ColorPallet.SECONDARY.getColor());
+ RenderUtils.drawString(message, screenWidth / 2 - width / 2 + 7, 10 + 8, ColorPallet.WHITE.getColor());
+
+ //now i draw the backround of the icon
+ RenderUtils.drawRoundedRect(screenWidth / 2 - width / 2 + 5, 10 + 5 + 14 + 5, 20, 20, 5, ColorPallet.TERTIARY.getColor());
+
+ //now i draw the icon
+ if (itemStack == null) {
+ //draw a question mark in the icon
+ RenderUtils.drawString("?", screenWidth / 2 - width / 2 + 5 + 5, 10 + 5 + 14 + 5 + 2, ColorPallet.WHITE.getColor(), 40);
+ } else {
+ RenderUtils.drawItemStack(itemStack, screenWidth / 2 - width / 2 + 5 + 2, 10 + 5 + 14 + 5 + 2);
+ }
+
+
+ //draw the backorund for the lore
+ RenderUtils.drawRoundedRect(screenWidth / 2 - width / 2 + 5 + 20 + 5, 10 + 5 + 14 + 5, (width - 10) - 25, (height - 100), 5, ColorPallet.SECONDARY.getColor());
+
+ //draw the lore, every line that is out of the lore background will not be drawn
+ int y = 10 + 5 + 14 + 5 + 2;
+ for (int i = 0; i < lore.length; i++) {
+ if (y + pixelsScrolled > 10 + 5 + 14 + 5 && y + pixelsScrolled < 10 + 5 + 14 + 5 + (height - 100)) {
+ RenderUtils.drawString(lore[i], screenWidth / 2 - width / 2 + 5 + 20 + 5 + 2, y + pixelsScrolled, ColorPallet.WHITE.getColor());
+ }
+ y += 10;
+ }
+
+
+ //now i draw the buttons buy and sell under the lore
+ //cancel button
+ RenderUtils.drawRoundedRect(screenWidth / 2 - width / 2 + 5, 10 + 5 + 14 + 5 + (height - 100) + 5, (width - 10) / 2 - 25, 60, 5, ColorPallet.ERROR.getColor());
+ RenderUtils.drawString("Cancel", screenWidth / 2 - width / 2 + 5 + 5, 10 + 5 + 14 + 5 + (height - 100) + 5 + 5, ColorPallet.WHITE.getColor(), 40);
+ if (isMouseOverCancel(mouseX, mouseY, screenWidth, screenHeight, width, height)) {
+ RenderUtils.drawRoundedRect(screenWidth / 2 - width / 2 + 5, 10 + 5 + 14 + 5 + (height - 100) + 5, (width - 10) / 2 - 25, 60, 5, RenderUtils.setAlpha(ColorPallet.WHITE.getColor(), 100));
+ RenderUtils.drawString("Cancel", screenWidth / 2 - width / 2 + 5 + 5, 10 + 5 + 14 + 5 + (height - 100) + 5 + 5, ColorPallet.WHITE.getColor(), 40);
+ if (isClicked()) {
+ //play a anvilsound
+ mc.thePlayer.playSound("random.anvil_land", 1, 1);
+ resetGUI();
+ mc.thePlayer.closeScreen();
+ }
+ }
+
+
+ //buy button
+ if (buyer == null) {
+ RenderUtils.drawRoundedRect(screenWidth / 2 - width / 2 + 5 + (width - 10) / 2 - 20, 10 + 5 + 14 + 5 + (height - 100) + 5, (width - 10) / 2 + 20, 60, 5, ColorPallet.SUCCESS.getColor());
+ RenderUtils.drawString(buyText, screenWidth / 2 - width / 2 + 5 + (width - 10) / 2 + 5 - 20, 10 + 5 + 14 + 5 + (height - 100) + 5 + 5, ColorPallet.WHITE.getColor(), 40);
+ } else {
+ RenderUtils.drawRoundedRect(screenWidth / 2 - width / 2 + 5 + (width - 10) / 2 - 20, 10 + 5 + 14 + 5 + (height - 100) + 5, (width - 10) / 2 + 20, 60, 5, ColorPallet.WARNING.getColor());
+ RenderUtils.drawString(getAlreadyBoughtText(buyer), screenWidth / 2 - width / 2 + 5 + (width - 10) / 2 + 5 - 20, 10 + 5 + 14 + 5 + (height - 100) + 5 + 5, ColorPallet.WHITE.getColor(), 40);
+ }
+ if (!isMouseOverCancel(mouseX, mouseY, screenWidth, screenHeight, width, height)) {
+ if (buyer == null) {
+ RenderUtils.drawRoundedRect(screenWidth / 2 - width / 2 + 5 + (width - 10) / 2 - 20, 10 + 5 + 14 + 5 + (height - 100) + 5, (width - 10) / 2 + 20, 60, 5, RenderUtils.setAlpha(ColorPallet.WHITE.getColor(), 50));
+ RenderUtils.drawString(buyText, screenWidth / 2 - width / 2 + 5 + (width - 10) / 2 + 5 - 20, 10 + 5 + 14 + 5 + (height - 100) + 5 + 5, ColorPallet.WHITE.getColor(), 40);
+ }
+ if (isClicked() && buyer == null) {
+ if (buyState == BuyState.INIT) {
+ //play a sound
+ mc.thePlayer.playSound("random.click", 1, 1);
+ buyText = "Click again to confirm";
+ buyState = BuyState.PURCHASE;
+ } else if (buyState == BuyState.CONFIRM) {
+ mc.thePlayer.playSound("random.click", 1, 1);
+ buyText = "Buying";
+ buyState = BuyState.BUYING;
+ }
+ }
+ }
+
+ }
+
+ public String getAlreadyBoughtText(String buyer) {
+ return "§5§o§7Bought by §b" + buyer;
+ }
+
+ @SubscribeEvent
+ public void onGuiMouseInput(GuiScreenEvent.MouseInputEvent event) {
+ if (event.gui instanceof BinGuiCurrent) {
+ int dwheel = Mouse.getDWheel();
+ pixelsScrolled += dwheel / 4;
+ }
+ }
+
+ public void resetGUI() {
+ buyState = BuyState.INIT;
+ buyText = "Buy (You can click anywhere)";
+ itemStack = null;
+ hasInitialMouseSet = false;
+ isRendered = false;
+ Mouse.setGrabbed(true);
+ MinecraftForge.EVENT_BUS.unregister(this);
+ }
+
+ public static Item getItemByText(String id) {
+ try {
+ ResourceLocation resourcelocation = new ResourceLocation(id);
+ if (!Item.itemRegistry.containsKey(resourcelocation)) {
+ throw new NumberInvalidException("block.notFound", resourcelocation);
+ }
+ Item item = Item.itemRegistry.getObject(resourcelocation);
+ if (item == null) {
+ throw new NumberInvalidException("block.notFound", resourcelocation);
+ }
+ return item;
+ } catch (Exception e) {
+ System.out.println("Error: " + e.getMessage());
+ return null;
+ }
+
+ }
+
+ public static ItemStack getSkull(String displayName, String uuid, String value) {
+ String url = "https://textures.minecraft.net/texture/" + value;
+ ItemStack render = new ItemStack(Items.skull, 1, 3);
+
+ NBTTagCompound skullOwner = new NBTTagCompound();
+ skullOwner.setString("Id", uuid);
+ skullOwner.setString("Name", uuid);
+
+ byte[] encodedData = Base64.getEncoder().encode(String.format("{textures:{SKIN:{url:\"%s\"}}}", url).getBytes());
+ NBTTagCompound textures_0 = new NBTTagCompound();
+ textures_0.setString("Value", new String(encodedData));
+
+ NBTTagList textures = new NBTTagList();
+ textures.appendTag(textures_0);
+
+ NBTTagCompound display = new NBTTagCompound();
+ display.setString("Name", displayName);
+
+ NBTTagCompound tag = new NBTTagCompound();
+ tag.setTag("display", display);
+
+ NBTTagCompound properties = new NBTTagCompound();
+ properties.setTag("textures", textures);
+ skullOwner.setTag("Properties", properties);
+ tag.setTag("SkullOwner", skullOwner);
+ render.setTagCompound(tag);
+ return render;
+ }
+
+ @SubscribeEvent
+ public void onChatEvent(ClientChatReceivedEvent event) {
+ String message = event.message.getFormattedText().toLowerCase(Locale.ROOT);
+ if (
+ message.contains("you have bought") ||
+ message.contains("you don't have enough coins") ||
+ message.contains("this auction wasn't found") ||
+ message.contains("there was an error with the auction house") ||
+ message.contains("you didn't participate in this auction") ||
+ message.contains("you claimed") ||
+ message.contains("you purchased") ||
+ message.contains("you cannot view this auction")
+ ) {
+ //close the gui
+ resetGUI();
+ mc.thePlayer.closeScreen();
+ }
+ }
+
+ public ItemStack getItem(int slotNum, GuiChest currentScreen) {
+ ContainerChest container = (ContainerChest) currentScreen.inventorySlots;
+ return container.getSlot(slotNum).getStack();
+ }
+
+ public boolean waitingForBed(GuiChest currentScreen) {
+ ItemStack bedStack = getItem(31, currentScreen);
+ if (bedStack == null || !bedStack.getItem().equals(Item.getByNameOrId("minecraft:bed"))) {
+ return false;
+ }
+
+ ItemStack itemStack = getItem(13, currentScreen);
+ if (itemStack == null) {
+ return false;
+ }
+ List<String> itemTooltip = itemStack.getTooltip(Minecraft.getMinecraft().thePlayer, false);
+ for (String data : itemTooltip) {
+ Matcher matcher = CAN_BUY_IN_MATCHER.matcher(EnumChatFormatting.getTextWithoutFormattingCodes(data));
+ if (!matcher.find()) {
+ continue;
+ }
+ String timeData = matcher.group(1);
+ if (timeData.equals("Soon!")) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public String isAlreadyBought(String[] tooltip) {
+ for (String data : tooltip) {
+ Matcher matcher = BUYER_MATCHER.matcher(EnumChatFormatting.getTextWithoutFormattingCodes(data));
+ if (!matcher.find()) {
+ continue;
+ }
+ return data.replaceAll("§5§o§7Buyer: ", "");
+ }
+ return null;
+ }
+
+ private static boolean isMouseOverCancel(int mouseX, int mouseY, int screenWidth, int screenHeight, int width, int height) {
+ return mouseX > screenWidth / 2 - width / 2 + 5 && mouseX < screenWidth / 2 - width / 2 + 5 + (width - 10) / 2 - 25 && mouseY > 10 + 5 + 14 + 5 + (height - 100) + 5 && mouseY < 10 + 5 + 14 + 5 + (height - 100) + 5 + 60;
+ }
+
+ private static boolean isMouseOverAccept(int mouseX, int mouseY, int screenWidth, int screenHeight, int width, int height) {
+ return mouseX > screenWidth / 2 - width / 2 + 5 + (width - 10) / 2 - 20 && mouseX < (screenWidth / 2 - width / 2 + 5 + (width - 10) / 2 - 20) + (width - 10) / 2 + 20 && mouseY > 10 + 5 + 14 + 5 + (height - 100) + 5 && mouseY < 10 + 5 + 14 + 5 + (height - 100) + 5 + 60;
+ }
+
+ public boolean isClicked() {
+ return wasMouseDown && !Mouse.isButtonDown(0);
+ }
+
+ @SubscribeEvent
+ public void onRenderEvent(TickEvent.RenderTickEvent event) {
+ if (Minecraft.getMinecraft() == null) return;
+ if (event.phase == TickEvent.Phase.END) {
+ wasMouseDown = Mouse.isButtonDown(0);
+ }
+ }
+
+ @SubscribeEvent
+ public void onMouseClicked(GuiScreenEvent.MouseInputEvent.Pre event) {
+ if (!Mouse.getEventButtonState()) {
+ return;
+ }
+ if (isRendered) {
+ event.setCanceled(true);
+ }
+ }
+}
diff --git a/src/main/java/de/torui/coflsky/gui/bingui/BinGuiManager.java b/src/main/java/de/torui/coflsky/gui/bingui/BinGuiManager.java
new file mode 100644
index 0000000..db0b110
--- /dev/null
+++ b/src/main/java/de/torui/coflsky/gui/bingui/BinGuiManager.java
@@ -0,0 +1,19 @@
+package de.torui.coflsky.gui.bingui;
+
+import de.torui.coflsky.CoflSky;
+import de.torui.coflsky.gui.GUIType;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.inventory.GuiChest;
+import org.lwjgl.input.Mouse;
+
+public class BinGuiManager {
+
+ public static void openNewFlipGui(String message, String extraData) {
+ if( CoflSky.config.purchaseOverlay != GUIType.COFL){
+ return;
+ }
+ GuiChest currentGui = new BinGuiCurrent(Minecraft.getMinecraft().thePlayer.inventory, null, message, extraData);
+ Mouse.setGrabbed(false);
+ Minecraft.getMinecraft().displayGuiScreen(currentGui);
+ }
+} \ No newline at end of file
diff --git a/src/main/java/de/torui/coflsky/gui/bingui/BuyState.java b/src/main/java/de/torui/coflsky/gui/bingui/BuyState.java
new file mode 100644
index 0000000..7e935e2
--- /dev/null
+++ b/src/main/java/de/torui/coflsky/gui/bingui/BuyState.java
@@ -0,0 +1,8 @@
+package de.torui.coflsky.gui.bingui;
+
+public enum BuyState {
+ INIT,
+ PURCHASE,
+ CONFIRM,
+ BUYING
+}
diff --git a/src/main/java/de/torui/coflsky/gui/bingui/helper/ColorPallet.java b/src/main/java/de/torui/coflsky/gui/bingui/helper/ColorPallet.java
new file mode 100644
index 0000000..c67f9be
--- /dev/null
+++ b/src/main/java/de/torui/coflsky/gui/bingui/helper/ColorPallet.java
@@ -0,0 +1,25 @@
+package de.torui.coflsky.gui.bingui.helper;
+
+import java.awt.*;
+
+public enum ColorPallet {
+ //could be changed through a config or something
+ PRIMARY(new Color(34, 40, 49, 255)),
+ SECONDARY(new Color(57, 62, 70, 255)),
+ TERTIARY(new Color(0, 173, 181, 255)),
+ WHITE(new Color(238, 238, 238, 255)),
+ ERROR(new Color(178, 30, 30, 255)),
+ SUCCESS(new Color(114, 208, 0, 255)),
+ WARNING(new Color(208, 121, 22, 255)),
+ INFO(new Color(204, 253, 233, 255));
+
+ private Color color;
+
+ ColorPallet(Color color) {
+ this.color = color;
+ }
+
+ public Color getColor() {
+ return color;
+ }
+}
diff --git a/src/main/java/de/torui/coflsky/gui/bingui/helper/GuiUtilsClone.java b/src/main/java/de/torui/coflsky/gui/bingui/helper/GuiUtilsClone.java
new file mode 100644
index 0000000..d59d3af
--- /dev/null
+++ b/src/main/java/de/torui/coflsky/gui/bingui/helper/GuiUtilsClone.java
@@ -0,0 +1,349 @@
+/*
+ * Forge Mod Loader
+ * Copyright (c) 2012-2014 cpw.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the GNU Lesser Public License v2.1
+ * which accompanies this distribution, and is available at
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ *
+ * Contributors (this class):
+ * bspkrs - implementation
+ */
+
+package de.torui.coflsky.gui.bingui.helper;
+
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.FontRenderer;
+import net.minecraft.client.renderer.GlStateManager;
+import net.minecraft.client.renderer.RenderHelper;
+import net.minecraft.client.renderer.Tessellator;
+import net.minecraft.client.renderer.WorldRenderer;
+import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
+import net.minecraft.util.ResourceLocation;
+import org.lwjgl.opengl.GL11;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class provides several methods and constants used by the Config GUI classes.
+ *
+ * @author bspkrs
+ */
+public class GuiUtilsClone {
+ public static final String UNDO_CHAR = "\u21B6";
+ public static final String RESET_CHAR = "\u2604";
+ public static final String VALID = "\u2714";
+ public static final String INVALID = "\u2715";
+
+ public static int[] colorCodes = new int[]{0, 170, 43520, 43690, 11141120, 11141290, 16755200, 11184810, 5592405, 5592575, 5635925, 5636095, 16733525, 16733695, 16777045, 16777215,
+ 0, 42, 10752, 10794, 2752512, 2752554, 2763264, 2763306, 1381653, 1381695, 1392405, 1392447, 4134165, 4134207, 4144917, 4144959};
+
+ public static int getColorCode(char c, boolean isLighter) {
+ return colorCodes[isLighter ? "0123456789abcdef".indexOf(c) : "0123456789abcdef".indexOf(c) + 16];
+ }
+
+ /**
+ * Draws a textured box of any size (smallest size is borderSize * 2 square) based on a fixed size textured box with continuous borders
+ * and filler. It is assumed that the desired texture ResourceLocation object has been bound using
+ * Minecraft.getMinecraft().getTextureManager().bindTexture(resourceLocation).
+ *
+ * @param x x axis offset
+ * @param y y axis offset
+ * @param u bound resource location image x offset
+ * @param v bound resource location image y offset
+ * @param width the desired box width
+ * @param height the desired box height
+ * @param textureWidth the width of the box texture in the resource location image
+ * @param textureHeight the height of the box texture in the resource location image
+ * @param borderSize the size of the box's borders
+ * @param zLevel the zLevel to draw at
+ */
+ public static void drawContinuousTexturedBox(int x, int y, int u, int v, int width, int height, int textureWidth, int textureHeight,
+ int borderSize, float zLevel) {
+ drawContinuousTexturedBox(x, y, u, v, width, height, textureWidth, textureHeight, borderSize, borderSize, borderSize, borderSize, zLevel);
+ }
+
+ /**
+ * Draws a textured box of any size (smallest size is borderSize * 2 square) based on a fixed size textured box with continuous borders
+ * and filler. The provided ResourceLocation object will be bound using
+ * Minecraft.getMinecraft().getTextureManager().bindTexture(resourceLocation).
+ *
+ * @param res the ResourceLocation object that contains the desired image
+ * @param x x axis offset
+ * @param y y axis offset
+ * @param u bound resource location image x offset
+ * @param v bound resource location image y offset
+ * @param width the desired box width
+ * @param height the desired box height
+ * @param textureWidth the width of the box texture in the resource location image
+ * @param textureHeight the height of the box texture in the resource location image
+ * @param borderSize the size of the box's borders
+ * @param zLevel the zLevel to draw at
+ */
+ public static void drawContinuousTexturedBox(ResourceLocation res, int x, int y, int u, int v, int width, int height, int textureWidth, int textureHeight,
+ int borderSize, float zLevel) {
+ drawContinuousTexturedBox(res, x, y, u, v, width, height, textureWidth, textureHeight, borderSize, borderSize, borderSize, borderSize, zLevel);
+ }
+
+ /**
+ * Draws a textured box of any size (smallest size is borderSize * 2 square) based on a fixed size textured box with continuous borders
+ * and filler. The provided ResourceLocation object will be bound using
+ * Minecraft.getMinecraft().getTextureManager().bindTexture(resourceLocation).
+ *
+ * @param res the ResourceLocation object that contains the desired image
+ * @param x x axis offset
+ * @param y y axis offset
+ * @param u bound resource location image x offset
+ * @param v bound resource location image y offset
+ * @param width the desired box width
+ * @param height the desired box height
+ * @param textureWidth the width of the box texture in the resource location image
+ * @param textureHeight the height of the box texture in the resource location image
+ * @param topBorder the size of the box's top border
+ * @param bottomBorder the size of the box's bottom border
+ * @param leftBorder the size of the box's left border
+ * @param rightBorder the size of the box's right border
+ * @param zLevel the zLevel to draw at
+ */
+ public static void drawContinuousTexturedBox(ResourceLocation res, int x, int y, int u, int v, int width, int height, int textureWidth, int textureHeight,
+ int topBorder, int bottomBorder, int leftBorder, int rightBorder, float zLevel) {
+ Minecraft.getMinecraft().getTextureManager().bindTexture(res);
+ drawContinuousTexturedBox(x, y, u, v, width, height, textureWidth, textureHeight, topBorder, bottomBorder, leftBorder, rightBorder, zLevel);
+ }
+
+ /**
+ * Draws a textured box of any size (smallest size is borderSize * 2 square) based on a fixed size textured box with continuous borders
+ * and filler. It is assumed that the desired texture ResourceLocation object has been bound using
+ * Minecraft.getMinecraft().getTextureManager().bindTexture(resourceLocation).
+ *
+ * @param x x axis offset
+ * @param y y axis offset
+ * @param u bound resource location image x offset
+ * @param v bound resource location image y offset
+ * @param width the desired box width
+ * @param height the desired box height
+ * @param textureWidth the width of the box texture in the resource location image
+ * @param textureHeight the height of the box texture in the resource location image
+ * @param topBorder the size of the box's top border
+ * @param bottomBorder the size of the box's bottom border
+ * @param leftBorder the size of the box's left border
+ * @param rightBorder the size of the box's right border
+ * @param zLevel the zLevel to draw at
+ */
+ public static void drawContinuousTexturedBox(int x, int y, int u, int v, int width, int height, int textureWidth, int textureHeight,
+ int topBorder, int bottomBorder, int leftBorder, int rightBorder, float zLevel) {
+ GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
+ GlStateManager.enableBlend();
+ GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0);
+
+ int fillerWidth = textureWidth - leftBorder - rightBorder;
+ int fillerHeight = textureHeight - topBorder - bottomBorder;
+ int canvasWidth = width - leftBorder - rightBorder;
+ int canvasHeight = height - topBorder - bottomBorder;
+ int xPasses = canvasWidth / fillerWidth;
+ int remainderWidth = canvasWidth % fillerWidth;
+ int yPasses = canvasHeight / fillerHeight;
+ int remainderHeight = canvasHeight % fillerHeight;
+
+ // Draw Border
+ // Top Left
+ drawTexturedModalRect(x, y, u, v, leftBorder, topBorder, zLevel);
+ // Top Right
+ drawTexturedModalRect(x + leftBorder + canvasWidth, y, u + leftBorder + fillerWidth, v, rightBorder, topBorder, zLevel);
+ // Bottom Left
+ drawTexturedModalRect(x, y + topBorder + canvasHeight, u, v + topBorder + fillerHeight, leftBorder, bottomBorder, zLevel);
+ // Bottom Right
+ drawTexturedModalRect(x + leftBorder + canvasWidth, y + topBorder + canvasHeight, u + leftBorder + fillerWidth, v + topBorder + fillerHeight, rightBorder, bottomBorder, zLevel);
+
+ for (int i = 0; i < xPasses + (remainderWidth > 0 ? 1 : 0); i++) {
+ // Top Border
+ drawTexturedModalRect(x + leftBorder + (i * fillerWidth), y, u + leftBorder, v, (i == xPasses ? remainderWidth : fillerWidth), topBorder, zLevel);
+ // Bottom Border
+ drawTexturedModalRect(x + leftBorder + (i * fillerWidth), y + topBorder + canvasHeight, u + leftBorder, v + topBorder + fillerHeight, (i == xPasses ? remainderWidth : fillerWidth), bottomBorder, zLevel);
+
+ // Throw in some filler for good measure
+ for (int j = 0; j < yPasses + (remainderHeight > 0 ? 1 : 0); j++)
+ drawTexturedModalRect(x + leftBorder + (i * fillerWidth), y + topBorder + (j * fillerHeight), u + leftBorder, v + topBorder, (i == xPasses ? remainderWidth : fillerWidth), (j == yPasses ? remainderHeight : fillerHeight), zLevel);
+ }
+
+ // Side Borders
+ for (int j = 0; j < yPasses + (remainderHeight > 0 ? 1 : 0); j++) {
+ // Left Border
+ drawTexturedModalRect(x, y + topBorder + (j * fillerHeight), u, v + topBorder, leftBorder, (j == yPasses ? remainderHeight : fillerHeight), zLevel);
+ // Right Border
+ drawTexturedModalRect(x + leftBorder + canvasWidth, y + topBorder + (j * fillerHeight), u + leftBorder + fillerWidth, v + topBorder, rightBorder, (j == yPasses ? remainderHeight : fillerHeight), zLevel);
+ }
+ }
+
+ public static void drawTexturedModalRect(int x, int y, int u, int v, int width, int height, float zLevel) {
+ float uScale = 1f / 0x100;
+ float vScale = 1f / 0x100;
+ Tessellator tessellator = Tessellator.getInstance();
+ WorldRenderer wr = tessellator.getWorldRenderer();
+ wr.begin(7, DefaultVertexFormats.POSITION_TEX);
+ wr.pos(x, y + height, zLevel).tex(u * uScale, ((v + height) * vScale)).endVertex();
+ wr.pos(x + width, y + height, zLevel).tex((u + width) * uScale, ((v + height) * vScale)).endVertex();
+ wr.pos(x + width, y, zLevel).tex((u + width) * uScale, (v * vScale)).endVertex();
+ wr.pos(x, y, zLevel).tex(u * uScale, (v * vScale)).endVertex();
+ tessellator.draw();
+ }
+
+ /**
+ * Draws a tooltip box on the screen with text in it.
+ * Automatically positions the box relative to the mouse to match Mojang's implementation.
+ * Automatically wraps text when there is not enough space on the screen to display the text without wrapping.
+ * Can have a maximum width set to avoid creating very wide tooltips.
+ *
+ * @param textLines the lines of text to be drawn in a hovering tooltip box.
+ * @param mouseX the mouse X position
+ * @param mouseY the mouse Y position
+ * @param screenWidth the available screen width for the tooltip to drawn in
+ * @param screenHeight the available screen height for the tooltip to drawn in
+ * @param maxTextWidth the maximum width of the text in the tooltip box.
+ * Set to a negative number to have no max width.
+ * @param font the font for drawing the text in the tooltip box
+ */
+ public static void drawHoveringText(List<String> textLines, final int mouseX, final int mouseY, final int screenWidth, final int screenHeight, final int maxTextWidth, FontRenderer font) {
+ if (!textLines.isEmpty()) {
+ GlStateManager.disableRescaleNormal();
+ RenderHelper.disableStandardItemLighting();
+ GlStateManager.disableLighting();
+ GlStateManager.disableDepth();
+ int tooltipTextWidth = 0;
+
+ for (String textLine : textLines) {
+ int textLineWidth = font.getStringWidth(textLine);
+
+ if (textLineWidth > tooltipTextWidth) {
+ tooltipTextWidth = textLineWidth;
+ }
+ }
+
+ boolean needsWrap = false;
+
+ int titleLinesCount = 1;
+ int tooltipX = mouseX + 4;
+ if (tooltipX + tooltipTextWidth + 4 > screenWidth) {
+ tooltipX = mouseX - 16 - tooltipTextWidth;
+ if (tooltipX < 4) // if the tooltip doesn't fit on the screen
+ {
+ if (mouseX > screenWidth / 2) {
+ tooltipTextWidth = mouseX - 12 - 8;
+ } else {
+ tooltipTextWidth = screenWidth - 16 - mouseX;
+ }
+ needsWrap = true;
+ }
+ }
+
+ if (maxTextWidth > 0 && tooltipTextWidth > maxTextWidth) {
+ tooltipTextWidth = maxTextWidth;
+ needsWrap = true;
+ }
+
+ if (needsWrap) {
+ int wrappedTooltipWidth = 0;
+ List<String> wrappedTextLines = new ArrayList<String>();
+ for (int i = 0; i < textLines.size(); i++) {
+ String textLine = textLines.get(i);
+ List<String> wrappedLine = font.listFormattedStringToWidth(textLine, tooltipTextWidth);
+ if (i == 0) {
+ titleLinesCount = wrappedLine.size();
+ }
+
+ for (String line : wrappedLine) {
+ int lineWidth = font.getStringWidth(line);
+ if (lineWidth > wrappedTooltipWidth) {
+ wrappedTooltipWidth = lineWidth;
+ }
+ wrappedTextLines.add(line);
+ }
+ }
+ tooltipTextWidth = wrappedTooltipWidth;
+ textLines = wrappedTextLines;
+
+ if (mouseX > screenWidth / 2) {
+ tooltipX = mouseX - 16 - tooltipTextWidth;
+ } else {
+ tooltipX = mouseX + 12;
+ }
+ }
+
+ int tooltipY = mouseY + 4;
+ int tooltipHeight = 8;
+
+ if (textLines.size() > 1) {
+ tooltipHeight += (textLines.size() - 1) * 10;
+ if (textLines.size() > titleLinesCount) {
+ tooltipHeight += 2; // gap between title lines and next lines
+ }
+ }
+
+ if (tooltipY + tooltipHeight + 6 > screenHeight) {
+ tooltipY = screenHeight - tooltipHeight - 6;
+ }
+
+ final int zLevel = 300;
+ final int backgroundColor = 0xF0100010;
+ drawGradientRect(zLevel, tooltipX - 3, tooltipY - 4, tooltipX + tooltipTextWidth + 3, tooltipY - 3, backgroundColor, backgroundColor);
+ drawGradientRect(zLevel, tooltipX - 3, tooltipY + tooltipHeight + 3, tooltipX + tooltipTextWidth + 3, tooltipY + tooltipHeight + 4, backgroundColor, backgroundColor);
+ drawGradientRect(zLevel, tooltipX - 3, tooltipY - 3, tooltipX + tooltipTextWidth + 3, tooltipY + tooltipHeight + 3, backgroundColor, backgroundColor);
+ drawGradientRect(zLevel, tooltipX - 4, tooltipY - 3, tooltipX - 3, tooltipY + tooltipHeight + 3, backgroundColor, backgroundColor);
+ drawGradientRect(zLevel, tooltipX + tooltipTextWidth + 3, tooltipY - 3, tooltipX + tooltipTextWidth + 4, tooltipY + tooltipHeight + 3, backgroundColor, backgroundColor);
+ final int borderColorStart = 0x505000FF;
+ final int borderColorEnd = (borderColorStart & 0xFEFEFE) >> 1 | borderColorStart & 0xFF000000;
+ drawGradientRect(zLevel, tooltipX - 3, tooltipY - 3 + 1, tooltipX - 3 + 1, tooltipY + tooltipHeight + 3 - 1, borderColorStart, borderColorEnd);
+ drawGradientRect(zLevel, tooltipX + tooltipTextWidth + 2, tooltipY - 3 + 1, tooltipX + tooltipTextWidth + 3, tooltipY + tooltipHeight + 3 - 1, borderColorStart, borderColorEnd);
+ drawGradientRect(zLevel, tooltipX - 3, tooltipY - 3, tooltipX + tooltipTextWidth + 3, tooltipY - 3 + 1, borderColorStart, borderColorStart);
+ drawGradientRect(zLevel, tooltipX - 3, tooltipY + tooltipHeight + 2, tooltipX + tooltipTextWidth + 3, tooltipY + tooltipHeight + 3, borderColorEnd, borderColorEnd);
+
+ for (int lineNumber = 0; lineNumber < textLines.size(); ++lineNumber) {
+ String line = textLines.get(lineNumber);
+ font.drawStringWithShadow(line, (float) tooltipX, (float) tooltipY, -1);
+
+ if (lineNumber + 1 == titleLinesCount) {
+ tooltipY += 2;
+ }
+
+ tooltipY += 10;
+ }
+
+ GlStateManager.enableLighting();
+ GlStateManager.enableDepth();
+ RenderHelper.enableStandardItemLighting();
+ GlStateManager.enableRescaleNormal();
+ }
+ }
+
+ public static void drawGradientRect(int zLevel, int left, int top, int right, int bottom, int startColor, int endColor) {
+ float startAlpha = (float) (startColor >> 24 & 255) / 255.0F;
+ float startRed = (float) (startColor >> 16 & 255) / 255.0F;
+ float startGreen = (float) (startColor >> 8 & 255) / 255.0F;
+ float startBlue = (float) (startColor & 255) / 255.0F;
+ float endAlpha = (float) (endColor >> 24 & 255) / 255.0F;
+ float endRed = (float) (endColor >> 16 & 255) / 255.0F;
+ float endGreen = (float) (endColor >> 8 & 255) / 255.0F;
+ float endBlue = (float) (endColor & 255) / 255.0F;
+
+ GlStateManager.disableTexture2D();
+ GlStateManager.enableBlend();
+ GlStateManager.disableAlpha();
+ GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0);
+ GlStateManager.shadeModel(7425);
+
+ Tessellator tessellator = Tessellator.getInstance();
+ WorldRenderer worldrenderer = tessellator.getWorldRenderer();
+ worldrenderer.begin(7, DefaultVertexFormats.POSITION_COLOR);
+ worldrenderer.pos(right, top, zLevel).color(startRed, startGreen, startBlue, startAlpha).endVertex();
+ worldrenderer.pos(left, top, zLevel).color(startRed, startGreen, startBlue, startAlpha).endVertex();
+ worldrenderer.pos(left, bottom, zLevel).color(endRed, endGreen, endBlue, endAlpha).endVertex();
+ worldrenderer.pos(right, bottom, zLevel).color(endRed, endGreen, endBlue, endAlpha).endVertex();
+ tessellator.draw();
+
+ GlStateManager.shadeModel(7424);
+ GlStateManager.disableBlend();
+ GlStateManager.enableAlpha();
+ GlStateManager.enableTexture2D();
+ }
+}
diff --git a/src/main/java/de/torui/coflsky/gui/bingui/helper/RenderUtils.java b/src/main/java/de/torui/coflsky/gui/bingui/helper/RenderUtils.java
new file mode 100644
index 0000000..64b2594
--- /dev/null
+++ b/src/main/java/de/torui/coflsky/gui/bingui/helper/RenderUtils.java
@@ -0,0 +1,367 @@
+package de.torui.coflsky.gui.bingui.helper;
+
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.FontRenderer;
+import net.minecraft.client.renderer.RenderHelper;
+import net.minecraft.client.renderer.entity.RenderItem;
+import net.minecraft.item.ItemStack;
+import org.jetbrains.annotations.NotNull;
+import org.lwjgl.opengl.GL11;
+
+import java.awt.*;
+
+
+/**
+ * Created by ForBai
+ */
+public class RenderUtils {
+ public static Minecraft mc = Minecraft.getMinecraft();
+
+ //draw a rectangle
+ public static void drawRect(float x, float y, float width, float height, int color) {
+ float alpha = (float) (color >> 24 & 255) / 255.0F;
+ float red = (float) (color >> 16 & 255) / 255.0F;
+ float green = (float) (color >> 8 & 255) / 255.0F;
+ float blue = (float) (color & 255) / 255.0F;
+ GL11.glEnable(GL11.GL_BLEND);
+ GL11.glDisable(GL11.GL_TEXTURE_2D);
+ GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ GL11.glColor4f(red, green, blue, alpha);
+ GL11.glBegin(GL11.GL_QUADS);
+ GL11.glVertex2d(x, y);
+ GL11.glVertex2d(x, y + height);
+ GL11.glVertex2d(x + width, y + height);
+ GL11.glVertex2d(x + width, y);
+ GL11.glEnd();
+ GL11.glEnable(GL11.GL_TEXTURE_2D);
+ GL11.glDisable(GL11.GL_BLEND);
+ }
+
+
+ //draws an outlined rectangle with a given color and size and a given line width
+ public static void drawRectOutline(int x, int y, int width, int height, float lineWidth, Color color) {
+ GL11.glEnable(GL11.GL_BLEND);
+ GL11.glDisable(GL11.GL_TEXTURE_2D);
+ GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ setColor(color);
+ GL11.glLineWidth(lineWidth);
+ GL11.glBegin(GL11.GL_LINE_LOOP);
+ GL11.glVertex2d(x, y);
+ GL11.glVertex2d(x + width, y);
+ GL11.glVertex2d(x + width, y + height);
+ GL11.glVertex2d(x, y + height);
+ GL11.glEnd();
+ GL11.glEnable(GL11.GL_TEXTURE_2D);
+ GL11.glDisable(GL11.GL_BLEND);
+ }
+
+ //draws a circle with a given radius and thickness
+ public static void drawCircle(int x, int y, int radius, Color color) {
+ GL11.glEnable(GL11.GL_BLEND);
+ GL11.glDisable(GL11.GL_TEXTURE_2D);
+ GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ setColor(color);
+ GL11.glBegin(GL11.GL_TRIANGLE_FAN);
+ GL11.glVertex2d(x, y);
+ for (int i = 0; i <= 360; i++) {
+ GL11.glVertex2d(x + Math.sin(i * Math.PI / 180) * radius, y + Math.cos(i * Math.PI / 180) * radius);
+ }
+ GL11.glEnd();
+ GL11.glEnable(GL11.GL_TEXTURE_2D);
+ GL11.glDisable(GL11.GL_BLEND);
+ }
+
+ //draws a circle outline with a given radius and thickness
+ public static void drawCircleOutline(int x, int y, float radius, float thickness, Color color) {
+ GL11.glEnable(GL11.GL_BLEND);
+ GL11.glDisable(GL11.GL_TEXTURE_2D);
+ GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ setColor(color);
+ GL11.glBegin(GL11.GL_LINE_LOOP);
+ for (int i = 0; i <= 360; i++) {
+ GL11.glVertex2d(x + Math.sin(i * Math.PI / 180) * radius, y + Math.cos(i * Math.PI / 180) * radius);
+ }
+ GL11.glEnd();
+ GL11.glEnable(GL11.GL_TEXTURE_2D);
+ GL11.glDisable(GL11.GL_BLEND);
+ }
+
+ //draws line from x1,y1 to x2,y2 with a given color and thickness
+ public static void drawLine(float x1, float y1, float x2, float y2, float thickness, Color color) {
+ GL11.glEnable(GL11.GL_BLEND);
+ GL11.glDisable(GL11.GL_TEXTURE_2D);
+ GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ setColor(color);
+ GL11.glLineWidth(thickness);
+ GL11.glBegin(GL11.GL_LINES);
+ GL11.glVertex2d(x1, y1);
+ GL11.glVertex2d(x2, y2);
+ GL11.glEnd();
+ GL11.glEnable(GL11.GL_TEXTURE_2D);
+ GL11.glDisable(GL11.GL_BLEND);
+ }
+
+ //draws a triangle from x1,y1 to x2,y2 to x3,y3
+ public static void drawTriangle(int x, int y, int x2, int y2, int x3, int y3, Color color) {
+ GL11.glEnable(GL11.GL_BLEND);
+ GL11.glDisable(GL11.GL_TEXTURE_2D);
+ GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ setColor(color);
+ GL11.glBegin(GL11.GL_TRIANGLES);
+ GL11.glVertex2d(x, y);
+ GL11.glVertex2d(x2, y2);
+ GL11.glVertex2d(x3, y3);
+ GL11.glEnd();
+ GL11.glEnable(GL11.GL_TEXTURE_2D);
+ GL11.glDisable(GL11.GL_BLEND);
+ }
+
+ //draws a triangle outline from x1,y1 to x2,y2 to x3,y3
+ public static void drawTriangleOutline(int x, int y, int x2, int y2, int x3, int y3, Color color) {
+ GL11.glEnable(GL11.GL_BLEND);
+ GL11.glDisable(GL11.GL_TEXTURE_2D);
+ GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ setColor(color);
+ GL11.glBegin(GL11.GL_LINE_LOOP);
+ GL11.glVertex2d(x, y);
+ GL11.glVertex2d(x2, y2);
+ GL11.glVertex2d(x3, y3);
+ GL11.glEnd();
+ GL11.glEnable(GL11.GL_TEXTURE_2D);
+ GL11.glDisable(GL11.GL_BLEND);
+ }
+
+ //draws an arc with a given radius, start angle, and end angle
+ public static void drawArc(int x, int y, int radius, int startAngle, int endAngle, Color color) {
+ GL11.glEnable(GL11.GL_BLEND);
+ GL11.glDisable(GL11.GL_TEXTURE_2D);
+ GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ setColor(color);
+ GL11.glBegin(GL11.GL_TRIANGLE_FAN);
+ GL11.glVertex2d(x, y);
+ for (int i = startAngle; i <= endAngle; i++) {
+ GL11.glVertex2d(x + Math.sin(i * Math.PI / 180) * radius, y + Math.cos(i * Math.PI / 180) * radius);
+ }
+ GL11.glEnd();
+ GL11.glEnable(GL11.GL_TEXTURE_2D);
+ GL11.glDisable(GL11.GL_BLEND);
+ }
+
+
+ //draw a loading circle with a given radius, thickness, and speed
+ public static void drawLoadingCircle(float x, float y, float radius, float thickness, float speed, Color color) {
+ GL11.glEnable(GL11.GL_BLEND);
+ GL11.glDisable(GL11.GL_TEXTURE_2D);
+ GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ setColor(color);
+ GL11.glLineWidth(thickness);
+ GL11.glBegin(GL11.GL_LINE_STRIP);
+ for (int i = 0; i <= 360; i++) {
+ GL11.glVertex2d(x + Math.sin((i + speed) * Math.PI / 180) * radius, y + Math.cos((i + speed) * Math.PI / 180) * radius);
+ }
+ GL11.glEnd();
+ GL11.glEnable(GL11.GL_TEXTURE_2D);
+ GL11.glDisable(GL11.GL_BLEND);
+ }
+
+ //draws a rounded rectangle with a given radius and color and size
+ public static void drawRoundedRect(int x, int y, int width, int height, int radius, @NotNull Color color) {
+
+ //draw the two rectangles
+ drawRect(x + radius, y, width - radius * 2, height, color.getRGB());
+ drawRect(x, y + radius, radius, height - radius * 2, color.getRGB());
+ drawRect(x + width - radius, y + radius, radius, height - radius * 2, color.getRGB());
+
+ //drawRect(x + radius, y, width - radius - radius, height, color.getRGB());
+ //drawRect(x, y + radius, width, height - radius - radius, color.getRGB());
+ //draw the circles
+ drawArc(x + radius, y + radius, radius, 180, 270, color);
+ drawArc(x + width - radius, y + radius, radius, 90, 180, color);
+ drawArc(x + radius, y + height - radius, radius, 270, 360, color);
+ drawArc(x + width - radius, y + height - radius, radius, 0, 90, color);
+
+ //drawCircle(x + radius, y + radius, radius, color);
+ //drawCircle(x + width - radius, y + radius, radius, color);
+ //drawCircle(x + radius, y + height - radius, radius, color);
+ //drawCircle(x + width - radius, y + height - radius, radius, color);
+
+ //drawRectOutline(x, y, width, height, 1, Color.GREEN);
+ }
+
+ //draws a gradient rectangle with a given color and size
+ public static void drawGradientRect(int x, int y, int width, int height, Color color1, Color color2) {
+ GL11.glEnable(GL11.GL_BLEND);
+ GL11.glDisable(GL11.GL_TEXTURE_2D);
+ GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ GL11.glShadeModel(GL11.GL_SMOOTH);
+ GL11.glBegin(GL11.GL_QUADS);
+ setColor(color1);
+ GL11.glVertex2d(x, y);
+ GL11.glVertex2d(x + width, y);
+ setColor(color2);
+ GL11.glVertex2d(x + width, y + height);
+ GL11.glVertex2d(x, y + height);
+ GL11.glEnd();
+ GL11.glShadeModel(GL11.GL_FLAT);
+ GL11.glEnable(GL11.GL_TEXTURE_2D);
+ GL11.glDisable(GL11.GL_BLEND);
+ }
+
+
+ public static void drawString(String text, int x, int y, Color color) {
+ setColor(color);
+ mc.fontRendererObj.drawString(text, x, y, color.getRGB());
+ }
+
+ public static void drawStringWithShadow(String text, int x, int y, Color color) {
+ setColor(color);
+ mc.fontRendererObj.drawStringWithShadow(text, x, y, color.getRGB());
+ }
+
+ public static void drawCenteredString(String text, int x, int y, Color color) {
+ setColor(color);
+ mc.fontRendererObj.drawString(text, x - mc.fontRendererObj.getStringWidth(text) / 2, y, color.getRGB());
+ }
+
+ public static void drawCenteredStringWithShadow(String text, int x, int y, Color color) {
+ setColor(color);
+ mc.fontRendererObj.drawStringWithShadow(text, x - mc.fontRendererObj.getStringWidth(text) / 2, y, color.getRGB());
+ }
+
+ //draws a string with custom scale
+ public static void drawString(String text, int x, int y, Color color, int scale) {
+ setColor(color);
+ FontRenderer fr = mc.fontRendererObj;
+ fr.drawString(text, x, y, color.getRGB());
+ }
+
+ //draws a string with custom scale and shadow
+ public static void drawStringWithShadow(String text, int x, int y, Color color, int scale) {
+ setColor(color);
+ FontRenderer fr = mc.fontRendererObj;
+ fr.drawStringWithShadow(text, x, y, color.getRGB());
+ }
+
+ public static void drawCenteredString(String text, int x, int y, Color color, int scale) {
+ setColor(color);
+ FontRenderer fr = mc.fontRendererObj;
+ fr.drawString(text, x - fr.getStringWidth(text) / 2, y, color.getRGB());
+ }
+
+ public static void drawCenteredStringWithShadow(String text, int x, int y, Color color, int scale) {
+ setColor(color);
+ FontRenderer fr = mc.fontRendererObj;
+ fr.drawStringWithShadow(text, x - fr.getStringWidth(text) / 2, y, color.getRGB());
+ }
+
+ public static void drawCenteredStringWithShadow(String text, int x, int y, Color color, int scale, boolean centered) {
+ setColor(color);
+ FontRenderer fr = mc.fontRendererObj;
+ if (centered) {
+ fr.drawStringWithShadow(text, x - fr.getStringWidth(text) / 2, y, color.getRGB());
+ } else {
+ fr.drawStringWithShadow(text, x, y, color.getRGB());
+ }
+ }
+
+ //draws an ItemStack at a given position with a given scale
+ public static void drawItemStack(ItemStack itemStack, int x, int y, float scale) {
+ GL11.glPushMatrix();
+ GL11.glScalef(scale, scale, scale);
+ mc.getRenderItem().renderItemIntoGUI(itemStack, x, y);
+ GL11.glPopMatrix();
+ }
+
+ public static void drawItemStackWithText(ItemStack stack, int x, int y, String text) {
+ if (stack == null) return;
+ RenderItem itemRender = Minecraft.getMinecraft().getRenderItem();
+ setColor(Color.WHITE);
+ RenderHelper.enableGUIStandardItemLighting();
+ itemRender.zLevel = -145;
+ itemRender.renderItemAndEffectIntoGUI(stack, x, y);
+ itemRender.renderItemOverlayIntoGUI(Minecraft.getMinecraft().fontRendererObj, stack, x, y, text);
+ itemRender.zLevel = 0;
+ RenderHelper.disableStandardItemLighting();
+ }
+
+ public static void drawItemStack(ItemStack stack, int x, int y) {
+ drawItemStackWithText(stack, x, y, null);
+ }
+
+ public static void drawItemStack(ItemStack itemStack, int x, int y, float scaleX, float scaleY) {
+ GL11.glPushMatrix();
+ GL11.glScalef(scaleX, scaleY, 0);
+ drawItemStack(itemStack, x, y);
+ GL11.glPopMatrix();
+ }
+
+ //draw centered ItemStack at a given position with a given scale
+ public static void drawCenteredItemStack(ItemStack itemStack, int x, int y, float scale) {
+ GL11.glPushMatrix();
+ GL11.glScalef(scale, scale, scale);
+ drawItemStack(itemStack, (int) (x - (scale / 2)), (int) (y - (scale / 2)));
+ GL11.glPopMatrix();
+ }
+
+ //draw a check mar with a given color and size using lines
+ public static void drawCheckMark(int x, int y, int size, Color color) {
+ GL11.glPushMatrix();
+ GL11.glEnable(GL11.GL_BLEND);
+ GL11.glDisable(GL11.GL_TEXTURE_2D);
+ GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ GL11.glLineWidth(2);
+ setColor(color);
+ GL11.glBegin(GL11.GL_LINES);
+ GL11.glVertex2d(x, y + size / 2);
+ GL11.glVertex2d(x + size / 2, y + size);
+ GL11.glVertex2d(x + size / 2, y + size);
+ GL11.glVertex2d(x + size, y);
+ GL11.glEnd();
+ GL11.glEnable(GL11.GL_TEXTURE_2D);
+ GL11.glDisable(GL11.GL_BLEND);
+ GL11.glPopMatrix();
+ }
+
+ //draw a cross mark with a given color and start and end points
+ public static void drawCrossMark(int x, int y, int x2, int y2, Color color) {
+ GL11.glPushMatrix();
+ GL11.glEnable(GL11.GL_BLEND);
+ GL11.glDisable(GL11.GL_TEXTURE_2D);
+ GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ GL11.glLineWidth(2);
+ setColor(color);
+ GL11.glBegin(GL11.GL_LINES);
+ GL11.glVertex2d(x, y);
+ GL11.glVertex2d(x2, y2);
+ GL11.glVertex2d(x2, y);
+ GL11.glVertex2d(x, y2);
+ GL11.glEnd();
+ GL11.glEnable(GL11.GL_TEXTURE_2D);
+ GL11.glDisable(GL11.GL_BLEND);
+ GL11.glPopMatrix();
+ }
+
+
+ //set alpha of color
+ public static Color setAlpha(Color color, int alpha) {
+ return new Color(color.getRed(), color.getGreen(), color.getBlue(), alpha);
+ }
+
+ //set color
+ public static void setColor(int color) {
+ float alpha = (float) (color >> 24 & 255) / 255.0F;
+ float red = (float) (color >> 16 & 255) / 255.0F;
+ float green = (float) (color >> 8 & 255) / 255.0F;
+ float blue = (float) (color & 255) / 255.0F;
+ GL11.glColor4f(red, green, blue, alpha);
+ }
+
+ public static void setColor(Color color) {
+ setColor(color.getRGB());
+ }
+
+ //rotate
+ public static void rotate(float angle) {
+ GL11.glRotatef(angle, 0.0F, 0.0F, 1.0F);
+ }
+}