From 48f309c1676626e0c8d0128220e50e51247c9abb Mon Sep 17 00:00:00 2001 From: BuildTools Date: Sun, 6 Jun 2021 23:35:32 +0800 Subject: ironmoon --- .../notenoughupdates/NEUEventListener.java | 62 +- .../moulberry/notenoughupdates/NEUManager.java | 4 + .../notenoughupdates/NotEnoughUpdates.java | 18 +- .../notenoughupdates/core/GuiElementTextField.java | 3 + .../miscfeatures/PetInfoOverlay.java | 4 - .../notenoughupdates/miscfeatures/SlotLocking.java | 8 +- .../miscfeatures/StorageManager.java | 35 +- .../miscgui/AccessoryBagOverlay.java | 5 + .../notenoughupdates/miscgui/GuiCustomEnchant.java | 1258 ++++++++++++++++++-- .../notenoughupdates/miscgui/StorageOverlay.java | 295 ++++- .../notenoughupdates/miscgui/TradeWindow.java | 62 +- .../notenoughupdates/mixins/MixinGuiContainer.java | 6 + .../notenoughupdates/mixins/MixinMinecraft.java | 6 + .../notenoughupdates/options/NEUConfig.java | 31 +- .../notenoughupdates/options/NEUConfigEditor.java | 16 +- .../profileviewer/GuiProfileViewer.java | 7 +- .../moulberry/notenoughupdates/util/SBInfo.java | 10 +- .../moulberry/notenoughupdates/util/Utils.java | 56 +- 18 files changed, 1697 insertions(+), 189 deletions(-) (limited to 'src/main/java') diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUEventListener.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUEventListener.java index 30f0f722..0c35c56c 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NEUEventListener.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUEventListener.java @@ -11,6 +11,7 @@ import io.github.moulberry.notenoughupdates.auction.CustomAHGui; import io.github.moulberry.notenoughupdates.core.BackgroundBlur; import io.github.moulberry.notenoughupdates.core.GuiScreenElementWrapper; import io.github.moulberry.notenoughupdates.core.util.MiscUtils; +import io.github.moulberry.notenoughupdates.core.util.render.RenderUtils; import io.github.moulberry.notenoughupdates.cosmetics.CapeManager; import io.github.moulberry.notenoughupdates.dungeons.DungeonBlocks; import io.github.moulberry.notenoughupdates.dungeons.DungeonWin; @@ -142,8 +143,8 @@ public class NEUEventListener { NotEnoughUpdates.INSTANCE.saveConfig(); } - private long notificationDisplayMillis = 0; - private List notificationLines = null; + private static long notificationDisplayMillis = 0; + private static List notificationLines = null; private static final Pattern BAD_ITEM_REGEX = Pattern.compile("x[0-9]{1,2}$"); @@ -163,6 +164,15 @@ public class NEUEventListener { private String loadedInvName = ""; public static boolean inventoryLoaded = false; + public static void displayNotification(List lines, boolean showForever) { + if(showForever) { + notificationDisplayMillis = -420; + } else { + notificationDisplayMillis = System.currentTimeMillis(); + } + notificationLines = lines; + } + @SubscribeEvent public void onTick(TickEvent.ClientTickEvent event) { if(event.phase != TickEvent.Phase.START) return; @@ -213,7 +223,8 @@ public class NEUEventListener { if(neu.hasSkyblockScoreboard()) { if(!preloadedItems) { preloadedItems = true; - for(JsonObject json : neu.manager.getItemInformation().values()) { + List list = new ArrayList<>(neu.manager.getItemInformation().values()); + for(JsonObject json : list) { itemPreloader.submit(() -> { ItemStack stack = neu.manager.jsonToStack(json, true, true); if(stack.getItem() == Items.skull) toPreload.add(stack); @@ -263,6 +274,7 @@ public class NEUEventListener { ItemCustomizeManager.tick(); BackgroundBlur.markDirty(); NPCRetexturing.getInstance().tick(); + StorageOverlay.getInstance().markDirty(); if(neu.hasSkyblockScoreboard()) { for(TextOverlay overlay : OverlayManager.textOverlays) { @@ -280,7 +292,10 @@ public class NEUEventListener { DungeonBlocks.tick(); } - neu.updateSkyblockScoreboard(); + if(System.currentTimeMillis() - SBInfo.getInstance().joinedWorld > 500 && + System.currentTimeMillis() - SBInfo.getInstance().unloadedWorld > 500) { + neu.updateSkyblockScoreboard(); + } CapeManager.getInstance().tick(); if(containerName != null) { @@ -305,15 +320,15 @@ public class NEUEventListener { if(neu.config.notifications.doRamNotif) { long maxMemoryMB = Runtime.getRuntime().maxMemory()/1024L/1024L; - if(maxMemoryMB > 4100) { + if(maxMemoryMB > 4100 || true) { notificationDisplayMillis = System.currentTimeMillis(); notificationLines = new ArrayList<>(); - notificationLines.add(EnumChatFormatting.DARK_RED+"Too much memory allocated!"); + notificationLines.add(EnumChatFormatting.GRAY+"Too much memory allocated!"); notificationLines.add(String.format(EnumChatFormatting.DARK_GRAY+"NEU has detected %03dMB of memory allocated to Minecraft!", maxMemoryMB)); - notificationLines.add(EnumChatFormatting.DARK_GRAY+"It is recommended to allocated between 2-4GB of memory"); - notificationLines.add(EnumChatFormatting.DARK_GRAY+"More than 4GB MAY cause FPS issues, EVEN if you have 16GB+ available"); + notificationLines.add(EnumChatFormatting.GRAY+"It is recommended to allocated between 2-4GB of memory"); + notificationLines.add(EnumChatFormatting.GRAY+"More than 4GB MAY cause FPS issues, EVEN if you have 16GB+ available"); notificationLines.add(""); - notificationLines.add(EnumChatFormatting.DARK_GRAY+"For more information, visit #ram-info in discord.gg/moulberry"); + notificationLines.add(EnumChatFormatting.GRAY+"For more information, visit #ram-info in discord.gg/moulberry"); } } @@ -436,7 +451,6 @@ public class NEUEventListener { @SubscribeEvent public void onRenderGameOverlayPost(RenderGameOverlayEvent.Post event) { - long timeRemaining = 15000 - (System.currentTimeMillis() - notificationDisplayMillis); if(neu.hasSkyblockScoreboard() && event.type == RenderGameOverlayEvent.ElementType.ALL) { DungeonWin.render(event.partialTicks); for(TextOverlay overlay : OverlayManager.textOverlays) { @@ -447,8 +461,14 @@ public class NEUEventListener { } OverlayManager.dontRenderOverlay = null; } + + if(Keyboard.isKeyDown(Keyboard.KEY_X)) { + notificationDisplayMillis = 0; + } + long timeRemaining = 15000 - (System.currentTimeMillis() - notificationDisplayMillis); + boolean display = timeRemaining > 0 || notificationDisplayMillis == -420; if(event.type == RenderGameOverlayEvent.ElementType.ALL && - timeRemaining > 0 && notificationLines != null && notificationLines.size() > 0) { + display && notificationLines != null && notificationLines.size() > 0) { int width = 0; int height = notificationLines.size()*10+10; @@ -463,13 +483,20 @@ public class NEUEventListener { int midX = sr.getScaledWidth()/2; int topY = sr.getScaledHeight()*3/4-height/2; - Gui.drawRect(midX-width/2, sr.getScaledHeight()*3/4-height/2, + RenderUtils.drawFloatingRectDark(midX-width/2, sr.getScaledHeight()*3/4-height/2, width, height); + /*Gui.drawRect(midX-width/2, sr.getScaledHeight()*3/4-height/2, midX+width/2, sr.getScaledHeight()*3/4+height/2, 0xFF3C3C3C); Gui.drawRect(midX-width/2+2, sr.getScaledHeight()*3/4-height/2+2, - midX+width/2-2, sr.getScaledHeight()*3/4+height/2-2, 0xFFC8C8C8); + midX+width/2-2, sr.getScaledHeight()*3/4+height/2-2, 0xFFC8C8C8);*/ + + int xLen = Minecraft.getMinecraft().fontRendererObj.getStringWidth("[X] Close"); + Minecraft.getMinecraft().fontRendererObj.drawString("[X] Close", midX+width/2f-3-xLen, + topY+3, 0xFFFF5555, false); - Minecraft.getMinecraft().fontRendererObj.drawString((timeRemaining/1000)+"s", midX-width/2f+3, - topY+3, 0xFF000000, false); + if(notificationDisplayMillis > 0) { + Minecraft.getMinecraft().fontRendererObj.drawString((timeRemaining/1000)+"s", midX-width/2f+3, + topY+3, 0xFFaaaaaa, false); + } Utils.drawStringCentered(notificationLines.get(0), Minecraft.getMinecraft().fontRendererObj, midX, topY+4+5, false, -1); @@ -1255,6 +1282,11 @@ public class NEUEventListener { */ @SubscribeEvent(priority = EventPriority.LOW) public void onGuiScreenMouse(GuiScreenEvent.MouseInputEvent.Pre event) { + if(Mouse.getEventButtonState() && StorageManager.getInstance().onAnyClick()) { + event.setCanceled(true); + return; + } + if(!event.isCanceled()) { Utils.scrollTooltip(Mouse.getEventDWheel()); } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java index f0b3fc0e..181b9225 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java @@ -690,6 +690,8 @@ public class NEUManager { internalname += ";3"; break; case "LEGENDARY": internalname += ";4"; break; + case "MYTHIC": + internalname += ";5"; break; } } } @@ -1304,6 +1306,8 @@ public class NEUManager { tier = "EPIC"; break; case "EPIC": tier = "LEGENDARY"; break; + case "LEGENDARY": + tier = "MYTHIC"; break; } } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java index 52e4b320..78bb6536 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java @@ -1,5 +1,6 @@ package io.github.moulberry.notenoughupdates; +import com.google.common.collect.Lists; import com.google.common.collect.Sets; import com.google.gson.Gson; import com.google.gson.GsonBuilder; @@ -221,6 +222,19 @@ public class NotEnoughUpdates { } });*/ + SimpleCommand stWhyCommand = new SimpleCommand("neustwhy", new SimpleCommand.ProcessCommandRunnable() { + public void processCommand(ICommandSender sender, String[] args) { + NEUEventListener.displayNotification(Lists.newArrayList( + "\u00a7eStorage Viewer", + "\u00a77Currently, the storage viewer requires you to click twice", + "\u00a77in order to switch between pages. This is because Hypixel", + "\u00a77has not yet added a shortcut command to go to any enderchest/", + "\u00a77storage page.", + "\u00a77While it is possible to send the second click", + "\u00a77automatically, doing so violates Hypixel's new mod rules."), true); + } + }); + SimpleCommand gamemodesCommand = new SimpleCommand("neugamemodes", new SimpleCommand.ProcessCommandRunnable() { public void processCommand(ICommandSender sender, String[] args) { boolean upgradeOverride = args.length == 1 && args[0].equals("upgradeOverride"); @@ -1159,6 +1173,7 @@ public class NotEnoughUpdates { ClientCommandHandler.instance.registerCommand(cosmeticsCommand); ClientCommandHandler.instance.registerCommand(linksCommand); ClientCommandHandler.instance.registerCommand(gamemodesCommand); + ClientCommandHandler.instance.registerCommand(stWhyCommand); ClientCommandHandler.instance.registerCommand(buttonsCommand); ClientCommandHandler.instance.registerCommand(resetRepoCommand); ClientCommandHandler.instance.registerCommand(reloadRepoCommand); @@ -1339,8 +1354,9 @@ public class NotEnoughUpdates { } } } + + hasSkyblockScoreboard = false; } - hasSkyblockScoreboard = false; } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/GuiElementTextField.java b/src/main/java/io/github/moulberry/notenoughupdates/core/GuiElementTextField.java index aded91e6..658ab2f2 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/GuiElementTextField.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/GuiElementTextField.java @@ -112,6 +112,9 @@ public class GuiElementTextField { public void setFocus(boolean focus) { this.focus = focus; + if(!focus) { + textField.setCursorPosition(textField.getCursorPosition()); + } } public boolean getFocus() { return focus; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/PetInfoOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/PetInfoOverlay.java index 1a266ca8..e7f5c8e6 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/PetInfoOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/PetInfoOverlay.java @@ -183,7 +183,6 @@ public class PetInfoOverlay extends TextOverlay { private static int getClosestPetIndex(String petType, int petId, String petItem, float petLevel) { Pet pet = getClosestPet(petType, petId, petItem, petLevel); if(pet == null) { - System.out.println("null pet"); return -1; } else { return getIdForPet(pet); @@ -914,10 +913,7 @@ public class PetInfoOverlay extends TextOverlay { config.petMap.put(config.selectedPet, pet); } } - } - - System.out.println(mouseButtonClicked + ":" + mode); } } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/SlotLocking.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/SlotLocking.java index 4054c4b2..3c53c735 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/SlotLocking.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/SlotLocking.java @@ -553,10 +553,14 @@ public class SlotLocking { } public LockedSlot getLockedSlotIndex(int index) { - if(!NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard() || !NotEnoughUpdates.INSTANCE.config.slotLocking.enableSlotLocking) return null; + if(!NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard() || !NotEnoughUpdates.INSTANCE.config.slotLocking.enableSlotLocking) { + return null; + } LockedSlot[] lockedSlots = getDataForProfile(); - if(lockedSlots == null) return null; + if(lockedSlots == null) { + return null; + } return getLockedSlot(lockedSlots, index); } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/StorageManager.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/StorageManager.java index 66fede9c..53607fae 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/StorageManager.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/StorageManager.java @@ -6,6 +6,7 @@ import io.github.moulberry.notenoughupdates.miscgui.StorageOverlay; import io.github.moulberry.notenoughupdates.util.SBInfo; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.client.gui.inventory.GuiChest; import net.minecraft.init.Blocks; import net.minecraft.inventory.ContainerChest; @@ -147,6 +148,7 @@ public class StorageManager { public static class StoragePage { public ItemStack[] items = new ItemStack[45]; public ItemStack backpackDisplayStack; + public String customTitle; public int rows = -1; public transient boolean matchesSearch; @@ -314,7 +316,9 @@ public class StorageManager { System.currentTimeMillis() - storageOpenSwitchMillis < 1000) return; if(getCurrentPageId() == page) return; - if(getCurrentWindowId() != -1 && onStorageMenu) { + if(page == 0) { + NotEnoughUpdates.INSTANCE.sendChatMessage("/enderchest"); + } else if(getCurrentWindowId() != -1 && onStorageMenu) { if(page < 9) { sendMouseClick(getCurrentWindowId(), 9+page); } else { @@ -324,13 +328,15 @@ public class StorageManager { storageOpenSwitchMillis = System.currentTimeMillis(); desiredStoragePage = page; - NotEnoughUpdates.INSTANCE.sendChatMessage("/storage"); + NotEnoughUpdates.INSTANCE.sendChatMessage("/storage " + (desiredStoragePage-8)); } } private void sendMouseClick(int windowId, int slotIndex) { - Minecraft.getMinecraft().playerController.windowClick(windowId, slotIndex, 0, 0, - Minecraft.getMinecraft().thePlayer); + EntityPlayerSP playerIn = Minecraft.getMinecraft().thePlayer; + short short1 = playerIn.openContainer.getNextTransactionID(playerIn.inventory); + ItemStack itemstack = playerIn.openContainer.getSlot(slotIndex).getStack(); + Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow(windowId, slotIndex, 0, 0, itemstack, short1)); } public int getDisplayIdForStorageId(int storageId) { @@ -343,6 +349,19 @@ public class StorageManager { return -1; } + public boolean onAnyClick() { + if(onStorageMenu && desiredStoragePage >= 0) { + if(desiredStoragePage < 9) { + sendMouseClick(getCurrentWindowId(), 9+desiredStoragePage); + } else { + sendMouseClick(getCurrentWindowId(), 27+desiredStoragePage-MAX_ENDER_CHEST_PAGES); + } + desiredStoragePage = -1; + return true; + } + return false; + } + public void openWindowPacket(S2DPacketOpenWindow packet) { shouldRenderStorageOverlayCached = false; if(!NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) return; @@ -357,14 +376,6 @@ public class StorageManager { if(windowTitle.trim().equals("Storage")) { onStorageMenu = true; - - if(desiredStoragePage >= 0 && System.currentTimeMillis() - storageOpenSwitchMillis < 1000) { - if(desiredStoragePage < 9) { - sendMouseClick(getCurrentWindowId(), 9+desiredStoragePage); - } else { - sendMouseClick(getCurrentWindowId(), 27+desiredStoragePage-MAX_ENDER_CHEST_PAGES); - } - } } else if(matcher.matches()) { int page = Integer.parseInt(matcher.group(1)); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/AccessoryBagOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/AccessoryBagOverlay.java index 760b7bab..6d0873ed 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/AccessoryBagOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/AccessoryBagOverlay.java @@ -355,6 +355,7 @@ public class AccessoryBagOverlay { missingInternal.sort(getItemComparator()); + Set missingDisplayNames = new HashSet<>(); for(String internal : missingInternal) { boolean hasDup = false; @@ -370,6 +371,10 @@ public class AccessoryBagOverlay { } ItemStack stack = NotEnoughUpdates.INSTANCE.manager.jsonToStack(NotEnoughUpdates.INSTANCE.manager.getItemInformation().get(internal), false); + + if(missingDisplayNames.contains(stack.getDisplayName())) continue; + missingDisplayNames.add(stack.getDisplayName()); + if(hasDup) { stack.setStackDisplayName(stack.getDisplayName()+"*"); } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiCustomEnchant.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiCustomEnchant.java index 2fe42cc9..f3cb2ed9 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiCustomEnchant.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiCustomEnchant.java @@ -1,9 +1,19 @@ package io.github.moulberry.notenoughupdates.miscgui; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.core.GlScissorStack; +import io.github.moulberry.notenoughupdates.core.GuiElementTextField; +import io.github.moulberry.notenoughupdates.core.util.lerp.LerpingFloat; +import io.github.moulberry.notenoughupdates.core.util.lerp.LerpingInteger; import io.github.moulberry.notenoughupdates.miscfeatures.SlotLocking; +import io.github.moulberry.notenoughupdates.util.Constants; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.client.gui.Gui; import net.minecraft.client.gui.ScaledResolution; import net.minecraft.client.gui.inventory.GuiContainer; @@ -17,15 +27,20 @@ import net.minecraft.inventory.Slot; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.play.client.C0EPacketClickWindow; import net.minecraft.util.MathHelper; import net.minecraft.util.ResourceLocation; +import org.apache.commons.lang3.text.WordUtils; import org.lwjgl.input.Keyboard; import org.lwjgl.input.Mouse; import org.lwjgl.opengl.GL11; import org.lwjgl.util.glu.Project; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import java.io.PrintStream; import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class GuiCustomEnchant extends Gui { @@ -34,24 +49,98 @@ public class GuiCustomEnchant extends Gui { private static final ResourceLocation ENCHANTMENT_TABLE_BOOK_TEXTURE = new ResourceLocation("textures/entity/enchanting_table_book.png"); private static final ModelBook MODEL_BOOK = new ModelBook(); + private static final int EXPERIENCE_ORB_COUNT = 30; + + private static final Pattern XP_COST_PATTERN = Pattern.compile("\\u00a73(\\d+) Exp Levels"); + private enum EnchantState { NO_ITEM, + ADDING_ENCHANT, + SWITCHING_DONT_UPDATE, INVALID_ITEM, HAS_ITEM } - private static class Enchantment { + private class Enchantment { public int slotIndex; public String enchantName; - public int xpCost = 30; - - public Enchantment(int slotIndex, String enchantName, int xpCost) { + public String enchId; + public List displayLore; + public int level; + public int xpCost = -1; + public boolean overMaxLevel = false; + public boolean conflicts = false; + + public Enchantment(int slotIndex, String enchantName, String enchId, List displayLore, int level, + boolean useMaxLevelForCost, boolean checkConflicts) { this.slotIndex = slotIndex; this.enchantName = enchantName; - this.xpCost = xpCost; + this.enchId = enchId; + this.displayLore = displayLore; + this.level = level; + + if(Constants.ENCHANTS != null) { + if(checkConflicts && Constants.ENCHANTS.has("enchant_pools")) { + JsonArray pools = Constants.ENCHANTS.getAsJsonArray("enchant_pools"); + out: + for(int i=0; i= 1 && Constants.ENCHANTS.has("enchants_xp_cost")) { + JsonObject allCosts = Constants.ENCHANTS.getAsJsonObject("enchants_xp_cost"); + if(allCosts.has(enchId)) { + JsonArray costs = allCosts.getAsJsonArray(enchId); + + if(costs.size() >= 1) { + if(useMaxLevelForCost) { + this.xpCost = costs.get(costs.size()-1).getAsInt(); + } else if(level-1 < costs.size()) { + this.xpCost = costs.get(level-1).getAsInt(); + } else { + overMaxLevel = true; + } + } + } + + } + } } } + public static class ExperienceOrb { + public float x; + public float y; + public float xLast; + public float yLast; + public float xVel; + public float yVel; + + public int type; + public int rotationDeg; + } + + private List orbs = new ArrayList<>(); + private int orbTargetX = 0; + private int orbTargetY = 0; + private int guiLeft; private int guiTop; private boolean shouldOverrideFast = false; @@ -63,17 +152,48 @@ public class GuiCustomEnchant extends Gui { public float bookOpen; public float bookOpenLast; - private static List applicable = new ArrayList<>(); - private static List removable = new ArrayList<>(); + private int currentPage; + private int expectedMaxPage; + + private boolean isScrollingLeft = true; + + private ItemStack enchantingItem = null; + + private int removingEnchantPlayerLevel = -1; + + private GuiElementTextField searchField = new GuiElementTextField("", GuiElementTextField.SCISSOR_TEXT); + + private HashMap playerEnchantIds = new HashMap<>(); + + private boolean searchRemovedFromApplicable = false; + private boolean searchRemovedFromRemovable = false; + private List applicable = new ArrayList<>(); + private List removable = new ArrayList<>(); + + private HashMap enchanterEnchLevels = new HashMap<>(); + private Enchantment enchanterCurrentEnch = null; public Random random = new Random(); private EnchantState currentState = EnchantState.NO_ITEM; private EnchantState lastState = EnchantState.NO_ITEM; + private LerpingInteger leftScroll = new LerpingInteger(0, 150); + private LerpingInteger rightScroll = new LerpingInteger(0, 150); + + private LerpingFloat arrowAmount = new LerpingFloat(0, 100); + private static final int X_SIZE = 364; private static final int Y_SIZE = 215; + private int clickedScrollOffset = -1; + private boolean isClickedScrollLeft = true; + + private boolean isChangingEnchLevel = false; + + private long cancelButtonAnimTime = 0; + private long confirmButtonAnimTime = 0; + public static GuiCustomEnchant getInstance() { return INSTANCE; } @@ -86,81 +206,272 @@ public class GuiCustomEnchant extends Gui { currentState = EnchantState.NO_ITEM; applicable.clear(); removable.clear(); + expectedMaxPage = 1; } return shouldOverrideFast; } + private int tickCounter = 0; public void tick() { GuiContainer chest = ((GuiContainer)Minecraft.getMinecraft().currentScreen); ContainerChest cc = (ContainerChest) chest.inventorySlots; ItemStack stack = cc.getLowerChestInventory().getStackInSlot(23); + ItemStack enchantGuideStack = cc.getLowerChestInventory().getStackInSlot(50); ItemStack enchantingItemStack = cc.getLowerChestInventory().getStackInSlot(19); - if(stack == null || enchantingItemStack == null) { - currentState = EnchantState.NO_ITEM; + int lastPage = currentPage; + + this.lastState = currentState; + if(enchantGuideStack != null && enchantGuideStack.getItem() != Items.book && enchantingItem != null) { + currentState = EnchantState.ADDING_ENCHANT; + } else if(stack == null || enchantingItemStack == null) { + if(currentState == EnchantState.SWITCHING_DONT_UPDATE || currentState == EnchantState.NO_ITEM) { + currentState = EnchantState.NO_ITEM; + } else { + currentState = EnchantState.SWITCHING_DONT_UPDATE; + } } else if(stack.getItem() != Items.dye) { - currentState = EnchantState.HAS_ITEM; + ItemStack sanityCheckStack = cc.getLowerChestInventory().getStackInSlot(12); + if(sanityCheckStack == null || sanityCheckStack.getItem() == Items.enchanted_book) { + currentState = EnchantState.HAS_ITEM; + enchantingItem = enchantingItemStack; + } else { + currentState = EnchantState.SWITCHING_DONT_UPDATE; + } } else if(stack.getItemDamage() == 1) { currentState = EnchantState.INVALID_ITEM; } else { currentState = EnchantState.NO_ITEM; } - applicable.clear(); - removable.clear(); if(currentState == EnchantState.HAS_ITEM) { - Set playerEnchantIds = new HashSet<>(); - - NBTTagCompound tag = enchantingItemStack.getTagCompound(); - if(tag != null) { - NBTTagCompound ea = tag.getCompoundTag("ExtraAttributes"); - if(ea != null) { - NBTTagCompound enchantments = ea.getCompoundTag("enchantments"); - if(enchantments != null) { - playerEnchantIds.addAll(enchantments.getKeySet()); + ItemStack pageUpStack = cc.getLowerChestInventory().getStackInSlot(17); + ItemStack pageDownStack = cc.getLowerChestInventory().getStackInSlot(35); + if(pageUpStack != null && pageDownStack != null) { + currentPage = 0; + boolean upIsGlass = pageUpStack.getItem() == Item.getItemFromBlock(Blocks.stained_glass_pane); + boolean downIsGlass = pageDownStack.getItem() == Item.getItemFromBlock(Blocks.stained_glass_pane); + int page = -1; + + expectedMaxPage = 1; + if(!downIsGlass) { + try { + page = Integer.parseInt(Utils.getRawTooltip(pageDownStack).get(1).substring(11))-1; + expectedMaxPage = page+1; + } catch(Exception ignored) {} + } + if(page == -1 && !upIsGlass) { + try { + page = Integer.parseInt(Utils.getRawTooltip(pageUpStack).get(1).substring(11))+1; + expectedMaxPage = page; + } catch(Exception ignored) {} + } + if(page == -1) { + currentPage = 1; + } else { + currentPage = page; + } + } + } + + List toRemove = new ArrayList<>(); + for(ExperienceOrb orb : orbs) { + float targetDeltaX = guiLeft+orbTargetX - orb.x; + float targetDeltaY = guiTop+orbTargetY - orb.y; + + float length = (float)Math.sqrt(targetDeltaX*targetDeltaX + targetDeltaY*targetDeltaY); + + if(length < 8 && orb.xVel*orb.xVel+orb.yVel*orb.yVel < 20) { + toRemove.add(orb); + continue; + } + + orb.xVel += targetDeltaX*2/length; + orb.yVel += targetDeltaY*2/length; + + orb.xVel *= 0.90; + orb.yVel *= 0.90; + + orb.xLast = orb.x; + orb.yLast = orb.y; + orb.x += orb.xVel; + orb.y += orb.yVel; + } + orbs.removeAll(toRemove); + + if(++tickCounter >= 20) { + tickCounter = 0; + } + + boolean updateItems = tickCounter == 0; + + if(currentState == EnchantState.ADDING_ENCHANT) { + if(arrowAmount.getTarget() != 1) { + arrowAmount.setTarget(1); + arrowAmount.resetTimer(); + } + } else { + if(arrowAmount.getTarget() != 0) { + arrowAmount.setTarget(0); + arrowAmount.resetTimer(); + } + } + + Set allowedSwitchStates = Sets.newHashSet(EnchantState.ADDING_ENCHANT, EnchantState.HAS_ITEM, EnchantState.SWITCHING_DONT_UPDATE); + if(lastState != currentState || lastPage != currentPage) { + if(!allowedSwitchStates.contains(lastState) || !allowedSwitchStates.contains(currentState)) { + leftScroll.setValue(0); + rightScroll.setValue(0); + } + updateItems = true; + } + + if(updateItems && currentState != EnchantState.SWITCHING_DONT_UPDATE) { + enchanterEnchLevels.clear(); + + if(enchantingItem != null) { + playerEnchantIds.clear(); + NBTTagCompound tag = enchantingItem.getTagCompound(); + if(tag != null) { + NBTTagCompound ea = tag.getCompoundTag("ExtraAttributes"); + if(ea != null) { + NBTTagCompound enchantments = ea.getCompoundTag("enchantments"); + if(enchantments != null) { + for(String enchId : enchantments.getKeySet()) { + playerEnchantIds.put(enchId, enchantments.getInteger(enchId)); + } + } } } } - for(int i=0; i<15; i++) { - int slotIndex = 12 + (i%5) + (i/5)*9; - ItemStack book = cc.getLowerChestInventory().getStackInSlot(slotIndex); - if(book != null) { - NBTTagCompound tagBook = book.getTagCompound(); - if(tagBook != null) { - NBTTagCompound ea = tagBook.getCompoundTag("ExtraAttributes"); - if(ea != null) { - NBTTagCompound enchantments = ea.getCompoundTag("enchantments"); - if(enchantments != null) { - for(String enchId : enchantments.getKeySet()) { - String name = Utils.cleanColour(book.getDisplayName()); - if(name.equalsIgnoreCase("Bane of Arthropods")) { - name = "Bane of Arth."; - } else if(name.equalsIgnoreCase("Projectile Protection")) { - name = "Projectile Prot"; - } else if(name.equalsIgnoreCase("Blast Protection")) { - name = "Blast Prot"; + if(currentState == EnchantState.ADDING_ENCHANT) { + removingEnchantPlayerLevel = -1; + boolean updateLevel = enchanterCurrentEnch == null; + for(int i=0; i<27; i++) { + int slotIndex = 9 + i; + ItemStack book = cc.getLowerChestInventory().getStackInSlot(slotIndex); + if(book != null && book.getItem() == Items.enchanted_book) { + NBTTagCompound tagBook = book.getTagCompound(); + if(tagBook != null) { + NBTTagCompound ea = tagBook.getCompoundTag("ExtraAttributes"); + if(ea != null) { + NBTTagCompound enchantments = ea.getCompoundTag("enchantments"); + if(enchantments != null) { + for(String enchId : enchantments.getKeySet()) { + String name = Utils.cleanColour(book.getDisplayName()); + if(name.equalsIgnoreCase("Bane of Arthropods")) { + name = "Bane of Arth."; + } else if(name.equalsIgnoreCase("Projectile Protection")) { + name = "Projectile Prot"; + } else if(name.equalsIgnoreCase("Blast Protection")) { + name = "Blast Prot"; + } + Enchantment enchantment = new Enchantment(slotIndex, name, enchId, + Utils.getRawTooltip(book), enchantments.getInteger(enchId), false, true); + enchantment.displayLore.remove(0); + + if(removingEnchantPlayerLevel == -1 && playerEnchantIds.containsKey(enchId)) { + removingEnchantPlayerLevel = playerEnchantIds.get(enchId); + } + + if(removingEnchantPlayerLevel >= 0 && enchantment.level < removingEnchantPlayerLevel) { + continue; + } + + if(enchanterCurrentEnch == null) { + enchanterCurrentEnch = enchantment; + } else if(updateLevel) { + if(removingEnchantPlayerLevel < 0 && enchantment.level > enchanterCurrentEnch.level) { + enchanterCurrentEnch = enchantment; + } else if(removingEnchantPlayerLevel >= 0 && enchantment.level < enchanterCurrentEnch.level) { + enchanterCurrentEnch = enchantment; + } + } + + enchanterEnchLevels.put(enchantment.level, enchantment); } - Enchantment enchantment = new Enchantment(slotIndex, name, 30); - if(playerEnchantIds.contains(enchId)) { - removable.add(enchantment); - } else { - applicable.add(enchantment); + } + } + } + } + } + if(enchanterCurrentEnch != null && removingEnchantPlayerLevel >= 0) { + for(String line : enchanterCurrentEnch.displayLore) { + Matcher matcher = XP_COST_PATTERN.matcher(line); + if(matcher.find()) { + enchanterCurrentEnch.xpCost = Integer.parseInt(matcher.group(1)); + } + } + } + } else { + isChangingEnchLevel = false; + enchanterCurrentEnch = null; + + searchRemovedFromRemovable = false; + searchRemovedFromApplicable = false; + applicable.clear(); + removable.clear(); + if(currentState == EnchantState.HAS_ITEM) { + for(int i=0; i<15; i++) { + int slotIndex = 12 + (i%5) + (i/5)*9; + ItemStack book = cc.getLowerChestInventory().getStackInSlot(slotIndex); + if(book != null) { + NBTTagCompound tagBook = book.getTagCompound(); + if(tagBook != null) { + NBTTagCompound ea = tagBook.getCompoundTag("ExtraAttributes"); + if(ea != null) { + NBTTagCompound enchantments = ea.getCompoundTag("enchantments"); + if(enchantments != null) { + for(String enchId : enchantments.getKeySet()) { + String name = Utils.cleanColour(book.getDisplayName()); + + if(searchField.getText().trim().isEmpty() || + name.toLowerCase().contains(searchField.getText().trim().toLowerCase())) { + if(name.equalsIgnoreCase("Bane of Arthropods")) { + name = "Bane of Arth."; + } else if(name.equalsIgnoreCase("Projectile Protection")) { + name = "Projectile Prot"; + } else if(name.equalsIgnoreCase("Blast Protection")) { + name = "Blast Prot"; + } else if(name.equalsIgnoreCase("Luck of the Sea")) { + name = "Luck of Sea"; + } + + if(playerEnchantIds.containsKey(enchId)) { + Enchantment enchantment = new Enchantment(slotIndex, name, enchId, + Utils.getRawTooltip(book), playerEnchantIds.get(enchId), false, false); + if(!enchantment.overMaxLevel) { + removable.add(enchantment); + } + } else { + Enchantment enchantment = new Enchantment(slotIndex, name, enchId, + Utils.getRawTooltip(book), enchantments.getInteger(enchId), true, true); + applicable.add(enchantment); + } + } else { + if(playerEnchantIds.containsKey(enchId)) { + searchRemovedFromRemovable = true; + } else { + searchRemovedFromApplicable = true; + } + } + + } } } } } } + removable.sort(Comparator.comparingInt(e -> e.xpCost)); + applicable.sort(Comparator.comparingInt(e -> e.xpCost)); } } - } //Update book model state if (lastState != currentState) { - this.lastState = currentState; - while (true) { this.pageOpenRandom += (float)(this.random.nextInt(4) - this.random.nextInt(4)); @@ -173,7 +484,7 @@ public class GuiCustomEnchant extends Gui { this.pageOpenLast = this.pageOpen; this.bookOpenLast = this.bookOpen; - if (currentState == EnchantState.HAS_ITEM) { + if (currentState == EnchantState.HAS_ITEM || currentState == EnchantState.ADDING_ENCHANT) { this.bookOpen += 0.2F; } else { this.bookOpen -= 0.2F; @@ -189,9 +500,16 @@ public class GuiCustomEnchant extends Gui { public void render(float partialTicks) { if(!(Minecraft.getMinecraft().currentScreen instanceof GuiContainer)) return; + long currentTime = System.currentTimeMillis(); + int playerXpLevel = Minecraft.getMinecraft().thePlayer.experienceLevel; + GuiContainer chest = ((GuiContainer)Minecraft.getMinecraft().currentScreen); ContainerChest cc = (ContainerChest) chest.inventorySlots; + leftScroll.tick(); + rightScroll.tick(); + arrowAmount.tick(); + ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft()); int width = scaledResolution.getScaledWidth(); int height = scaledResolution.getScaledHeight(); @@ -216,56 +534,208 @@ public class GuiCustomEnchant extends Gui { Utils.drawTexturedRect(guiLeft, guiTop, X_SIZE, Y_SIZE, 0, X_SIZE/512f, 0, Y_SIZE/512f, GL11.GL_NEAREST); + Minecraft.getMinecraft().fontRendererObj.drawString("Applicable", guiLeft+7, guiTop+7, 0x404040, false); + Minecraft.getMinecraft().fontRendererObj.drawString("Removable", guiLeft+247, guiTop+7, 0x404040, false); + + if(currentState == EnchantState.HAS_ITEM || currentState == EnchantState.ADDING_ENCHANT) { + String pageStr = "Page: "+currentPage+"/"+expectedMaxPage; + int pageStrLen = Minecraft.getMinecraft().fontRendererObj.getStringWidth(pageStr); + Utils.drawStringCentered(pageStr, Minecraft.getMinecraft().fontRendererObj, + guiLeft+X_SIZE/2, guiTop+14, false, 0x404040); + + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(guiLeft+X_SIZE/2-pageStrLen/2-2-15, guiTop+6, 15, 15, + 0, 15/512f, 372/512f, 387/512f, GL11.GL_NEAREST); + Utils.drawTexturedRect(guiLeft+X_SIZE/2+pageStrLen/2+2, guiTop+6, 15, 15, + 15/512f, 30/512f, 372/512f, 387/512f, GL11.GL_NEAREST); + } + + //Left scroll bar + { + int offset; + if(applicable.size() <= 6) { + offset = 0; + } else if(isScrollingLeft && clickedScrollOffset >= 0) { + offset = mouseY - clickedScrollOffset; + if(offset < 0) offset = 0; + if(offset > 96-15) offset = 96-15; + } else { + offset = Math.round((96-15) * (leftScroll.getValue() / (float)((applicable.size()-6)*16))); + } + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(guiLeft+104, guiTop+18+offset, 12, 15, + 0, 12/512f, 313/512f, (313+15)/512f, GL11.GL_NEAREST); + } + //Right scroll bar + { + int offset; + if(removable.size() <= 6) { + offset = 0; + } else if(!isScrollingLeft && clickedScrollOffset >= 0) { + offset = mouseY - clickedScrollOffset; + if(offset < 0) offset = 0; + if(offset > 96-15) offset = 96-15; + } else { + offset = Math.round((96-15) * (rightScroll.getValue() / (float)((removable.size()-6)*16))); + } + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(guiLeft+344, guiTop+18+offset, 12, 15, + 0, 12/512f, 313/512f, (313+15)/512f, GL11.GL_NEAREST); + } + //Enchant book model renderEnchantBook(scaledResolution, partialTicks); + //Can't be enchanted text + if(currentState == EnchantState.INVALID_ITEM) { + GlStateManager.disableDepth(); + Utils.drawStringCentered("This item can't", Minecraft.getMinecraft().fontRendererObj, + guiLeft+X_SIZE/2, guiTop+88, true, 0xffff5555); + Utils.drawStringCentered("be enchanted", Minecraft.getMinecraft().fontRendererObj, + guiLeft+X_SIZE/2, guiTop+98, true, 0xffff5555); + GlStateManager.enableDepth(); + } + + //Enchant arrow + if(arrowAmount.getValue() > 0) { + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + float w = 22 * arrowAmount.getValue(); + if(removingEnchantPlayerLevel < 0) { + Utils.drawTexturedRect(guiLeft+134, guiTop+58, w, 16, + 0, w/512f, 297/512f, (297+16)/512f, GL11.GL_NEAREST); + } else { + Utils.drawTexturedRect(guiLeft+230-w, guiTop+58, w, 16, + (44-w)/512f, 44/512f, 297/512f, (297+16)/512f, GL11.GL_NEAREST); + } + } + + //Text if no enchants appear + if(currentState == EnchantState.HAS_ITEM || currentState == EnchantState.ADDING_ENCHANT) { + if(applicable.isEmpty() && removable.isEmpty() && searchRemovedFromApplicable) { + Utils.drawStringCentered("Can't find that", Minecraft.getMinecraft().fontRendererObj, + guiLeft+8+48, guiTop+28, true, 0xffff5555); + Utils.drawStringCentered("enchant, perhaps", Minecraft.getMinecraft().fontRendererObj, + guiLeft+8+48, guiTop+38, true, 0xffff5555); + Utils.drawStringCentered("it is on", Minecraft.getMinecraft().fontRendererObj, + guiLeft+8+48, guiTop+48, true, 0xffff5555); + Utils.drawStringCentered("another page?", Minecraft.getMinecraft().fontRendererObj, + guiLeft+8+48, guiTop+58, true, 0xffff5555); + } else if(applicable.isEmpty() && !searchRemovedFromApplicable) { + Utils.drawStringCentered("No applicable", Minecraft.getMinecraft().fontRendererObj, + guiLeft+8+48, guiTop+28, true, 0xffff5555); + Utils.drawStringCentered("enchants on", Minecraft.getMinecraft().fontRendererObj, + guiLeft+8+48, guiTop+38, true, 0xffff5555); + Utils.drawStringCentered("this page...", Minecraft.getMinecraft().fontRendererObj, + guiLeft+8+48, guiTop+48, true, 0xffff5555); + } + if(applicable.isEmpty() && removable.isEmpty() && searchRemovedFromRemovable) { + Utils.drawStringCentered("Can't find that", Minecraft.getMinecraft().fontRendererObj, + guiLeft+248+48, guiTop+28, true, 0xffff5555); + Utils.drawStringCentered("enchant, perhaps", Minecraft.getMinecraft().fontRendererObj, + guiLeft+248+48, guiTop+38, true, 0xffff5555); + Utils.drawStringCentered("it is on", Minecraft.getMinecraft().fontRendererObj, + guiLeft+248+48, guiTop+48, true, 0xffff5555); + Utils.drawStringCentered("another page?", Minecraft.getMinecraft().fontRendererObj, + guiLeft+248+48, guiTop+58, true, 0xffff5555); + } else if(removable.isEmpty() && !searchRemovedFromRemovable) { + Utils.drawStringCentered("No removable", Minecraft.getMinecraft().fontRendererObj, + guiLeft+248+48, guiTop+28, true, 0xffff5555); + Utils.drawStringCentered("enchants on", Minecraft.getMinecraft().fontRendererObj, + guiLeft+248+48, guiTop+38, true, 0xffff5555); + Utils.drawStringCentered("this page...", Minecraft.getMinecraft().fontRendererObj, + guiLeft+248+48, guiTop+48, true, 0xffff5555); + } + } //Available enchants (left) - for(int i=0; i<6; i++) { - if(applicable.size() <= i) break; + GlScissorStack.push(0, guiTop+18, width, guiTop+18+96, scaledResolution); + for(int i=0; i<7; i++) { + int index = i + leftScroll.getValue()/16; + + if(applicable.size() <= index) break; + Enchantment ench = applicable.get(index); + + int top = guiTop-(leftScroll.getValue()%16)+18+16*i; + int vOffset = enchanterCurrentEnch != null && enchanterCurrentEnch.enchId.equals(ench.enchId) ? 16 : 0; + int uOffset = ench.conflicts ? 112 : 0; + int textOffset = vOffset/16; Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); GlStateManager.color(1, 1, 1, 1); - Utils.drawTexturedRect(guiLeft+8, guiTop+18+16*i, 96, 16, - 0, 96/512f, 249/512f, (249+16)/512f, GL11.GL_NEAREST); + Utils.drawTexturedRect(guiLeft+8, top, 96, 16, + uOffset/512f, (96+uOffset)/512f, (249+vOffset)/512f, (249+16+vOffset)/512f, GL11.GL_NEAREST); + + if(mouseX > guiLeft+8 && mouseX <= guiLeft+8+96 && + mouseY > top && mouseY <= top+16) { + disallowClick = true; + if(ench.displayLore != null) { + tooltipToDisplay = ench.displayLore; + } + } - //Utils.drawTexturedRect(guiLeft+8, guiTop+18+16*i, 16, 16, - // 0/512f, 16/512f, 217/512f, (217+16)/512f, GL11.GL_NEAREST); + String levelStr = ""+ench.xpCost; + int colour = 0xc8ff8f; + if(ench.xpCost > playerXpLevel) { + colour = 0xff5555; + } - String levelStr = "35"; int levelWidth = Minecraft.getMinecraft().fontRendererObj.getStringWidth(levelStr); - Minecraft.getMinecraft().fontRendererObj.drawString(levelStr, guiLeft+16-levelWidth/2-1, guiTop+18+16*i+4, 0x2d2102, false); - Minecraft.getMinecraft().fontRendererObj.drawString(levelStr, guiLeft+16-levelWidth/2+1, guiTop+18+16*i+4, 0x2d2102, false); - Minecraft.getMinecraft().fontRendererObj.drawString(levelStr, guiLeft+16-levelWidth/2, guiTop+18+16*i+4-1, 0x2d2102, false); - Minecraft.getMinecraft().fontRendererObj.drawString(levelStr, guiLeft+16-levelWidth/2, guiTop+18+16*i+4+1, 0x2d2102, false); - Minecraft.getMinecraft().fontRendererObj.drawString(levelStr, guiLeft+16-levelWidth/2, guiTop+18+16*i+4, 0xc8ff8f, false); + Minecraft.getMinecraft().fontRendererObj.drawString(levelStr, guiLeft+16-levelWidth/2-1, top+4, 0x2d2102, false); + Minecraft.getMinecraft().fontRendererObj.drawString(levelStr, guiLeft+16-levelWidth/2+1, top+4, 0x2d2102, false); + Minecraft.getMinecraft().fontRendererObj.drawString(levelStr, guiLeft+16-levelWidth/2, top+4-1, 0x2d2102, false); + Minecraft.getMinecraft().fontRendererObj.drawString(levelStr, guiLeft+16-levelWidth/2, top+4+1, 0x2d2102, false); + Minecraft.getMinecraft().fontRendererObj.drawString(levelStr, guiLeft+16-levelWidth/2, top+4, colour, false); - String name = applicable.get(i).enchantName; - Minecraft.getMinecraft().fontRendererObj.drawString(name, guiLeft+8+16+2, guiTop+18+16*i+4, 0xffffffdd, true); + Minecraft.getMinecraft().fontRendererObj.drawString(ench.enchantName, guiLeft+8+16+2+textOffset, top+4+textOffset, 0xffffffdd, true); } + GlScissorStack.pop(scaledResolution); + + //Removable enchants (right) + GlScissorStack.push(0, guiTop+18, width, guiTop+18+96, scaledResolution); + for(int i=0; i<7; i++) { + int index = i + rightScroll.getValue()/16; + + if(removable.size() <= index) break; + Enchantment ench = removable.get(index); - //Removable enchants (left) - for(int i=0; i<6; i++) { - if(removable.size() <= i) break; + int top = guiTop-(rightScroll.getValue()%16)+18+16*i; + int vOffset = enchanterCurrentEnch != null && enchanterCurrentEnch.enchId.equals(ench.enchId) ? 16 : 0; + int textOffset = vOffset/16; Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); GlStateManager.color(1, 1, 1, 1); - Utils.drawTexturedRect(guiLeft+248, guiTop+18+16*i, 96, 16, - 0, 96/512f, 249/512f, (249+16)/512f, GL11.GL_NEAREST); + Utils.drawTexturedRect(guiLeft+248, top, 96, 16, + 0, 96/512f, (249+vOffset)/512f, (249+16+vOffset)/512f, GL11.GL_NEAREST); + + if(mouseX > guiLeft+248 && mouseX <= guiLeft+248+96 && + mouseY > top && mouseY <= top+16) { + disallowClick = true; + if(ench.displayLore != null) { + tooltipToDisplay = ench.displayLore; + } + } - //Utils.drawTexturedRect(guiLeft+8, guiTop+18+16*i, 16, 16, - // 0/512f, 16/512f, 217/512f, (217+16)/512f, GL11.GL_NEAREST); + String levelStr = ""+ench.xpCost; + if(ench.xpCost < 0) levelStr = "?"; + int colour = 0xc8ff8f; + if(ench.xpCost > playerXpLevel) { + colour = 0xff5555; + } - String levelStr = "35"; int levelWidth = Minecraft.getMinecraft().fontRendererObj.getStringWidth(levelStr); - Minecraft.getMinecraft().fontRendererObj.drawString(levelStr, guiLeft+256-levelWidth/2-1, guiTop+18+16*i+4, 0x2d2102, false); - Minecraft.getMinecraft().fontRendererObj.drawString(levelStr, guiLeft+256-levelWidth/2+1, guiTop+18+16*i+4, 0x2d2102, false); - Minecraft.getMinecraft().fontRendererObj.drawString(levelStr, guiLeft+256-levelWidth/2, guiTop+18+16*i+4-1, 0x2d2102, false); - Minecraft.getMinecraft().fontRendererObj.drawString(levelStr, guiLeft+256-levelWidth/2, guiTop+18+16*i+4+1, 0x2d2102, false); - Minecraft.getMinecraft().fontRendererObj.drawString(levelStr, guiLeft+256-levelWidth/2, guiTop+18+16*i+4, 0xc8ff8f, false); - - String name = removable.get(i).enchantName; - Minecraft.getMinecraft().fontRendererObj.drawString(name, guiLeft+248+16+2, guiTop+18+16*i+4, 0xffffffdd, true); + Minecraft.getMinecraft().fontRendererObj.drawString(levelStr, guiLeft+256-levelWidth/2-1, top+4, 0x2d2102, false); + Minecraft.getMinecraft().fontRendererObj.drawString(levelStr, guiLeft+256-levelWidth/2+1, top+4, 0x2d2102, false); + Minecraft.getMinecraft().fontRendererObj.drawString(levelStr, guiLeft+256-levelWidth/2, top+4-1, 0x2d2102, false); + Minecraft.getMinecraft().fontRendererObj.drawString(levelStr, guiLeft+256-levelWidth/2, top+4+1, 0x2d2102, false); + Minecraft.getMinecraft().fontRendererObj.drawString(levelStr, guiLeft+256-levelWidth/2, top+4, colour, false); + + Minecraft.getMinecraft().fontRendererObj.drawString(ench.enchantName, + guiLeft+248+16+2+textOffset, top+4+textOffset, 0xffffffdd, true); } + GlScissorStack.pop(scaledResolution); //Player Inventory Items Minecraft.getMinecraft().fontRendererObj.drawString(Minecraft.getMinecraft().thePlayer.inventory.getDisplayName().getUnformattedText(), @@ -299,8 +769,230 @@ public class GuiCustomEnchant extends Gui { } } + //Search bar + if(currentState == EnchantState.HAS_ITEM) { + if(searchField.getText().isEmpty() && !searchField.getFocus()) { + searchField.setSize(90, 14); + searchField.setPrependText("\u00a77Search..."); + } else { + if(searchField.getFocus()) { + int len = Minecraft.getMinecraft().fontRendererObj.getStringWidth(searchField.getTextDisplay())+10; + searchField.setSize(Math.max(90, len), 14); + } else { + searchField.setSize(90, 14); + } + searchField.setPrependText(""); + } + searchField.render(guiLeft+X_SIZE/2-searchField.getWidth()/2, guiTop+83); + } else if(currentState == EnchantState.ADDING_ENCHANT && + enchanterCurrentEnch != null && !enchanterEnchLevels.isEmpty()) { + int left = guiLeft+X_SIZE/2-56; + int top = guiTop+83; + + int uOffset = enchanterCurrentEnch.conflicts ? 112 : 0; + + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(left, top, 112, 16, + uOffset/512f, (112+uOffset)/512f, 249/512f, (249+16)/512f, GL11.GL_NEAREST); + + if(mouseX > left+16 && mouseX <= left+96 && + mouseY > top && mouseY <= top+16) { + disallowClick = true; + if(enchanterCurrentEnch.displayLore != null) { + tooltipToDisplay = enchanterCurrentEnch.displayLore; + } + } + + //Enchant cost + String levelStr = ""+enchanterCurrentEnch.xpCost; + if(enchanterCurrentEnch.xpCost < 0) levelStr = "?"; + + int colour = 0xc8ff8f; + if(enchanterCurrentEnch.xpCost > playerXpLevel) { + colour = 0xff5555; + } + + int levelWidth = Minecraft.getMinecraft().fontRendererObj.getStringWidth(levelStr); + Minecraft.getMinecraft().fontRendererObj.drawString(levelStr, left+8-levelWidth/2-1, top+4, 0x2d2102, false); + Minecraft.getMinecraft().fontRendererObj.drawString(levelStr, left+8-levelWidth/2+1, top+4, 0x2d2102, false); + Minecraft.getMinecraft().fontRendererObj.drawString(levelStr, left+8-levelWidth/2, top+4-1, 0x2d2102, false); + Minecraft.getMinecraft().fontRendererObj.drawString(levelStr, left+8-levelWidth/2, top+4+1, 0x2d2102, false); + Minecraft.getMinecraft().fontRendererObj.drawString(levelStr, left+8-levelWidth/2, top+4, colour, false); + + //Enchant name + String name = WordUtils.capitalizeFully(enchanterCurrentEnch.enchId.replace("_", " ")); + if(name.equalsIgnoreCase("Bane of Arthropods")) { + name = "Bane of Arth."; + } else if(name.equalsIgnoreCase("Projectile Protection")) { + name = "Projectile Prot"; + } else if(name.equalsIgnoreCase("Blast Protection")) { + name = "Blast Prot"; +