diff options
Diffstat (limited to 'src/main/java/io')
18 files changed, 1697 insertions, 189 deletions
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<String> notificationLines = null; + private static long notificationDisplayMillis = 0; + private static List<String> 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<String> 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<JsonObject> 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<String> 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<String> 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<String> 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<pools.size(); i++) { + JsonArray pool = pools.get(i).getAsJsonArray(); + + boolean hasThis = false; + boolean hasApplied = false; + + for(int j=0; j<pool.size(); j++) { + String enchIdPoolElement = pool.get(j).getAsString(); + if(enchId.equalsIgnoreCase(enchIdPoolElement)) { + hasThis = true; + } else if(playerEnchantIds.containsKey(enchIdPoolElement)) { + hasApplied = true; + } + if(hasThis && hasApplied) { + this.conflicts = true; + break out; + } + } + } + } + + if(level >= 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<ExperienceOrb> 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<Enchantment> applicable = new ArrayList<>(); - private static List<Enchantment> 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<String, Integer> playerEnchantIds = new HashMap<>(); + + private boolean searchRemovedFromApplicable = false; + private boolean searchRemovedFromRemovable = false; + private List<Enchantment> applicable = new ArrayList<>(); + private List<Enchantment> removable = new ArrayList<>(); + + private HashMap<Integer, Enchantment> 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<String> 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<ExperienceOrb> 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<EnchantState> 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"; + } else if(name.equalsIgnoreCase("Luck of the Sea")) { + name = "Luck of Sea"; + } + Utils.drawStringCentered(name, Minecraft.getMinecraft().fontRendererObj, guiLeft+X_SIZE/2, top+8, true, 0xffffffdd); + + if(isChangingEnchLevel) { + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(left+96, top, 16, 16, + 96/512f, 112/512f, 265/512f, (265+16)/512f, GL11.GL_NEAREST); + } + + //Enchant level + levelStr = ""+enchanterCurrentEnch.level; + if(enchanterCurrentEnch.xpCost < 0) levelStr = "?"; + levelWidth = Minecraft.getMinecraft().fontRendererObj.getStringWidth(levelStr); + Minecraft.getMinecraft().fontRendererObj.drawString(levelStr, left+96+8-levelWidth/2-1, top+4, 0x2d2102, false); + Minecraft.getMinecraft().fontRendererObj.drawString(levelStr, left+96+8-levelWidth/2+1, top+4, 0x2d2102, false); + Minecraft.getMinecraft().fontRendererObj.drawString(levelStr, left+96+8-levelWidth/2, top+4-1, 0x2d2102, false); + Minecraft.getMinecraft().fontRendererObj.drawString(levelStr, left+96+8-levelWidth/2, top+4+1, 0x2d2102, false); + Minecraft.getMinecraft().fontRendererObj.drawString(levelStr, left+96+8-levelWidth/2, top+4, 0xea82ff, false); + + //Confirm button + + String confirmText = "Apply"; + if(removingEnchantPlayerLevel >= 0) { + if(removingEnchantPlayerLevel == enchanterCurrentEnch.level) { + confirmText = "Remove"; + } else if(enchanterCurrentEnch.level > removingEnchantPlayerLevel) { + confirmText = "Upgrade"; + } else { + confirmText = "Bad Level"; + } + } + if(System.currentTimeMillis() - confirmButtonAnimTime < 500 && !(playerXpLevel < enchanterCurrentEnch.xpCost)) { + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(guiLeft+X_SIZE/2-1-48, top+18, 48, 14, + 0, 48/512f, 342/512f, (342+14)/512f, GL11.GL_NEAREST); + Utils.drawStringCentered(confirmText, Minecraft.getMinecraft().fontRendererObj, + guiLeft+X_SIZE/2-1-23, top+18+9, false, 0x408040); + } else { + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(guiLeft+X_SIZE/2-1-48, top+18, 48, 14, + 0, 48/512f, 328/512f, (328+14)/512f, GL11.GL_NEAREST); + Utils.drawStringCentered(confirmText, Minecraft.getMinecraft().fontRendererObj, + guiLeft+X_SIZE/2-1-24, top+18+8, false, 0x408040); + + if(playerXpLevel < enchanterCurrentEnch.xpCost) { + Gui.drawRect(guiLeft+X_SIZE/2-1-48, top+18, guiLeft+X_SIZE/2-1, top+18+14, 0x80000000); + } + } + + //Cancel button + if(System.currentTimeMillis() - cancelButtonAnimTime < 500) { + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(guiLeft+X_SIZE/2+1, top+18, 48, 14, + 0, 48/512f, 342/512f, (342+14)/512f, GL11.GL_NEAREST); + Utils.drawStringCentered("Cancel", Minecraft.getMinecraft().fontRendererObj, + guiLeft+X_SIZE/2+1+25, top+18+9, false, 0xa04040); + } else { + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(guiLeft+X_SIZE/2+1, top+18, 48, 14, + 0, 48/512f, 328/512f, (328+14)/512f, GL11.GL_NEAREST); + Utils.drawStringCentered("Cancel", Minecraft.getMinecraft().fontRendererObj, + guiLeft+X_SIZE/2+1+24, top+18+8, false, 0xa04040); + } + + if(mouseY > top+18 && mouseY <= top+18+16) { + if(mouseX > guiLeft+X_SIZE/2-1-48 && mouseX <= guiLeft+X_SIZE/2-1) { + disallowClick = true; + if(enchanterCurrentEnch.displayLore != null) { + tooltipToDisplay = enchanterCurrentEnch.displayLore; + } + } else if(mouseX > guiLeft+X_SIZE/2+1 && mouseX <= guiLeft+X_SIZE/2+1+48) { + disallowClick = true; + tooltipToDisplay = Lists.newArrayList("\u00a7cCancel"); + } + } + + //Enchant level switcher + if(isChangingEnchLevel) { + tooltipToDisplay = null; + + List<Enchantment> before = new ArrayList<>(); + List<Enchantment> after = new ArrayList<>(); + + for(Enchantment ench : enchanterEnchLevels.values()) { + if(ench.level < enchanterCurrentEnch.level) { + before.add(ench); + } else if(ench.level > enchanterCurrentEnch.level) { + after.add(ench); + } + } + + before.sort(Comparator.comparingInt(o -> -o.level)); + after.sort(Comparator.comparingInt(o -> o.level)); + + int bSize = before.size(); + int aSize = after.size(); + GlStateManager.disableDepth(); + for(int i=0; i<bSize+aSize; i++) { + Enchantment ench; + int yIndex; + if(i < bSize) { + ench = before.get(i); + yIndex = -i-1; + } else { + ench = after.get(i-bSize); + yIndex = i-bSize+1; + } + + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + + int type = 0; + if(i == bSize) { + type = 2; + } else if(i == 0) { + type = 1; + } + + if(mouseX > left+96 && mouseX <= left+96+16 && + mouseY > top+16*yIndex && mouseY <= top+16*yIndex+16) { + tooltipToDisplay = new ArrayList<>(ench.displayLore); + if(tooltipToDisplay.size() > 2) { + tooltipToDisplay.remove(tooltipToDisplay.size()-1); + tooltipToDisplay.remove(tooltipToDisplay.size()-1); + } + itemHoverX = -1; + itemHoverY = -1; + } + + Utils.drawTexturedRect(left+96, top+16*yIndex, 16, 16, + 16*type/512f, (16+16*type)/512f, 356/512f, (356+16)/512f, GL11.GL_NEAREST); + + levelStr = ""+ench.level; + levelWidth = Minecraft.getMinecraft().fontRendererObj.getStringWidth(levelStr); + Minecraft.getMinecraft().fontRendererObj.drawString(levelStr, left+96+8-levelWidth/2-1, top+16*yIndex+4, 0x2d2102, false); + Minecraft.getMinecraft().fontRendererObj.drawString(levelStr, left+96+8-levelWidth/2+1, top+16*yIndex+4, 0x2d2102, false); + Minecraft.getMinecraft().fontRendererObj.drawString(levelStr, left+96+8-levelWidth/2, top+16*yIndex+4-1, 0x2d2102, false); + Minecraft.getMinecraft().fontRendererObj.drawString(levelStr, left+96+8-levelWidth/2, top+16*yIndex+4+1, 0x2d2102, false); + Minecraft.getMinecraft().fontRendererObj.drawString(levelStr, left+96+8-levelWidth/2, top+16*yIndex+4, 0xea82ff, false); + } + GlStateManager.enableDepth(); + } + + if(mouseX > left+96 && mouseX <= left+96+16 && + mouseY > top && mouseY <= top+16) { + if(isChangingEnchLevel) { + tooltipToDisplay = Lists.newArrayList("\u00a7cCancel level change"); + } else { + tooltipToDisplay = Lists.newArrayList("\u00a7aChange enchant level"); + } + } + } + //Item enchant input ItemStack itemEnchantInput = cc.getSlot(19).getStack(); + if(itemEnchantInput != null && itemEnchantInput.getItem() == Item.getItemFromBlock(Blocks.stained_glass_pane)) { + itemEnchantInput = enchantingItem; + } { int itemX = guiLeft+174; int itemY = guiTop+58; @@ -312,7 +1004,6 @@ public class GuiCustomEnchant extends Gui { 0, 16/512f, 281/512f, (281+16)/512f, GL11.GL_NEAREST); } else { Utils.drawItemStack(itemEnchantInput, itemX, itemY); - } if(mouseX >= itemX && mouseX < itemX+18 && @@ -327,8 +1018,7 @@ public class GuiCustomEnchant extends Gui { } } - - if(itemHoverX >= 0 && itemHoverY >= 0) { + if(!isChangingEnchLevel && itemHoverX >= 0 && itemHoverY >= 0) { GlStateManager.disableDepth(); GlStateManager.colorMask(true, true, true, false); Gui.drawRect(itemHoverX, itemHoverY, itemHoverX + 16, itemHoverY + 16, @@ -338,6 +1028,33 @@ public class GuiCustomEnchant extends Gui { } GlStateManager.translate(0, 0, 300); + + //Orb animation + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + GlStateManager.disableDepth(); + for(ExperienceOrb orb : orbs) { + int orbX = Math.round(orb.xLast + (orb.x - orb.xLast) * partialTicks); + int orbY = Math.round(orb.yLast + (orb.y - orb.yLast) * partialTicks); + GlStateManager.pushMatrix(); + GlStateManager.translate(orbX, orbY, 0); + GlStateManager.rotate(orb.rotationDeg, 0, 0, 1); + + float targetDeltaX = guiLeft+orbTargetX - orb.x; + float targetDeltaY = guiTop+orbTargetY - orb.y; + float length = (float)Math.sqrt(targetDeltaX*targetDeltaX + targetDeltaY*targetDeltaY); + float velSq = orb.xVel*orb.xVel+orb.yVel*orb.yVel; + float opacity = Math.min(2, Math.max(0.5f, length/16)) * Math.min(2, Math.max(0.5f, velSq/40)); + if(opacity > 1) opacity = 1; + opacity = (float)Math.sqrt(opacity); + GlStateManager.color(1, 1, 1, opacity); + + Utils.drawTexturedRect(-8, -8, 16, 16, + ((orb.type%3)*16)/512f, (16+(orb.type%3)*16)/512f, (217+orb.type/3*16)/512f, (217+16+orb.type/3*16)/512f, GL11.GL_NEAREST); + GlStateManager.popMatrix(); + } + GlStateManager.enableDepth(); + if(stackOnMouse != null) { if(disallowClick) { Utils.drawItemStack(new ItemStack(Item.getItemFromBlock(Blocks.barrier)), mouseX - 8, mouseY - 8); @@ -351,6 +1068,37 @@ public class GuiCustomEnchant extends Gui { GlStateManager.translate(0, 0, -300); } + private void spawnExperienceOrbs(int startX, int startY, int targetX, int targetY, int baseType) { + orbs.clear(); + + this.orbTargetX = targetX; + this.orbTargetY = targetY; + + Random rand = new Random(); + for(int i=0; i<EXPERIENCE_ORB_COUNT; i++) { + ExperienceOrb orb = new ExperienceOrb(); + orb.x = startX; + orb.y = startY; + orb.xLast = startX; + orb.yLast = startY; + orb.xVel = rand.nextFloat()*20 - 10; + orb.yVel = rand.nextFloat()*20 - 10; + orb.type = baseType; + + float typeRand = rand.nextFloat(); + if(typeRand < 0.6) { + orb.type += 0; + } else if(typeRand < 0.9) { + orb.type += 1; + } else { + orb.type += 2; + } + orb.rotationDeg = rand.nextInt(4)*90; + + orbs.add(orb); + } + } + private void renderEnchantBook(ScaledResolution scaledresolution, float partialTicks) { GlStateManager.enableDepth(); @@ -401,7 +1149,7 @@ public class GuiCustomEnchant extends Gui { } public void overrideIsMouseOverSlot(Slot slot, int mouseX, int mouseY, CallbackInfoReturnable<Boolean> cir) { - if(shouldOverrideFast) { + if(shouldOverrideFast && currentState != EnchantState.ADDING_ENCHANT) { boolean playerInv = slot.inventory == Minecraft.getMinecraft().thePlayer.inventory; int slotId = slot.getSlotIndex(); if(playerInv && slotId < 36) { @@ -429,21 +1177,355 @@ public class GuiCustomEnchant extends Gui { } public boolean mouseInput(int mouseX, int mouseY) { - if(mouseX > guiLeft+102 && mouseX < guiLeft+102+144) { - if(mouseY > guiTop+133 && mouseY < guiTop+133+54) { - return false; - } else if(mouseY > guiTop+133+54+4 && mouseY < guiTop+133+54+4+18) { - return false; + if(Mouse.getEventButtonState() && (currentState == EnchantState.HAS_ITEM || currentState == EnchantState.ADDING_ENCHANT)) { + if(mouseY > guiTop+6 && mouseY < guiTop+6+15) { + String pageStr = "Page: "+currentPage+"/"+expectedMaxPage; + int pageStrLen = Minecraft.getMinecraft().fontRendererObj.getStringWidth(pageStr); + + int click = -1; + if(mouseX > guiLeft+X_SIZE/2-pageStrLen/2-2-15 && mouseX <= guiLeft+X_SIZE/2-pageStrLen/2-2) { + click = 17; + } else if(mouseX > guiLeft+X_SIZE/2+pageStrLen/2+2 && mouseX <= guiLeft+X_SIZE/2+pageStrLen/2+2+15) { + click = 35; + } + + if(click >= 0) { + if(currentState == EnchantState.ADDING_ENCHANT) { + if(Mouse.getEventButtonState()) { + if(!(Minecraft.getMinecraft().currentScreen instanceof GuiContainer)) return true; + GuiContainer chest = ((GuiContainer)Minecraft.getMinecraft().currentScreen); + + EntityPlayerSP playerIn = Minecraft.getMinecraft().thePlayer; + short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory); + ItemStack stack = ((ContainerChest)chest.inventorySlots).getLowerChestInventory().getStackInSlot(48); + Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow( + chest.inventorySlots.windowId, 48, 0, 0, stack, transactionID)); + + cancelButtonAnimTime = System.currentTimeMillis(); + } + return true; + } else { + if(!(Minecraft.getMinecraft().currentScreen instanceof GuiContainer)) return true; + GuiContainer chest = ((GuiContainer)Minecraft.getMinecraft().currentScreen); + + EntityPlayerSP playerIn = Minecraft.getMinecraft().thePlayer; + short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory); + ItemStack stack = ((ContainerChest)chest.inventorySlots).getLowerChestInventory().getStackInSlot(click); + Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow( + chest.inventorySlots.windowId, click, 0, 0, stack, transactionID)); + return true; + } + } + } + } + + if(currentState == EnchantState.HAS_ITEM) { + if(Mouse.getEventButtonState()) { + if(mouseX > guiLeft+X_SIZE/2-searchField.getWidth()/2 && mouseX < guiLeft+X_SIZE/2+searchField.getWidth()/2 && + mouseY > guiTop+80 && mouseY < guiTop+96) { + searchField.mouseClicked(mouseX, mouseY, Mouse.getEventButton()); + } else { + searchField.setFocus(false); + } + } else if(Mouse.getEventButton() < 0 && searchField.getFocus() && Mouse.isButtonDown(0)) { + searchField.mouseClickMove(mouseX, mouseY, 0, 0); + } + } else if(currentState == EnchantState.ADDING_ENCHANT && !enchanterEnchLevels.isEmpty()) { + if(Mouse.getEventButtonState()) { + int left = guiLeft+X_SIZE/2-56; + int top = guiTop+83; + + Utils.drawTexturedRect(guiLeft+X_SIZE/2-1-48, top+18, 48, 14, + 0, 48/512f, 328/512f, (328+14)/512f, GL11.GL_NEAREST); + Utils.drawTexturedRect(guiLeft+X_SIZE/2+1, top+18, 48, 14, + 0, 48/512f, 328/512f, (328+14)/512f, GL11.GL_NEAREST); + + if(!isChangingEnchLevel && mouseX > guiLeft+X_SIZE/2+1 && mouseX <= guiLeft+X_SIZE/2+1+48 && + mouseY > top+18 && mouseY <= top+18+14) { + if(!(Minecraft.getMinecraft().currentScreen instanceof GuiContainer)) return true; + GuiContainer chest = ((GuiContainer)Minecraft.getMinecraft().currentScreen); + + EntityPlayerSP playerIn = Minecraft.getMinecraft().thePlayer; + short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory); + ItemStack stack = ((ContainerChest)chest.inventorySlots).getLowerChestInventory().getStackInSlot(48); + Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow( + chest.inventorySlots.windowId, 48, 0, 0, stack, transactionID)); + + cancelButtonAnimTime = System.currentTimeMillis(); + } else if(!isChangingEnchLevel && enchanterCurrentEnch != null && + (mouseX > left+16 && mouseX <= left+96 && + mouseY > top && mouseY <= top+16) || + (mouseX > guiLeft+X_SIZE/2-1-48 && mouseX <= guiLeft+X_SIZE/2-1 && + mouseY > top+18 && mouseY <= top+18+14)) { + if(!(Minecraft.getMinecraft().currentScreen instanceof GuiContainer)) return true; + GuiContainer chest = ((GuiContainer)Minecraft.getMinecraft().currentScreen); + + EntityPlayerSP playerIn = Minecraft.getMinecraft().thePlayer; + short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory); + ItemStack stack = ((ContainerChest)chest.inventorySlots).getLowerChestInventory().getStackInSlot(enchanterCurrentEnch.slotIndex); + Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow( + chest.inventorySlots.windowId, + enchanterCurrentEnch.slotIndex, 0, 0, stack, transactionID)); + + int playerXpLevel = Minecraft.getMinecraft().thePlayer.experienceLevel; + if(playerXpLevel >= enchanterCurrentEnch.xpCost) { + if(removingEnchantPlayerLevel >= 0 && enchanterCurrentEnch.level == removingEnchantPlayerLevel) { + spawnExperienceOrbs(guiLeft+X_SIZE/2, guiTop+66, X_SIZE/2, 36, 3); + } else { + spawnExperienceOrbs(mouseX, mouseY, X_SIZE/2, 66, 0); + } + } + + confirmButtonAnimTime = System.currentTimeMillis(); + } else if(mouseX > left+96 && mouseX <= left+96+16) { + if(!isChangingEnchLevel) { + if(mouseY > top && mouseY < top+16) { + isChangingEnchLevel = true; + return true; + } + } else { + List<Enchantment> before = new ArrayList<>(); + List<Enchantment> after = new ArrayList<>(); + + for(Enchantment ench : enchanterEnchLevels.values()) { + if(ench.level < enchanterCurrentEnch.level) { + before.add(ench); + } else if(ench.level > enchanterCurrentEnch.level) { + after.add(ench); + } + } + + before.sort(Comparator.comparingInt(o -> -o.level)); + after.sort(Comparator.comparingInt(o -> o.level)); + + int bSize = before.size(); + int aSize = after.size(); + for(int i=0; i<bSize+aSize; i++) { + Enchantment ench; + int yIndex; + if(i < bSize) { + yIndex = -i-1; + ench = before.get(i); + } else { + yIndex = i-bSize+1; + ench = after.get(i-bSize); + } + + if(mouseY > top+16*yIndex && mouseY <= top+16*yIndex+16) { + enchanterCurrentEnch = ench; + isChangingEnchLevel = false; + return true; + } + } + } + } + + if(isChangingEnchLevel) { + isChangingEnchLevel = false; + return true; + } + } + } + + if(!Mouse.getEventButtonState() && Mouse.getEventButton() < 0 && clickedScrollOffset != -1) { + LerpingInteger lerpingInteger = isClickedScrollLeft ? leftScroll : rightScroll; + List<Enchantment> enchantsList = isClickedScrollLeft ? applicable : removable; + + if(enchantsList.size() > 6) { + int newOffset = mouseY - clickedScrollOffset; + + int newScroll = Math.round(newOffset * (float)((enchantsList.size()-6)*16) / (96-15)); + int max = (enchantsList.size()-6)*16; + + if(newScroll > max) newScroll = max; + if(newScroll < 0) newScroll = 0; + + lerpingInteger.setValue(newScroll); + } + } + if(Mouse.getEventButton() == 0) { + if(Mouse.getEventButtonState()) { + if(mouseX > guiLeft+104 && mouseX < guiLeft+104+12) { + int offset; + if(applicable.size() <= 6) { + offset = 0; + } else { + offset = Math.round((96-15) * (leftScroll.getValue() / (float)((applicable.size()-6)*16))); + } + if(mouseY >= guiTop+18+offset && mouseY < guiTop+18+offset+15) { + isClickedScrollLeft = true; + clickedScrollOffset = mouseY - offset; + } + } else if(mouseX > guiLeft+344 && mouseX < guiLeft+344+12) { + int offset; + if(removable.size() <= 6) { + offset = 0; + } else { + offset = Math.round((96-15) * (rightScroll.getValue() / (float)((removable.size()-6)*16))); + } + if(mouseY >= guiTop+18+offset && mouseY < guiTop+18+offset+15) { + isClickedScrollLeft = false; + clickedScrollOffset = mouseY - offset; + } + } + } else { + clickedScrollOffset = -1; + } + } + + if(mouseY > guiTop+18 && mouseY < guiTop+18+96) { + if(mouseX > guiLeft+8 && mouseX < guiLeft+8+96) { + if(Mouse.getEventButton() == 0 && Mouse.getEventButtonState() && + Minecraft.getMinecraft().thePlayer.inventory.getItemStack() == null) { + for(int i=0; i<7; i++) { + int index = i + leftScroll.getValue() / 16; + if(applicable.size() <= index) break; + + int top = guiTop - (leftScroll.getValue() % 16) + 18 + 16 * i; + if(mouseX > guiLeft + 8 && mouseX <= guiLeft + 8 + 96 && + mouseY > top && mouseY <= top + 16) { + Enchantment ench = applicable.get(index); + + if(!(Minecraft.getMinecraft().currentScreen instanceof GuiContainer)) return true; + GuiContainer chest = ((GuiContainer)Minecraft.getMinecraft().currentScreen); + + if(currentState == EnchantState.HAS_ITEM) { + EntityPlayerSP playerIn = Minecraft.getMinecraft().thePlayer; + short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory); + ItemStack stack = ((ContainerChest)chest.inventorySlots).getLowerChestInventory().getStackInSlot(ench.slotIndex); + Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow( + chest.inventorySlots.windowId, + ench.slotIndex, 0, 0, stack, transactionID)); + } else if(currentState == EnchantState.ADDING_ENCHANT) { + EntityPlayerSP playerIn = Minecraft.getMinecraft().thePlayer; + short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory); + ItemStack stack = ((ContainerChest)chest.inventorySlots).getLowerChestInventory().getStackInSlot(48); + Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow( + chest.inventorySlots.windowId, 48, 0, 0, stack, transactionID)); + + cancelButtonAnimTime = System.currentTimeMillis(); + } + + return true; + } + } + } + + isScrollingLeft = true; + } else if(mouseX > guiLeft+248 && mouseX < guiLeft+248+96) { + if(Mouse.getEventButton() == 0 && Mouse.getEventButtonState() && + Minecraft.getMinecraft().thePlayer.inventory.getItemStack() == null) { + for(int i=0; i<7; i++) { + int index = i + rightScroll.getValue() / 16; + if(removable.size() <= index) break; + + int top = guiTop - (rightScroll.getValue() % 16) + 18 + 16 * i; + if(mouseX > guiLeft + 248 && mouseX <= guiLeft + 248 + 96 && + mouseY > top && mouseY <= top + 16) { + Enchantment ench = removable.get(index); + + if(!(Minecraft.getMinecraft().currentScreen instanceof GuiContainer)) return true; + GuiContainer chest = ((GuiContainer)Minecraft.getMinecraft().currentScreen); + + if(currentState == EnchantState.HAS_ITEM) { + EntityPlayerSP playerIn = Minecraft.getMinecraft().thePlayer; + short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory); + ItemStack stack = ((ContainerChest)chest.inventorySlots).getLowerChestInventory().getStackInSlot(ench.slotIndex); + Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow( + chest.inventorySlots.windowId, + ench.slotIndex, 0, 0, stack, transactionID)); + } else if(currentState == EnchantState.ADDING_ENCHANT) { + EntityPlayerSP playerIn = Minecraft.getMinecraft().thePlayer; + short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory); + ItemStack stack = ((ContainerChest)chest.inventorySlots).getLowerChestInventory().getStackInSlot(48); + Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow( + chest.inventorySlots.windowId, 48, 0, 0, stack, transactionID)); + + cancelButtonAnimTime = System.currentTimeMillis(); + } + + return true; + } + } + } + isScrollingLeft = false; + } + } + if(Mouse.getEventDWheel() != 0) { + int scroll = Mouse.getEventDWheel(); + if(scroll > 0) { + scroll = -16; + } else { + scroll = 16; + } + + LerpingInteger lerpingInteger = isScrollingLeft ? leftScroll : rightScroll; + + int elementsCount = isScrollingLeft ? applicable.size() : removable.size(); + int max = (elementsCount-6)*16; + + int newTarget = lerpingInteger.getTarget()+scroll; + if(newTarget > max) newTarget = max; + if(newTarget < 0) newTarget = 0; + + if(newTarget != lerpingInteger.getTarget()) { + lerpingInteger.resetTimer(); + lerpingInteger.setTarget(newTarget); + } + } + + if(mouseX > guiLeft+102 && mouseX < guiLeft+102+160) { + if((mouseY > guiTop+133 && mouseY < guiTop+133+54) || (mouseY > guiTop+133+54+4 && mouseY < guiTop+133+54+4+18)) { + if(currentState == EnchantState.ADDING_ENCHANT) { + if(Mouse.getEventButtonState()) { + if(!(Minecraft.getMinecraft().currentScreen instanceof GuiContainer)) return true; + GuiContainer chest = ((GuiContainer)Minecraft.getMinecraft().currentScreen); + + EntityPlayerSP playerIn = Minecraft.getMinecraft().thePlayer; + short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory); + ItemStack stack = ((ContainerChest)chest.inventorySlots).getLowerChestInventory().getStackInSlot(48); + Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow( + chest.inventorySlots.windowId, 48, 0, 0, stack, transactionID)); + + cancelButtonAnimTime = System.currentTimeMillis(); + } + return true; + } else { + return false; + } } } if(mouseX >= guiLeft+173 && mouseX < guiLeft+173+18 && mouseY >= guiTop+57 && mouseY < guiTop+57+18) { - return false; + if(currentState == EnchantState.ADDING_ENCHANT) { + if(Mouse.getEventButtonState()) { + if(!(Minecraft.getMinecraft().currentScreen instanceof GuiContainer)) return true; + GuiContainer chest = ((GuiContainer)Minecraft.getMinecraft().currentScreen); + + EntityPlayerSP playerIn = Minecraft.getMinecraft().thePlayer; + short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory); + ItemStack stack = ((ContainerChest)chest.inventorySlots).getLowerChestInventory().getStackInSlot(48); + Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow( + chest.inventorySlots.windowId, 48, 0, 0, stack, transactionID)); + + cancelButtonAnimTime = System.currentTimeMillis(); + } + return true; + } else { + return false; + } } return true; } public boolean keyboardInput() { + if(currentState == EnchantState.HAS_ITEM && searchField.getFocus()) { + if(Keyboard.getEventKeyState()) { + searchField.keyTyped(Keyboard.getEventCharacter(), Keyboard.getEventKey()); + } + return true; + } + return Keyboard.getEventKey() != Keyboard.KEY_ESCAPE && (!NotEnoughUpdates.INSTANCE.config.slotLocking.enableSlotLocking || Keyboard.getEventKey() != NotEnoughUpdates.INSTANCE.config.slotLocking.slotLockKey); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/StorageOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/StorageOverlay.java index a59131ea..24a4f413 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/StorageOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/StorageOverlay.java @@ -1,14 +1,14 @@ package io.github.moulberry.notenoughupdates.miscgui; import com.google.common.collect.Lists; -import com.google.gson.stream.JsonWriter; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.core.BackgroundBlur; import io.github.moulberry.notenoughupdates.core.GlScissorStack; import io.github.moulberry.notenoughupdates.core.GuiElement; import io.github.moulberry.notenoughupdates.core.GuiElementTextField; +import io.github.moulberry.notenoughupdates.core.config.KeybindHelper; import io.github.moulberry.notenoughupdates.core.util.lerp.LerpingInteger; -import io.github.moulberry.notenoughupdates.core.util.render.RenderUtils; +import io.github.moulberry.notenoughupdates.miscfeatures.SlotLocking; import io.github.moulberry.notenoughupdates.miscfeatures.StorageManager; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; @@ -16,10 +16,12 @@ import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.Gui; import net.minecraft.client.gui.ScaledResolution; import net.minecraft.client.gui.inventory.GuiChest; +import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.client.renderer.OpenGlHelper; +import net.minecraft.client.shader.Framebuffer; import net.minecraft.init.Blocks; -import net.minecraft.inventory.Container; +import net.minecraft.init.Items; import net.minecraft.inventory.ContainerChest; import net.minecraft.inventory.Slot; import net.minecraft.item.Item; @@ -29,12 +31,14 @@ import net.minecraft.util.ResourceLocation; import org.lwjgl.input.Keyboard; import org.lwjgl.input.Mouse; import org.lwjgl.opengl.GL11; -import org.lwjgl.opengl.GLSync; +import org.lwjgl.util.vector.Vector2f; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import java.awt.*; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; public class StorageOverlay extends GuiElement { @@ -42,6 +46,10 @@ public class StorageOverlay extends GuiElement { private static final int CHEST_SLOT_SIZE = 18; private static final int CHEST_BOTTOM_OFFSET = 215; + private Framebuffer framebuffer = null; + + private Set<Vector2f> enchantGlintRenderLocations = new HashSet<>(); + public static final ResourceLocation STORAGE_PREVIEW_TEXTURES[] = new ResourceLocation[4]; private static final ResourceLocation STORAGE_TEXTURES[] = new ResourceLocation[4]; private static final ResourceLocation STORAGE_ICONS_TEXTURE = new ResourceLocation("notenoughupdates:storage_gui/storage_icons.png"); @@ -90,6 +98,8 @@ public class StorageOverlay extends GuiElement { private int desiredHeightMX = -1; private int desiredHeightMY = -1; + private boolean dirty = false; + private int scrollGrabOffset = -1; private LerpingInteger scroll = new LerpingInteger(0, 200); @@ -103,6 +113,10 @@ public class StorageOverlay extends GuiElement { } } + public void markDirty() { + dirty = true; + } + private void scrollToY(int y) { int target = y; if(target < 0) target = 0; @@ -250,6 +264,115 @@ public class StorageOverlay extends GuiElement { boolean mouseInsideStorages = mouseY > guiTop+3 && mouseY < guiTop+3+storageViewSize; //Storages + boolean doItemRender = true; + boolean doRenderFramebuffer = false; + int startY = getPageCoords(0).y; + if(OpenGlHelper.isFramebufferEnabled()) { + int h; + synchronized(StorageManager.getInstance().storageConfig.displayToStorageIdMap) { + int lastDisplayId = StorageManager.getInstance().storageConfig.displayToStorageIdMap.size()-1; + int coords = (int)Math.ceil(lastDisplayId/3f)*3+3; + + h = getPageCoords(coords).y+scroll.getValue(); + } + int w = sizeX; + + //Render from framebuffer + if(framebuffer != null) { + GlScissorStack.push(0, guiTop+3, width, guiTop+3+storageViewSize, scaledResolution); + GlStateManager.enableDepth(); + GlStateManager.translate(0, startY, 107.0001f); + framebuffer.bindFramebufferTexture(); + GlStateManager.color(1, 1, 1, 1); + + Utils.drawTexturedRect(0, 0, w, h, 0, 1, 1, 0, GL11.GL_NEAREST); + renderEnchOverlay(enchantGlintRenderLocations); + + GlStateManager.translate(0, -startY, -107.0001f); + GlScissorStack.pop(scaledResolution); + } + + if(dirty || framebuffer == null) { + dirty = false; + + int fw = w*scaledResolution.getScaleFactor(); + int fh = h*scaledResolution.getScaleFactor(); + + if(framebuffer == null) { + framebuffer = new Framebuffer(fw, fh, true); + } else if(framebuffer.framebufferWidth != fw || framebuffer.framebufferHeight != fh) { + framebuffer.createBindFramebuffer(fw, fh); + } + framebuffer.framebufferClear(); + framebuffer.bindFramebuffer(true); + + GlStateManager.matrixMode(GL11.GL_PROJECTION); + GlStateManager.loadIdentity(); + GlStateManager.ortho(0.0D, w, h, 0.0D, 1000.0D, 3000.0D); + GlStateManager.matrixMode(GL11.GL_MODELVIEW); + + GlStateManager.pushMatrix(); + GlStateManager.translate(-guiLeft, -guiTop-startY, 0); + + doRenderFramebuffer = true; + } else { + doItemRender = false; + } + } + + if(doItemRender) { + enchantGlintRenderLocations.clear(); + for(Map.Entry<Integer, Integer> entry : StorageManager.getInstance().storageConfig.displayToStorageIdMap.entrySet()) { + int displayId = entry.getKey(); + int storageId = entry.getValue(); + + IntPair coords = getPageCoords(displayId); + int storageX = coords.x; + int storageY = coords.y; + + if(!doRenderFramebuffer) { + if(coords.y-11 > 3+storageViewSize || coords.y+90 < 3) continue; + } + + StorageManager.StoragePage page = StorageManager.getInstance().getPage(storageId, false); + if(page != null && page.rows > 0) { + int rows = page.rows; + + for(int k=0; k<rows*9; k++) { + ItemStack stack = page.items[k]; + + if(stack == null) continue; + + int itemX = storageX+1+18*(k%9); + int itemY = storageY+1+18*(k/9); + + if(doRenderFramebuffer) { + Utils.drawItemStackWithoutGlint(stack, itemX, itemY); + if(stack.hasEffect() || stack.getItem() == Items.enchanted_book) { + enchantGlintRenderLocations.add(new Vector2f(itemX, itemY-startY)); + } + } else { + Utils.drawItemStack(stack, itemX, itemY); + } + } + + GlStateManager.disableLighting(); + GlStateManager.enableDepth(); + } + } + } + + if(OpenGlHelper.isFramebufferEnabled() && doRenderFramebuffer) { + GlStateManager.popMatrix(); + Minecraft.getMinecraft().getFramebuffer().bindFramebuffer(true); + + GlStateManager.matrixMode(GL11.GL_PROJECTION); + GlStateManager.loadIdentity(); + GlStateManager.ortho(0.0D, scaledResolution.getScaledWidth_double(), scaledResolution.getScaledHeight_double(), + 0.0D, 1000.0D, 3000.0D); + GlStateManager.matrixMode(GL11.GL_MODELVIEW); + } + GlScissorStack.push(0, guiTop+3, width, guiTop+3+storageViewSize, scaledResolution); for(Map.Entry<Integer, Integer> entry : StorageManager.getInstance().storageConfig.displayToStorageIdMap.entrySet()) { int displayId = entry.getKey(); @@ -261,13 +384,29 @@ public class StorageOverlay extends GuiElement { if(coords.y-11 > 3+storageViewSize || coords.y+90 < 3) continue; + StorageManager.StoragePage page = StorageManager.getInstance().getPage(storageId, false); + + String pageTitle; if(storageId < 9) { - fontRendererObj.drawString("Ender Chest Page "+(storageId+1), storageX, storageY-11, textColour); + pageTitle = "Ender Chest Page " + (storageId + 1); + } else if(page.customTitle != null && !page.customTitle.isEmpty()) { + pageTitle = page.customTitle; + } else if(page != null && page.backpackDisplayStack != null) { + pageTitle = page.backpackDisplayStack.getDisplayName(); } else { - fontRendererObj.drawString("Backpack Slot "+(storageId-8), storageX, storageY-11, textColour); + pageTitle = "Backpack Slot "+(storageId-8); + } + int titleLen = fontRendererObj.getStringWidth(pageTitle); + fontRendererObj.drawString(pageTitle, storageX, storageY-11, textColour); + + if(mouseX >= storageX && mouseX <= storageX+titleLen+15 && + mouseY >= storageY-14 && mouseY <= storageY+1) { + Minecraft.getMinecraft().getTextureManager().bindTexture(storageTexture); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(storageX+titleLen, storageY-14, 15, 15, + 24/600f, 39/600f, 250/400f, 265/ 400f, GL11.GL_NEAREST); } - StorageManager.StoragePage page = StorageManager.getInstance().getPage(storageId, false); if(page == null) { Minecraft.getMinecraft().getTextureManager().bindTexture(storageTexture); GlStateManager.color(1, 1, 1, 1); @@ -312,7 +451,12 @@ public class StorageOverlay extends GuiElement { ItemStack stack = page.items[k]; int itemX = storageX+1+18*(k%9); int itemY = storageY+1+18*(k/9); - Utils.drawItemStack(stack, itemX, itemY); + + /*if(doItemRender || frameBufferItemRender) { + GlStateManager.colorMask(true, true, true, true); + Utils.drawItemStack(stack, itemX, itemY); + GlStateManager.colorMask(false, false, false, false); + }*/ if(!searchBar.getText().isEmpty()) { if(stack == null || !NotEnoughUpdates.INSTANCE.manager.doesStackMatchSearch(stack, searchBar.getText())) { @@ -364,6 +508,31 @@ public class StorageOverlay extends GuiElement { } else { Gui.drawRect(storageX, storageY, storageX+storageW, storageY+storageH, 0x30000000); } + + if(StorageManager.getInstance().desiredStoragePage == storageId && StorageManager.getInstance().onStorageMenu) { + Utils.drawStringCenteredScaledMaxWidth("Please click again to load...", fontRendererObj, + storageX+81-1, storageY+storageH/2-5, false, 150, 0x111111); + Utils.drawStringCenteredScaledMaxWidth("Please click again to load...", fontRendererObj, + storageX+81+1, storageY+storageH/2-5, false, 150, 0x111111); + Utils.drawStringCenteredScaledMaxWidth("Please click again to load...", fontRendererObj, + storageX+81, storageY+storageH/2-5-1, false, 150, 0x111111); + Utils.drawStringCenteredScaledMaxWidth("Please click again to load...", fontRendererObj, + storageX+81, storageY+storageH/2-5+1, false, 150, 0x111111); + Utils.drawStringCenteredScaledMaxWidth("Please click again to load...", fontRendererObj, + storageX+81, storageY+storageH/2-5, false, 150, 0xffdf00); + + Utils.drawStringCenteredScaledMaxWidth("Use /neustwhy for more info", fontRendererObj, + storageX+81-1, storageY+storageH/2+5, false, 150, 0x111111); + Utils.drawStringCenteredScaledMaxWidth("Use /neustwhy for more info", fontRendererObj, + storageX+81+1, storageY+storageH/2+5, false, 150, 0x111111); + Utils.drawStringCenteredScaledMaxWidth("Use /neustwhy for more info", fontRendererObj, + storageX+81, storageY+storageH/2+5-1, false, 150, 0x111111); + Utils.drawStringCenteredScaledMaxWidth("Use /neustwhy for more info", fontRendererObj, + storageX+81, storageY+storageH/2+5+1, false, 150, 0x111111); + Utils.drawStringCenteredScaledMaxWidth("Use /neustwhy for more info", fontRendererObj, + storageX+81, storageY+storageH/2+5, false, 150, 0xffdf00); + } + GlStateManager.enableDepth(); } } @@ -384,7 +553,6 @@ public class StorageOverlay extends GuiElement { int itemX = 181+18*i; int itemY = storageViewSize+76; - //Utils.drawItemStack(playerItems[i], itemX, itemY); GlStateManager.pushMatrix(); GlStateManager.translate(181-8, storageViewSize+18-(inventoryStartIndex/9*18+31), 0); guiChest.drawSlot(containerChest.inventorySlots.get(inventoryStartIndex+i)); @@ -539,6 +707,8 @@ public class StorageOverlay extends GuiElement { vIndex = NotEnoughUpdates.INSTANCE.config.storageGUI.backpackPreview ? 1 : 0; break; case 4: vIndex = NotEnoughUpdates.INSTANCE.config.storageGUI.enderchestPreview ? 1 : 0; break; + case 5: + vIndex = NotEnoughUpdates.INSTANCE.config.storageGUI.masonryMode ? 1 : 0; break; } Utils.drawTexturedRect(buttonX, buttonY, 16, 16, minU, maxU, (vIndex*16)/256f, (vIndex*16+16)/256f, GL11.GL_NEAREST); @@ -596,6 +766,14 @@ public class StorageOverlay extends GuiElement { "Off" ); break; + case 5: + tooltipToDisplay = createTooltip( + "Compact Vertically", + NotEnoughUpdates.INSTANCE.config.storageGUI.masonryMode ? 0 : 1, + "On", + "Off" + ); + break; } } } @@ -622,11 +800,12 @@ public class StorageOverlay extends GuiElement { if(page != null && page.rows > 0) { int rows = page.rows; + GlStateManager.translate(0, 0, 100); + GlStateManager.disableDepth(); BackgroundBlur.renderBlurredBackground(7, width, height, mouseX+2, mouseY+2, 172, 10+18*rows); Utils.drawGradientRect(mouseX+2, mouseY+2, mouseX+174, mouseY+12+18*rows, 0xc0101010, 0xd0101010); Minecraft.getMinecraft().getTextureManager().bindTexture(storagePreviewTexture); - GlStateManager.translate(0, 0, 100); GlStateManager.color(1, 1, 1, 1); Utils.drawTexturedRect(mouseX, mouseY, 176, 7, 0, 1, 0, 7/32f, GL11.GL_NEAREST); for(int i=0; i<rows; i++) { @@ -637,9 +816,12 @@ public class StorageOverlay extends GuiElement { for(int i=0; i<rows*9; i++) { ItemStack stack = page.items[i]; if(stack != null) { + GlStateManager.enableDepth(); Utils.drawItemStack(stack, mouseX+8+18*(i%9), mouseY+8+18*(i/9)); + GlStateManager.disableDepth(); } } + GlStateManager.enableDepth(); GlStateManager.translate(0, 0, -100); } else { Utils.drawHoveringText(tooltipToDisplay, mouseX, mouseY, width, height, -1, Minecraft.getMinecraft().fontRendererObj); @@ -681,10 +863,17 @@ public class StorageOverlay extends GuiElement { public IntPair getPageCoords(int displayId) { if(displayId < 0) displayId = 0; - int y = -scroll.getValue()+17+104*(displayId/3); + int y; + if(NotEnoughUpdates.INSTANCE.config.storageGUI.masonryMode) { + y = -scroll.getValue()+18+108*(displayId/3); + } else { + y = -scroll.getValue()+17+104*(displayId/3); + } for(int i=0; i<=displayId-3; i += 3) { int maxRows = 1; for(int j=i; j<i+3; j++) { + if(NotEnoughUpdates.INSTANCE.config.storageGUI.masonryMode && displayId%3 != j%3) continue; + if(!StorageManager.getInstance().storageConfig.displayToStorageIdMap.containsKey(j)) { continue; } @@ -783,6 +972,7 @@ public class StorageOverlay extends GuiElement { if(mouseX > guiLeft+pageCoords.x && mouseX < guiLeft+pageCoords.x+162 && mouseY > guiTop+pageCoords.y && mouseY < guiTop+pageCoords.y+rows*18) { if(currentPage >= 0 && entry.getValue() == currentPage) { + dirty = true; return false; } else { if(Mouse.getEventButtonState() && Mouse.getEventButton() == 0 && @@ -866,7 +1056,11 @@ public class StorageOverlay extends GuiElement { case 4: NotEnoughUpdates.INSTANCE.config.storageGUI.enderchestPreview = !NotEnoughUpdates.INSTANCE.config.storageGUI.enderchestPreview; break; + case 5: + NotEnoughUpdates.INSTANCE.config.storageGUI.masonryMode = + !NotEnoughUpdates.INSTANCE.config.storageGUI.masonryMode; break; } + dirty = true; } if(mouseX >= guiLeft+10 && mouseX <= guiLeft+171 && @@ -1019,14 +1213,91 @@ public class StorageOverlay extends GuiElement { } if(Keyboard.getEventKeyState()) { + if(NotEnoughUpdates.INSTANCE.config.slotLocking.enableSlotLocking && + KeybindHelper.isKeyPressed(NotEnoughUpdates.INSTANCE.config.slotLocking.slotLockKey)) { + if(!(Minecraft.getMinecraft().currentScreen instanceof GuiContainer)) return true; + GuiContainer container = (GuiContainer) Minecraft.getMinecraft().currentScreen; + + ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft()); + int width = scaledResolution.getScaledWidth(); + int height = scaledResolution.getScaledHeight(); + int mouseX = Mouse.getX() * width / Minecraft.getMinecraft().displayWidth; + int mouseY = height - Mouse.getY() * height / Minecraft.getMinecraft().displayHeight - 1; + + for(Slot slot : container.inventorySlots.inventorySlots) { + if(slot != null && + slot.inventory == Minecraft.getMinecraft().thePlayer.inventory && + container.isMouseOverSlot(slot, mouseX, mouseY)) { + SlotLocking.getInstance().toggleLock(slot.getSlotIndex()); + return true; + } + } + } + String prevText = searchBar.getText(); searchBar.setFocus(true); searchBar.keyTyped(Keyboard.getEventCharacter(), Keyboard.getEventKey()); if(!prevText.equals(searchBar.getText())) { StorageManager.getInstance().searchDisplay(searchBar.getText()); + dirty = true; } } return true; } + + private static final ResourceLocation RES_ITEM_GLINT = new ResourceLocation("textures/misc/enchanted_item_glint.png"); + private void renderEnchOverlay(Set<Vector2f> locations) { + float f = (float)(Minecraft.getSystemTime() % 3000L) / 3000.0F / 8.0F; + float f1 = (float)(Minecraft.getSystemTime() % 4873L) / 4873.0F / 8.0F; + Minecraft.getMinecraft().getTextureManager().bindTexture(RES_ITEM_GLINT); + + GL11.glPushMatrix(); + for(Vector2f loc : locations) { + GlStateManager.pushMatrix(); + GlStateManager.enableRescaleNormal(); + GlStateManager.enableAlpha(); + GlStateManager.alphaFunc(516, 0.1F); + GlStateManager.enableBlend(); + + GlStateManager.disableLighting(); + + GlStateManager.translate(loc.x, loc.y, 0); + + GlStateManager.depthMask(false); + GlStateManager.depthFunc(GL11.GL_EQUAL); + GlStateManager.blendFunc(GL11.GL_SRC_COLOR, GL11.GL_ONE); + GL11.glBlendFunc(GL11.GL_SRC_COLOR, GL11.GL_ONE); + GlStateManager.matrixMode(5890); + GlStateManager.pushMatrix(); + GlStateManager.scale(8.0F, 8.0F, 8.0F); + GlStateManager.translate(f, 0.0F, 0.0F); + GlStateManager.rotate(-50.0F, 0.0F, 0.0F, 1.0F); + + GlStateManager.color(0x80/255f, 0x40/255f, 0xCC/255f, 1); + Utils.drawTexturedRectNoBlend(0, 0, 16, 16, 0, 1/16f, 0, 1/16f, GL11.GL_NEAREST); + + GlStateManager.popMatrix(); + GlStateManager.pushMatrix(); + GlStateManager.scale(8.0F, 8.0F, 8.0F); + GlStateManager.translate(-f1, 0.0F, 0.0F); + GlStateManager.rotate(10.0F, 0.0F, 0.0F, 1.0F); + + GlStateManager.color(0x80/255f, 0x40/255f, 0xCC/255f, 1); + Utils.drawTexturedRectNoBlend(0, 0, 16, 16, 0, 1/16f, 0, 1/16f, GL11.GL_NEAREST); + + GlStateManager.popMatrix(); + GlStateManager.matrixMode(5888); + GlStateManager.blendFunc(770, 771); + GlStateManager.depthFunc(515); + GlStateManager.depthMask(true); + + GlStateManager.popMatrix(); + } + GlStateManager.disableRescaleNormal(); + GL11.glPopMatrix(); + + GlStateManager.bindTexture(0); + } + } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/TradeWindow.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/TradeWindow.java index d4d9ded3..0e4fbdea 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/TradeWindow.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/TradeWindow.java @@ -95,6 +95,26 @@ public class TradeWindow { new Color(64, 64, 64, 255).getRGB()); } + private static int getPrice(String internalname) { + int pricePer = NotEnoughUpdates.INSTANCE.manager.auctionManager.getLowestBin(internalname); + if(pricePer == -1) { + JsonObject bazaarInfo = NotEnoughUpdates.INSTANCE.manager.auctionManager.getBazaarInfo(internalname); + if(bazaarInfo != null && bazaarInfo.has("avg_buy")) { + pricePer = (int)bazaarInfo.get("avg_buy").getAsFloat(); + } + } + if(pricePer == -1) { + JsonObject info = NotEnoughUpdates.INSTANCE.manager.auctionManager.getItemAuctionInfo(internalname); + if(info != null && !NotEnoughUpdates.INSTANCE.manager.auctionManager.isVanillaItem(internalname) && + info.has("price") && info.has("count")) { + int auctionPricePer = (int)(info.get("price").getAsFloat() / info.get("count").getAsFloat()); + + pricePer = auctionPricePer; + } + } + return pricePer; + } + private static int processTopItems(ItemStack stack, Map<Integer, Set<String>> topItems, Map<String, ItemStack> topItemsStack, Map<String, Integer> topItemsCount) { String internalname = NotEnoughUpdates.INSTANCE.manager.getInternalNameForItem(stack); @@ -149,19 +169,7 @@ public class TradeWindow { } catch(Exception ignored) {} } } else { - JsonObject info = NotEnoughUpdates.INSTANCE.manager.auctionManager.getItemAuctionInfo(internalname); - int pricePer = -1; - if(info != null && !NotEnoughUpdates.INSTANCE.manager.auctionManager.isVanillaItem(internalname) && - info.has("price") && info.has("count")) { - int auctionPricePer = (int)(info.get("price").getAsFloat() / info.get("count").getAsFloat()); - - pricePer = auctionPricePer; - } else { - JsonObject bazaarInfo = NotEnoughUpdates.INSTANCE.manager.auctionManager.getBazaarInfo(internalname); - if(bazaarInfo != null && bazaarInfo.has("avg_buy")) { - pricePer = (int)bazaarInfo.get("avg_buy").getAsFloat(); - } - } + int pricePer = getPrice(internalname); if(pricePer > 0) { topItemsStack.putIfAbsent(internalname, stack); @@ -252,19 +260,7 @@ public class TradeWindow { NBTTagCompound nbt = items.getCompoundTagAt(k).getCompoundTag("tag"); String internalname2 = NotEnoughUpdates.INSTANCE.manager.getInternalnameFromNBT(nbt); if(internalname2 != null) { - JsonObject info2 = NotEnoughUpdates.INSTANCE.manager.auctionManager.getItemAuctionInfo(internalname2); - - int pricePer2 = -1; - if(info2 != null && info2.has("price") && info2.has("count")) { - int auctionPricePer2 = (int)(info2.get("price").getAsFloat() / info2.get("count").getAsFloat()); - - pricePer2 = auctionPricePer2; - } else { - JsonObject bazaarInfo2 = NotEnoughUpdates.INSTANCE.manager.auctionManager.getBazaarInfo(internalname2); - if(bazaarInfo2 != null && bazaarInfo2.has("avg_buy")) { - pricePer2 = (int)bazaarInfo2.get("avg_buy").getAsFloat(); - } - } + int pricePer2 = getPrice(internalname2); if(pricePer2 > 0) { int count2 = items.getCompoundTagAt(k).getByte("Count"); price += pricePer2 * count2; @@ -350,18 +346,8 @@ public class TradeWindow { list.add(containerIndex); } } else { - JsonObject info = NotEnoughUpdates.INSTANCE.manager.auctionManager.getItemAuctionInfo(internalname); - int price = -1; - if(info != null && info.has("price") && info.has("count")) { - int auctionPricePer = (int)(info.get("price").getAsFloat() / info.get("count").getAsFloat()); - - price = auctionPricePer * stack.stackSize; - } else { - JsonObject bazaarInfo = NotEnoughUpdates.INSTANCE.manager.auctionManager.getBazaarInfo(internalname); - if(bazaarInfo != null && bazaarInfo.has("avg_buy")) { - price = (int)bazaarInfo.get("avg_buy").getAsFloat() * stack.stackSize; - } - } + int price = getPrice(internalname); + if(price == -1) price = 0; price += getBackpackValue(stack); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiContainer.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiContainer.java index 1312cd17..e527e18e 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiContainer.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiContainer.java @@ -31,6 +31,7 @@ import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; @Mixin(GuiContainer.class) @@ -72,6 +73,11 @@ public abstract class MixinGuiContainer extends GuiScreen { } } + @Redirect(method="mouseReleased", at=@At(value = "INVOKE", target = "Ljava/util/Set;isEmpty()Z")) + public boolean mouseReleased_isEmpty(Set<?> set) { + return set.size() <= 1; + } + @Inject(method="isMouseOverSlot", at=@At("HEAD"), cancellable = true) public void isMouseOverSlot(Slot slotIn, int mouseX, int mouseY, CallbackInfoReturnable<Boolean> cir) { StorageOverlay.getInstance().overrideIsMouseOverSlot(slotIn, mouseX, mouseY, cir); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinMinecraft.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinMinecraft.java index a72f247f..81ab8ec0 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinMinecraft.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinMinecraft.java @@ -8,6 +8,7 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(Minecraft.class) @@ -29,4 +30,9 @@ public class MixinMinecraft { } } + @Redirect(method="loadWorld(Lnet/minecraft/client/multiplayer/WorldClient;Ljava/lang/String;)V", + at=@At(value = "INVOKE", target = "Ljava/lang/System;gc()V")) + public void loadWorld_gc() { + } + } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java b/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java index 5c8b9471..a80cc94a 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java @@ -160,10 +160,10 @@ public class NEUConfig extends Config { public MiscOverlays miscOverlays = new MiscOverlays(); @Expose - /*@Category( + @Category( name = "Storage GUI", desc = "Storage GUI" - )*/ + ) public StorageGUI storageGUI = new StorageGUI(); @Expose @@ -308,6 +308,18 @@ public class NEUConfig extends Config { ) @ConfigEditorButton(runnableId = 8, buttonText = "Open") public boolean editEnchantColoursButton = true; + + @Expose + @ConfigOption( + name = "Chroma Text Speed", + desc = "Change the speed of chroma text for items names (/neucustomize) and enchant colours (/neuec) with the chroma colour code (&z)" + ) + @ConfigEditorSlider( + minValue = 10, + maxValue = 500, + minStep = 10 + ) + public int chromaSpeed = 100; } public static class Notifications { @@ -1197,8 +1209,8 @@ public class NEUConfig extends Config { @Expose @ConfigOption( name = "Enable Storage GUI", - desc = "THIS FEATURE IS CURRENTLY DISABLED BECAUSE HYPIXEL IS TOO LAZY TO ADD A SINGLE COMMAND LMFAO"/*"Show a custom storage overlay when accessing /storage." + - "Makes switching between pages much easier and also allows for searching through all storages"*/ + desc = "Show a custom storage overlay when accessing /storage." + + "Makes switching between pages much easier and also allows for searching through all storages" ) @ConfigEditorBoolean @ConfigAccordionId(id = 1) @@ -1240,12 +1252,21 @@ public class NEUConfig extends Config { @Expose @ConfigOption( name = "Backpack Preview", - desc = "THIS FEATURE IS CURRENTLY DISABLED BECAUSE HYPIXEL IS TOO LAZY TO ADD A SINGLE COMMAND LMFAO"//"Preview Backpacks when hovering over the selector on the left side" + desc = "Preview Backpacks when hovering over the selector on the left side" ) @ConfigEditorBoolean @ConfigAccordionId(id = 1) public boolean backpackPreview = false; + @Expose + @ConfigOption( + name = "Compact Vertically", + desc = "Remove the space between backpacks when there is a size discrepancy" + ) + @ConfigEditorBoolean + @ConfigAccordionId(id = 1) + public boolean masonryMode = false; + @ConfigOption( name = "Inventory Backpacks", desc = "" diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfigEditor.java b/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfigEditor.java index f1c051dc..2d89d4b4 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfigEditor.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfigEditor.java @@ -584,15 +584,15 @@ public class NEUConfigEditor extends GuiElement { continue; } if(editor instanceof GuiOptionEditorAccordion) { - GuiOptionEditorAccordion accordion = (GuiOptionEditorAccordion) editor; - if(accordion.getToggled()) { - int accordionDepth = 0; - if(option.accordionId >= 0) { - accordionDepth = activeAccordions.get(option.accordionId)+1; + GuiOptionEditorAccordion accordion = (GuiOptionEditorAccordion) editor; + if(accordion.getToggled()) { + int accordionDepth = 0; + if(option.accordionId >= 0) { + accordionDepth = activeAccordions.get(option.accordionId)+1; + } + activeAccordions.put(accordion.getAccordionId(), accordionDepth); + } } - activeAccordions.put(accordion.getAccordionId(), accordionDepth); - } - } optionY += editor.getHeight() + 5; if(optionY > 0) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java index 883a0b7a..3fe7d9d3 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java @@ -2103,7 +2103,12 @@ public class GuiProfileViewer extends GuiScreen { float fairySouls = Utils.getElementAsFloat(Utils.getElement(profileInfo, "fairy_souls_collected"), 0); - Utils.renderAlignedString(EnumChatFormatting.LIGHT_PURPLE+"Fairy Souls", EnumChatFormatting.WHITE.toString()+(int)fairySouls+"/220", + + int fairySoulMax = 227; + if(Constants.FAIRYSOULS != null && Constants.FAIRYSOULS.has("Max Souls")) { + fairySoulMax = Constants.FAIRYSOULS.get("Max Souls").getAsInt(); + } + Utils.renderAlignedString(EnumChatFormatting.LIGHT_PURPLE+"Fairy Souls", EnumChatFormatting.WHITE.toString()+(int)fairySouls+"/"+fairySoulMax, guiLeft+xStart, guiTop+yStartBottom, 76); if(skillInfo != null) { float totalSkillLVL = 0; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java b/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java index df981359..1a5e168d 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java @@ -51,7 +51,8 @@ public class SBInfo { private long lastManualLocRaw = -1; private long lastLocRaw = -1; - private long joinedWorld = -1; + public long joinedWorld = -1; + public long unloadedWorld = -1; private JsonObject locraw = null; public boolean isInDungeon = false; @@ -71,7 +72,7 @@ public class SBInfo { } @SubscribeEvent - public void onWorldChange(WorldEvent.Load event) { + public void onWorldLoad(WorldEvent.Load event) { lastLocRaw = -1; locraw = null; mode = null; @@ -79,6 +80,11 @@ public class SBInfo { lastOpenContainerName = null; } + @SubscribeEvent + public void onWorldUnload(WorldEvent.Unload event) { + unloadedWorld = System.currentTimeMillis(); + } + private static final Pattern JSON_BRACKET_PATTERN = Pattern.compile("\\{.+}"); public void onSendChatMessage(String msg) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java b/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java index 4c32c49c..acdd4cb4 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java @@ -1,12 +1,15 @@ package io.github.moulberry.notenoughupdates.util; import com.google.common.base.Splitter; +import com.google.common.collect.Lists; +import com.google.common.collect.Multimap; import com.google.gson.*; import com.mojang.authlib.Agent; import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService; import com.mojang.authlib.yggdrasil.YggdrasilUserAuthentication; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.util.TexLoc; +import net.minecraft.block.Block; import net.minecraft.client.Minecraft; import net.minecraft.client.audio.PositionedSoundRecord; import net.minecraft.client.audio.SoundHandler; @@ -20,8 +23,14 @@ import net.minecraft.client.renderer.texture.DynamicTexture; import net.minecraft.client.renderer.texture.TextureMap; import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.resources.model.IBakedModel; +import net.minecraft.enchantment.Enchantment; +import net.minecraft.enchantment.EnchantmentHelper; +import net.minecraft.entity.EnumCreatureAttribute; +import net.minecraft.entity.ai.attributes.AttributeModifier; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.event.ClickEvent; import net.minecraft.event.HoverEvent; +import net.minecraft.init.Items; import net.minecraft.inventory.Slot; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; @@ -154,6 +163,7 @@ public class Utils { try { itemRender.renderItemAndEffectIntoGUI(stack, x, y); } catch(Exception e) {e.printStackTrace();} //Catch exceptions to ensure that hasEffectOverride is set back to false. + itemRender.renderItemOverlayIntoGUI(Minecraft.getMinecraft().fontRendererObj, stack, x, y, null); hasEffectOverride = false; itemRender.zLevel = 0; RenderHelper.disableStandardItemLighting(); @@ -224,11 +234,15 @@ public class Utils { long currentTimeMillis = System.currentTimeMillis(); if(startTime == 0) startTime = currentTimeMillis; + int chromaSpeed = NotEnoughUpdates.INSTANCE.config.misc.chromaSpeed; + if(chromaSpeed < 10) chromaSpeed = 10; + if(chromaSpeed > 5000) chromaSpeed = 5000; + StringBuilder rainbowText = new StringBuilder(); int len = 0; for(int i=0; i<str.length(); i++) { char c = str.charAt(i); - int index = ((int)(offset+len/12f-(currentTimeMillis-startTime)/100))%rainbow.length; + int index = ((int)(offset+len/12f-(currentTimeMillis-startTime)/chromaSpeed))%rainbow.length; len += Minecraft.getMinecraft().fontRendererObj.getCharWidth(c); if(bold) len++; @@ -293,6 +307,45 @@ public class Utils { return ""; } + public static List<String> getRawTooltip(ItemStack stack) { + List<String> list = Lists.<String>newArrayList(); + String s = stack.getDisplayName(); + + if (stack.hasDisplayName()) { + s = EnumChatFormatting.ITALIC + s; + } + + s = s + EnumChatFormatting.RESET; + + if (!stack.hasDisplayName() && stack.getItem() == Items.filled_map) { + s = s + " #" + stack.getItemDamage(); + } + + list.add(s); + + if (stack.hasTagCompound()) { + if (stack.getTagCompound().hasKey("display", 10)) { + NBTTagCompound nbttagcompound = stack.getTagCompound().getCompoundTag("display"); + + if (nbttagcompound.hasKey("color", 3)) { + list.add(EnumChatFormatting.ITALIC + StatCollector.translateToLocal("item.dyed")); + } + + if (nbttagcompound.getTagId("Lore") == 9) { + NBTTagList nbttaglist1 = nbttagcompound.getTagList("Lore", 8); + + if (nbttaglist1.tagCount() > 0) { + for (int j1 = 0; j1 < nbttaglist1.tagCount(); ++j1) { + list.add(EnumChatFormatting.DARK_PURPLE + "" + EnumChatFormatting.ITALIC + nbttaglist1.getStringTagAt(j1)); + } + } + } + } + } + + return list; + } + public static String floatToString(float f, int decimals) { if(decimals <= 0) { return String.valueOf(Math.round(f)); @@ -473,6 +526,7 @@ public class Utils { public static void drawTexturedRect(float x, float y, float width, float height, float uMin, float uMax, float vMin, float vMax, int filter) { GlStateManager.enableTexture2D(); GlStateManager.enableBlend(); + GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA); GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, filter); |