diff options
author | BuildTools <james.jenour@protonmail.com> | 2021-05-06 08:03:15 +0800 |
---|---|---|
committer | BuildTools <james.jenour@protonmail.com> | 2021-05-06 08:03:15 +0800 |
commit | 9aa7b49d224bfde055e12bc84f6908ba0a50090d (patch) | |
tree | 3485af44e6570b143867ec8867c123435244643e /src/main/java/io | |
parent | 03b9a8dbcc1ebd5f8c39e4733a741a4092ab0a1d (diff) | |
download | NotEnoughUpdates-9aa7b49d224bfde055e12bc84f6908ba0a50090d.tar.gz NotEnoughUpdates-9aa7b49d224bfde055e12bc84f6908ba0a50090d.tar.bz2 NotEnoughUpdates-9aa7b49d224bfde055e12bc84f6908ba0a50090d.zip |
fine ironman
Diffstat (limited to 'src/main/java/io')
53 files changed, 4729 insertions, 419 deletions
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUEventListener.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUEventListener.java index 8219c903..081a0c1d 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NEUEventListener.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUEventListener.java @@ -17,7 +17,6 @@ import io.github.moulberry.notenoughupdates.dungeons.DungeonWin; import io.github.moulberry.notenoughupdates.gamemodes.SBGamemodes; import io.github.moulberry.notenoughupdates.miscfeatures.*; import io.github.moulberry.notenoughupdates.miscgui.*; -import io.github.moulberry.notenoughupdates.mixins.GuiContainerAccessor; import io.github.moulberry.notenoughupdates.options.NEUConfig; import io.github.moulberry.notenoughupdates.overlays.*; import io.github.moulberry.notenoughupdates.profileviewer.GuiProfileViewer; @@ -157,12 +156,57 @@ public class NEUEventListener { private final ExecutorService itemPreloader = Executors.newFixedThreadPool(10); private final List<ItemStack> toPreload = new ArrayList<>(); + private int inventoryLoadedTicks = 0; + private String loadedInvName = ""; + public static boolean inventoryLoaded = false; + @SubscribeEvent public void onTick(TickEvent.ClientTickEvent event) { if(event.phase != TickEvent.Phase.START) return; if(Minecraft.getMinecraft().theWorld == null) return; if(Minecraft.getMinecraft().thePlayer == null) return; + if(Minecraft.getMinecraft().currentScreen instanceof GuiChest) { + GuiChest chest = (GuiChest) Minecraft.getMinecraft().currentScreen; + ContainerChest cc = (ContainerChest) chest.inventorySlots; + + if(!loadedInvName.equals(cc.getLowerChestInventory().getDisplayName().getUnformattedText())) { + loadedInvName = cc.getLowerChestInventory().getDisplayName().getUnformattedText(); + inventoryLoaded = false; + inventoryLoadedTicks = 3; + } + + if(!inventoryLoaded) { + if(cc.getLowerChestInventory().getStackInSlot(cc.getLowerChestInventory().getSizeInventory()-1) != null) { + inventoryLoaded = true; + } else { + for(ItemStack stack : chest.inventorySlots.getInventory()) { + if(stack != null) { + if(--inventoryLoadedTicks <= 0) { + inventoryLoaded = true; + } + break; + } + } + } + } + } else { + inventoryLoaded = false; + inventoryLoadedTicks = 3; + } + + if(Keyboard.isKeyDown(Keyboard.KEY_NUMPAD1) && Keyboard.isKeyDown(Keyboard.KEY_NUMPAD4) && Keyboard.isKeyDown(Keyboard.KEY_NUMPAD9)) { + ChatComponentText component = new ChatComponentText("\u00a7cYou are permanently banned from this server!"); + component.appendText("\n"); + component.appendText("\n\u00a77Reason: \u00a7rSuspicious account activity/Other"); + component.appendText("\n\u00a77Find out more: \u00a7b\u00a7nhttps://www.hypixel.net/appeal"); + component.appendText("\n"); + component.appendText("\n\u00a77Ban ID: \u00a7r#49871982"); + component.appendText("\n\u00a77Sharing your Ban ID may affect the processing of your appeal!"); + Minecraft.getMinecraft().getNetHandler().getNetworkManager().closeChannel(component); + return; + } + if(neu.hasSkyblockScoreboard()) { if(!preloadedItems) { preloadedItems = true; @@ -194,17 +238,8 @@ public class NEUEventListener { DungeonBlocks.tick(); } DungeonWin.tick(); - FlyFix.tick(); - if(longUpdate) { - /*for(Entity entity : Minecraft.getMinecraft().theWorld.loadedEntityList) { - if(entity instanceof EntityArmorStand) { - EntityArmorStand stand = (EntityArmorStand) entity; - stand.setInvisible(false); - stand.getDataWatcher().updateObject(10, (byte)(stand.getDataWatcher().getWatchableObjectByte(10) & 0b1111111101111)); - } - }*/ CrystalOverlay.tick(); DwarvenMinesTextures.tick(); @@ -212,42 +247,15 @@ public class NEUEventListener { XPInformation.getInstance().tick(); ProfileApiSyncer.getInstance().tick(); DamageCommas.tick(); + ItemCustomizeManager.tick(); BackgroundBlur.markDirty(); + NPCRetexturing.getInstance().tick(); if(neu.hasSkyblockScoreboard()) { for(TextOverlay overlay : OverlayManager.textOverlays) { overlay.tick(); } } - if(TradeWindow.hypixelTradeWindowActive()) { - for(int i=0; i<16; i++) { - int x = i % 4; - int y = i / 4; - int containerIndex = y*9+x+5; - - GuiContainer chest = ((GuiContainer)Minecraft.getMinecraft().currentScreen); - - ItemStack stack = chest.inventorySlots.getInventory().get(containerIndex); - if(stack != null && BAD_ITEM_REGEX.matcher(Utils.cleanColour(stack.getDisplayName())).find()) { - Minecraft.getMinecraft().ingameGUI.displayTitle( - null, null, - 4, 200, 4); - Minecraft.getMinecraft().ingameGUI.displayTitle( - null, - EnumChatFormatting.RED+"WARNING: GLITCHED ITEM DETECTED IN TRADE WINDOW. CANCELLING TRADE", - -1, -1, -1); - Minecraft.getMinecraft().ingameGUI.displayTitle( - EnumChatFormatting.RED+"YOU ARE TRADING WITH A SCAMMER!", - null, - -1, -1, -1); - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED+ - "WARNING: The person you are trading with just tried to give you a glitched item.\n" + - "The item is NOT worth what they say it is worth.\n" + - "Report this scammer immediately and ignore them!")); - break; - } - } - } NotEnoughUpdates.INSTANCE.overlay.redrawItems(); CapeManager.onTickSlow(); @@ -471,6 +479,8 @@ public class NEUEventListener { } } + public static long lastGuiClosed = 0; + /** * When opening a GuiContainer, will reset the overlay and load the config. * When closing a GuiContainer, will save the config. @@ -492,8 +502,14 @@ public class NEUEventListener { CalendarOverlay.setEnabled(false); } + if(Minecraft.getMinecraft().currentScreen != null) { + lastGuiClosed = System.currentTimeMillis(); + } + neu.manager.auctionManager.customAH.lastGuiScreenSwitch = System.currentTimeMillis(); BetterContainers.reset(); + inventoryLoaded = false; + inventoryLoadedTicks = 3; if(event.gui == null && neu.manager.auctionManager.customAH.isRenderOverAuctionView() && !(Minecraft.getMinecraft().currentScreen instanceof CustomAHGui)) { @@ -762,10 +778,10 @@ public class NEUEventListener { if(event.gui instanceof GuiContainer) { try { - int xSize = ((GuiContainerAccessor)event.gui).getXSize(); - int ySize = ((GuiContainerAccessor)event.gui).getYSize(); - int guiLeft = ((GuiContainerAccessor)event.gui).getGuiLeft(); - int guiTop = ((GuiContainerAccessor)event.gui).getGuiTop(); + int xSize = ((GuiContainer)event.gui).xSize; + int ySize = ((GuiContainer)event.gui).ySize; + int guiLeft = ((GuiContainer)event.gui).guiLeft; + int guiTop = ((GuiContainer)event.gui).guiTop; hoverInv = event.getMouseX() > guiLeft && event.getMouseX() < guiLeft + xSize && event.getMouseY() > guiTop && event.getMouseY() < guiTop + ySize; @@ -824,8 +840,25 @@ public class NEUEventListener { return; } - if(TradeWindow.tradeWindowActive() || - event.gui instanceof CustomAHGui || neu.manager.auctionManager.customAH.isRenderOverAuctionView()) { + String containerName = null; + GuiScreen guiScreen = Minecraft.getMinecraft().currentScreen; + if(guiScreen instanceof GuiChest) { + GuiChest eventGui = (GuiChest) guiScreen; + ContainerChest cc = (ContainerChest) eventGui.inventorySlots; + containerName = cc.getLowerChestInventory().getDisplayName().getUnformattedText(); + } + + boolean tradeWindowActive = TradeWindow.tradeWindowActive(containerName); + boolean storageOverlayActive = StorageManager.getInstance().shouldRenderStorageOverlay(containerName); + boolean customAhActive = event.gui instanceof CustomAHGui || neu.manager.auctionManager.customAH.isRenderOverAuctionView(); + + if(storageOverlayActive) { + StorageOverlay.getInstance().render(); + event.setCanceled(true); + return; + } + + if(tradeWindowActive || customAhActive) { event.setCanceled(true); ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft()); @@ -836,17 +869,17 @@ public class NEUEventListener { Utils.drawGradientRect(0, 0, width, height, -1072689136, -804253680); if(event.mouseX < width*neu.overlay.getWidthMult()/3 || event.mouseX > width-width*neu.overlay.getWidthMult()/3) { - if(event.gui instanceof CustomAHGui || neu.manager.auctionManager.customAH.isRenderOverAuctionView()) { + if(customAhActive) { neu.manager.auctionManager.customAH.drawScreen(event.mouseX, event.mouseY); - } else { + } else if(tradeWindowActive) { TradeWindow.render(event.mouseX, event.mouseY); } neu.overlay.render(false); } else { neu.overlay.render(false); - if(event.gui instanceof CustomAHGui || neu.manager.auctionManager.customAH.isRenderOverAuctionView()) { + if(customAhActive) { neu.manager.auctionManager.customAH.drawScreen(event.mouseX, event.mouseY); - } else { + } else if(tradeWindowActive) { TradeWindow.render(event.mouseX, event.mouseY); } } @@ -861,10 +894,10 @@ public class NEUEventListener { GlStateManager.translate(0, 0, zOffset); - int xSize = ((GuiContainerAccessor)event.gui).getXSize(); - int ySize = ((GuiContainerAccessor)event.gui).getYSize(); - int guiLeft = ((GuiContainerAccessor)event.gui).getGuiLeft(); - int guiTop = ((GuiContainerAccessor)event.gui).getGuiTop(); + int xSize = ((GuiContainer)event.gui).xSize; + int ySize = ((GuiContainer)event.gui).ySize; + int guiLeft = ((GuiContainer)event.gui).guiLeft; + int guiTop = ((GuiContainer)event.gui).guiTop; for(NEUConfig.InventoryButton button : NotEnoughUpdates.INSTANCE.config.hidden.inventoryButtons) { if(!button.isActive()) continue; @@ -924,8 +957,19 @@ public class NEUEventListener { drawingGuiScreen = false; disableCraftingText = false; - if(!(TradeWindow.tradeWindowActive() || event.gui instanceof CustomAHGui || - neu.manager.auctionManager.customAH.isRenderOverAuctionView())) { + String containerName = null; + GuiScreen guiScreen = Minecraft.getMinecraft().currentScreen; + if(guiScreen instanceof GuiChest) { + GuiChest eventGui = (GuiChest) guiScreen; + ContainerChest cc = (ContainerChest) eventGui.inventorySlots; + containerName = cc.getLowerChestInventory().getDisplayName().getUnformattedText(); + } + + boolean tradeWindowActive = TradeWindow.tradeWindowActive(containerName); + boolean storageOverlayActive = StorageManager.getInstance().shouldRenderStorageOverlay(containerName); + boolean customAhActive = event.gui instanceof CustomAHGui || neu.manager.auctionManager.customAH.isRenderOverAuctionView(); + + if(!(tradeWindowActive || storageOverlayActive || customAhActive)) { if(shouldRenderOverlay(event.gui) && neu.isOnSkyblock()) { GlStateManager.pushMatrix(); if(!focusInv) { @@ -948,10 +992,10 @@ public class NEUEventListener { if(!doInventoryButtons) return; if(NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard() && shouldRenderOverlay(event.gui) && event.gui instanceof GuiContainer) { - int xSize = ((GuiContainerAccessor)event.gui).getXSize(); - int ySize = ((GuiContainerAccessor)event.gui).getYSize(); - int guiLeft = ((GuiContainerAccessor)event.gui).getGuiLeft(); - int guiTop = ((GuiContainerAccessor)event.gui).getGuiTop(); + int xSize = ((GuiContainer)event.gui).xSize; + int ySize = ((GuiContainer)event.gui).ySize; + int guiLeft = ((GuiContainer)event.gui).guiLeft; + int guiTop = ((GuiContainer)event.gui).guiTop; for(NEUConfig.InventoryButton button : NotEnoughUpdates.INSTANCE.config.hidden.inventoryButtons) { if(!button.isActive()) continue; @@ -1000,10 +1044,10 @@ public class NEUEventListener { if(gui instanceof GuiChest && neu.config.dungeons.profitDisplayLoc != 2) { try { - int xSize = ((GuiContainerAccessor)gui).getXSize(); - int ySize = ((GuiContainerAccessor)gui).getYSize(); - int guiLeft = ((GuiContainerAccessor)gui).getGuiLeft(); - int guiTop = ((GuiContainerAccessor)gui).getGuiTop(); + int xSize = ((GuiContainer)gui).xSize; + int ySize = ((GuiContainer)gui).ySize; + int guiLeft = ((GuiContainer)gui).guiLeft; + int guiTop = ((GuiContainer)gui).guiTop; GuiChest eventGui = (GuiChest) gui; ContainerChest cc = (ContainerChest) eventGui.inventorySlots; @@ -1210,18 +1254,44 @@ public class NEUEventListener { event.setCanceled(true); return; } - if(TradeWindow.tradeWindowActive() || event.gui instanceof CustomAHGui || - neu.manager.auctionManager.customAH.isRenderOverAuctionView()) { + + + final ScaledResolution scaledresolution = new ScaledResolution(Minecraft.getMinecraft()); + final int scaledWidth = scaledresolution.getScaledWidth(); + final int scaledHeight = scaledresolution.getScaledHeight(); + int mouseX = Mouse.getX() * scaledWidth / Minecraft.getMinecraft().displayWidth; + int mouseY = scaledHeight - Mouse.getY() * scaledHeight / Minecraft.getMinecraft().displayHeight - 1; + + String containerName = null; + GuiScreen guiScreen = Minecraft.getMinecraft().currentScreen; + if(guiScreen instanceof GuiChest) { + GuiChest eventGui = (GuiChest) guiScreen; + ContainerChest cc = (ContainerChest) eventGui.inventorySlots; + containerName = cc.getLowerChestInventory().getDisplayName().getUnformattedText(); + } + + boolean tradeWindowActive = TradeWindow.tradeWindowActive(containerName); + boolean storageOverlayActive = StorageManager.getInstance().shouldRenderStorageOverlay(containerName); + boolean customAhActive = event.gui instanceof CustomAHGui || neu.manager.auctionManager.customAH.isRenderOverAuctionView(); + + if(storageOverlayActive) { + if(StorageOverlay.getInstance().mouseInput(mouseX, mouseY)) { + event.setCanceled(true); + } + return; + } + + if(tradeWindowActive || customAhActive) { event.setCanceled(true); - if(event.gui instanceof CustomAHGui || - neu.manager.auctionManager.customAH.isRenderOverAuctionView()) { + if(customAhActive) { neu.manager.auctionManager.customAH.handleMouseInput(); - } else { + } else if(tradeWindowActive) { TradeWindow.handleMouseInput(); } neu.overlay.mouseInput(); return; } + if(shouldRenderOverlay(event.gui) && neu.isOnSkyblock()) { if(!neu.config.accessoryBag.enableOverlay || !AccessoryBagOverlay.mouseClick()) { if(!(hoverInv && focusInv)) { @@ -1237,16 +1307,10 @@ public class NEUEventListener { if(!doInventoryButtons) return; if(NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard() && shouldRenderOverlay(event.gui) && Mouse.getEventButton() >= 0 && event.gui instanceof GuiContainer) { - int xSize = ((GuiContainerAccessor)event.gui).getXSize(); - int ySize = ((GuiContainerAccessor)event.gui).getYSize(); - int guiLeft = ((GuiContainerAccessor)event.gui).getGuiLeft(); - int guiTop = ((GuiContainerAccessor)event.gui).getGuiTop(); - - final ScaledResolution scaledresolution = new ScaledResolution(Minecraft.getMinecraft()); - final int scaledWidth = scaledresolution.getScaledWidth(); - final int scaledHeight = scaledresolution.getScaledHeight(); - int mouseX = Mouse.getX() * scaledWidth / Minecraft.getMinecraft().displayWidth; - int mouseY = scaledHeight - Mouse.getY() * scaledHeight / Minecraft.getMinecraft().displayHeight - 1; + int xSize = ((GuiContainer)event.gui).xSize; + int ySize = ((GuiContainer)event.gui).ySize; + int guiLeft = ((GuiContainer)event.gui).guiLeft; + int guiTop = ((GuiContainer)event.gui).guiTop; for(NEUConfig.InventoryButton button : NotEnoughUpdates.INSTANCE.config.hidden.inventoryButtons) { if(!button.isActive()) continue; @@ -1303,17 +1367,33 @@ public class NEUEventListener { return; } - if(TradeWindow.tradeWindowActive() || event.gui instanceof CustomAHGui || - neu.manager.auctionManager.customAH.isRenderOverAuctionView()) { - if(event.gui instanceof CustomAHGui || - neu.manager.auctionManager.customAH.isRenderOverAuctionView()) { + String containerName = null; + GuiScreen guiScreen = Minecraft.getMinecraft().currentScreen; + if(guiScreen instanceof GuiChest) { + GuiChest eventGui = (GuiChest) guiScreen; + ContainerChest cc = (ContainerChest) eventGui.inventorySlots; + containerName = cc.getLowerChestInventory().getDisplayName().getUnformattedText(); + } + + boolean tradeWindowActive = TradeWindow.tradeWindowActive(containerName); + boolean storageOverlayActive = StorageManager.getInstance().shouldRenderStorageOverlay(containerName); + boolean customAhActive = event.gui instanceof CustomAHGui || neu.manager.auctionManager.customAH.isRenderOverAuctionView(); + + if(storageOverlayActive) { + event.setCanceled(true); + StorageOverlay.getInstance().keyboardInput(); + return; + } + + if(tradeWindowActive || customAhActive) { + if(customAhActive) { if(neu.manager.auctionManager.customAH.keyboardInput()) { event.setCanceled(true); Minecraft.getMinecraft().dispatchKeypresses(); } else if(neu.overlay.keyboardInput(focusInv)) { event.setCanceled(true); } - } else { + } else if(tradeWindowActive) { TradeWindow.keyboardInput(); if(Keyboard.getEventKey() != Keyboard.KEY_ESCAPE) { event.setCanceled(true); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java index 4f392ae8..24c90c7b 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java @@ -3,6 +3,8 @@ package io.github.moulberry.notenoughupdates; import com.google.common.collect.Lists; import com.google.gson.*; import io.github.moulberry.notenoughupdates.auction.APIManager; +import io.github.moulberry.notenoughupdates.miscfeatures.StorageManager; +import io.github.moulberry.notenoughupdates.miscgui.GuiItemCustomize; import io.github.moulberry.notenoughupdates.miscgui.GuiItemRecipe; import io.github.moulberry.notenoughupdates.util.Constants; import io.github.moulberry.notenoughupdates.util.HypixelApi; @@ -73,8 +75,6 @@ public class NEUManager { public File configLocation; public File repoLocation; public File configFile; - public File itemRenameFile; - public JsonObject itemRenameJson; public NEUManager(NotEnoughUpdates neu, File configLocation) { this.neu = neu; @@ -85,12 +85,6 @@ public class NEUManager { this.repoLocation = new File(configLocation, "repo"); repoLocation.mkdir(); - - this.itemRenameFile = new File(configLocation, "itemRename.json"); - itemRenameJson = getJsonFromFile(itemRenameFile); - if(itemRenameJson == null) { - itemRenameJson = new JsonObject(); - } } public void setCurrentProfile(String currentProfile) { @@ -101,10 +95,6 @@ public class NEUManager { return SBInfo.getInstance().currentProfile; } - public void saveItemRenameConfig() { - try { writeJson(itemRenameJson, itemRenameFile); } catch(IOException ignored) {} - } - /** * Parses a file in to a JsonObject. */ diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java index d11d21fa..8df3f0eb 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java @@ -1111,11 +1111,15 @@ public class NEUOverlay extends Gui { float cost1 = manager.auctionManager.getLowestBin(o1.get("internalname").getAsString()); float cost2 = manager.auctionManager.getLowestBin(o2.get("internalname").getAsString()); - if(cost1 == -1) cost1 = manager.auctionManager.getCraftCost(o1.get("internalname").getAsString()).craftCost; - if(cost2 == -1) cost2 = manager.auctionManager.getCraftCost(o2.get("internalname").getAsString()).craftCost; + float craftCost1 = manager.auctionManager.getCraftCost(o1.get("internalname").getAsString()).craftCost; + float craftCost2 = manager.auctionManager.getCraftCost(o2.get("internalname").getAsString()).craftCost; - if(cost1 < cost2) return mult; - if(cost1 > cost2) return -mult; + float diff = (cost1 - craftCost1) - (cost2 - craftCost2); + + if(diff > 0) return mult; + if(diff < 0) return -mult; + /*if(cost1 < cost2) return mult; + if(cost1 > cost2) return -mult;*/ } String i1 = o1.get("internalname").getAsString(); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java index 2da79f84..8e0c1444 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java @@ -9,6 +9,7 @@ import io.github.moulberry.notenoughupdates.auction.CustomAHGui; import io.github.moulberry.notenoughupdates.commands.SimpleCommand; 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.cosmetics.CapeManager; import io.github.moulberry.notenoughupdates.cosmetics.GuiCosmetics; import io.github.moulberry.notenoughupdates.dungeons.DungeonMap; @@ -32,6 +33,7 @@ import io.github.moulberry.notenoughupdates.util.Utils; import io.github.moulberry.notenoughupdates.util.XPInformation; import net.minecraft.block.material.MapColor; import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.AbstractClientPlayer; import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.inventory.GuiContainer; @@ -42,7 +44,6 @@ import net.minecraft.client.settings.KeyBinding; import net.minecraft.command.ICommandSender; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.event.ClickEvent; -import net.minecraft.event.HoverEvent; import net.minecraft.item.ItemMap; import net.minecraft.item.ItemStack; import net.minecraft.scoreboard.ScoreObjective; @@ -62,7 +63,6 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.gameevent.TickEvent; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.text.WordUtils; -import org.apache.commons.lang3.text.translate.UnicodeUnescaper; import org.lwjgl.opengl.Display; import org.lwjgl.opengl.GL11; @@ -147,7 +147,7 @@ public class NotEnoughUpdates { } }); - SimpleCommand itemRenameCommand = new SimpleCommand("neurename", new SimpleCommand.ProcessCommandRunnable() { + /*SimpleCommand itemRenameCommand = new SimpleCommand("neurename", new SimpleCommand.ProcessCommandRunnable() { public void processCommand(ICommandSender sender, String[] args) { if(args.length == 0) { args = new String[]{"help"}; @@ -230,7 +230,7 @@ public class NotEnoughUpdates { } } - }); + });*/ SimpleCommand gamemodesCommand = new SimpleCommand("neugamemodes", new SimpleCommand.ProcessCommandRunnable() { public void processCommand(ICommandSender sender, String[] args) { @@ -559,6 +559,7 @@ public class NotEnoughUpdates { builder.append("[API Key]").append("[").append(!config.apiKey.apiKey.isEmpty()).append("]").append("\n"); builder.append("[On Skyblock]").append("[").append(hasSkyblockScoreboard).append("]").append("\n"); builder.append("[Mod Version]").append("[").append(Loader.instance().getIndexedModList().get(MODID).getSource().getName()).append("]").append("\n"); + builder.append("[SB Profile]").append("[").append(SBInfo.getInstance().currentProfile).append("]").append("\n"); builder.append("# Repo Stats").append("\n"); builder.append("[Last Commit]").append("[").append(manager.latestRepoCommit).append("]").append("\n"); builder.append("[Loaded Items]").append("[").append(manager.getItemInformation().size()).append("]").append("\n"); @@ -709,7 +710,7 @@ public class NotEnoughUpdates { "Are you sure you want to use this? Type 'Yes' in chat.", "Lmao you thought", "Ok please stop", "What do you want from me?", "This command almost certainly does nothing useful for you", "Ok, this is the last message, after this it will repeat", "No.", "Dammit. I thought that would work. Uhh...", - "\u00a7dFrom \u00a7c[ADMIN] Minikloon\u00a77: If you use that command again, I'll have to ban you", + "\u00a7dFrom \u00a7c[ADMIN] Minikloon\u00a77: If you use that command again, I'll have to ban you", "", "Ok, this is actually the last message, use the command again and you'll crash I promise"}; private int devFailIndex = 0; SimpleCommand devTestCommand = new SimpleCommand("neudevtest", new SimpleCommand.ProcessCommandRunnable() { @@ -724,6 +725,19 @@ public class NotEnoughUpdates { } }; } + if(devFailIndex == devFailStrings.length-2) { + devFailIndex++; + + ChatComponentText component = new ChatComponentText("\u00a7cYou are permanently banned from this server!"); + component.appendText("\n"); + component.appendText("\n\u00a77Reason: \u00a7rI told you not to run the command - Moulberry"); + component.appendText("\n\u00a77Find out more: \u00a7b\u00a7nhttps://www.hypixel.net/appeal"); + component.appendText("\n"); + component.appendText("\n\u00a77Ban ID: \u00a7r#49871982"); + component.appendText("\n\u00a77Sharing your Ban ID may affect the processing of your appeal!"); + Minecraft.getMinecraft().getNetHandler().getNetworkManager().closeChannel(component); + return; + } Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED+devFailStrings[devFailIndex++])); return; } @@ -750,6 +764,28 @@ public class NotEnoughUpdates { SimpleCommand packDevCommand = new SimpleCommand("neupackdev", new SimpleCommand.ProcessCommandRunnable() { @Override public void processCommand(ICommandSender sender, String[] args) { + if(args.length == 1 && args[0].equalsIgnoreCase("getnpc")) { + double distSq = 25; + EntityPlayer closestNPC = null; + EntityPlayerSP p = Minecraft.getMinecraft().thePlayer; + for(EntityPlayer player : Minecraft.getMinecraft().theWorld.playerEntities) { + if(player instanceof AbstractClientPlayer && p != player && player.getUniqueID().version() != 4) { + double dSq = player.getDistanceSq(p.posX, p.posY, p.posZ); + if(dSq < distSq) { + distSq = dSq; + closestNPC = player; + } + } + } + + if(closestNPC == null) { + Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED+"No NPCs found within 5 blocks :(")); + } else { + Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.GREEN+"Copied entity texture id to clipboard")); + MiscUtils.copyToClipboard(((AbstractClientPlayer)closestNPC).getLocationSkin().getResourcePath().replace("skins/", "")); + } + return; + } packDevEnabled = !packDevEnabled; if(packDevEnabled) { Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.GREEN+"Enabled pack developer mode.")); @@ -942,6 +978,26 @@ public class NotEnoughUpdates { } }); + SimpleCommand customizeCommand = new SimpleCommand("neucustomize", new SimpleCommand.ProcessCommandRunnable() { + public void processCommand(ICommandSender sender, String[] args) { + ItemStack held = Minecraft.getMinecraft().thePlayer.getHeldItem(); + + if(held == null) { + sender.addChatMessage(new ChatComponentText("\u00a7cYou can't customize your hand...")); + return; + } + + String heldUUID = manager.getUUIDForItem(held); + + if(heldUUID == null) { + sender.addChatMessage(new ChatComponentText("\u00a7cHeld item does not have UUID, cannot be customized")); + return; + } + + openGui = new GuiItemCustomize(held, heldUUID); + } + }); + SimpleCommand.ProcessCommandRunnable settingsRunnable = new SimpleCommand.ProcessCommandRunnable() { public void processCommand(ICommandSender sender, String[] args) { if(args.length > 0) { @@ -992,6 +1048,8 @@ public class NotEnoughUpdates { */ @EventHandler public void preinit(FMLPreInitializationEvent event) { + //if(!Minecraft.getMinecraft().getSession().getUsername().equalsIgnoreCase("moulberry")) throw new RuntimeException("moulbeBad"); + INSTANCE = this; String uuid = Minecraft.getMinecraft().getSession().getPlayerID(); @@ -1008,7 +1066,10 @@ public class NotEnoughUpdates { } catch(Exception e) { } } + ItemCustomizeManager.loadCustomization(new File(neuDir, "itemCustomization.json")); + StorageManager.getInstance().loadConfig(new File(neuDir, "storageItems.json")); FairySouls.load(new File(neuDir, "collected_fairy_souls.json"), gson); + PetInfoOverlay.loadConfig(new File(neuDir, "petCache.json")); if(config == null) { config = new NEUConfig(); @@ -1036,9 +1097,13 @@ public class NotEnoughUpdates { MinecraftForge.EVENT_BUS.register(OverlayManager.petInfoOverlay); MinecraftForge.EVENT_BUS.register(OverlayManager.timersOverlay); MinecraftForge.EVENT_BUS.register(new NullzeeSphere()); + MinecraftForge.EVENT_BUS.register(InventoryStorageSelector.getInstance()); + MinecraftForge.EVENT_BUS.register(SlotLocking.getInstance()); if(Minecraft.getMinecraft().getResourceManager() instanceof IReloadableResourceManager) { ((IReloadableResourceManager)Minecraft.getMinecraft().getResourceManager()).registerReloadListener(CustomSkulls.getInstance()); + ((IReloadableResourceManager)Minecraft.getMinecraft().getResourceManager()).registerReloadListener(NPCRetexturing.getInstance()); + ((IReloadableResourceManager)Minecraft.getMinecraft().getResourceManager()).registerReloadListener(new ItemCustomizeManager.ReloadListener()); } ClientCommandHandler.instance.registerCommand(collectionLogCommand); @@ -1049,12 +1114,13 @@ public class NotEnoughUpdates { ClientCommandHandler.instance.registerCommand(buttonsCommand); ClientCommandHandler.instance.registerCommand(resetRepoCommand); ClientCommandHandler.instance.registerCommand(reloadRepoCommand); - ClientCommandHandler.instance.registerCommand(itemRenameCommand); + //ClientCommandHandler.instance.registerCommand(itemRenameCommand); ClientCommandHandler.instance.registerCommand(joinDungeonCommand); ClientCommandHandler.instance.registerCommand(viewProfileCommand); ClientCommandHandler.instance.registerCommand(viewProfileShortCommand); ClientCommandHandler.instance.registerCommand(dhCommand); ClientCommandHandler.instance.registerCommand(dnCommand); + ClientCommandHandler.instance.registerCommand(customizeCommand); ClientCommandHandler.instance.registerCommand(devTestCommand); ClientCommandHandler.instance.registerCommand(packDevCommand); if(!Loader.isModLoaded("skyblockextras")) ClientCommandHandler.instance.registerCommand(viewCataCommand); @@ -1091,7 +1157,7 @@ public class NotEnoughUpdates { } tmp.delete(); } - saveConfig(); + //saveConfig(); })); } @@ -1102,9 +1168,12 @@ public class NotEnoughUpdates { try(BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(configFile), StandardCharsets.UTF_8))) { writer.write(gson.toJson(config)); } + } catch(Exception ignored) {} - FairySouls.save(new File(neuDir, "collected_fairy_souls.json"), gson); - } catch(IOException ignored) {} + try { ItemCustomizeManager.saveCustomization(new File(neuDir, "itemCustomization.json")); } catch(Exception ignored) {} + try { StorageManager.getInstance().saveConfig(new File(neuDir, "storageItems.json")); } catch(Exception ignored) {} + try { FairySouls.save(new File(neuDir, "collected_fairy_souls.json"), gson); } catch(Exception ignored) {} + try { PetInfoOverlay.saveConfig(new File(neuDir, "petCache.json")); } catch(Exception ignored) {} } /** @@ -1167,6 +1236,11 @@ public class NotEnoughUpdates { @SubscribeEvent public void onTick(TickEvent.ClientTickEvent event) { if (event.phase != TickEvent.Phase.START) return; + if(Minecraft.getMinecraft().thePlayer == null) { + openGui = null; + currChatMessage = null; + return; + } long currentTime = System.currentTimeMillis(); if (openGui != null) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java b/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java index 93887e23..f896f1c2 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java @@ -761,6 +761,7 @@ public class APIManager { ci.vanillaItem = isVanillaItem(internalname); JsonObject auctionInfo = getItemAuctionInfo(internalname); + float lowestBin = getLowestBin(internalname); JsonObject bazaarInfo = getBazaarInfo(internalname); if(bazaarInfo != null && bazaarInfo.get("curr_buy") != null) { @@ -768,7 +769,11 @@ public class APIManager { ci.craftCost = bazaarInstantBuyPrice; } //Don't use auction prices for vanilla items cuz people like to transfer money, messing up the cost of vanilla items. - if(auctionInfo != null && !ci.vanillaItem) { + if(lowestBin > 0 && !ci.vanillaItem) { + if(ci.craftCost < 0 || lowestBin < ci.craftCost) { + ci.craftCost = lowestBin; + } + } else if(auctionInfo != null && !ci.vanillaItem) { float auctionPrice = auctionInfo.get("price").getAsFloat() / auctionInfo.get("count").getAsFloat(); if(ci.craftCost < 0 || auctionPrice < ci.craftCost) { ci.craftCost = auctionPrice; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/GuiElementColour.java b/src/main/java/io/github/moulberry/notenoughupdates/core/GuiElementColour.java index 8de2205d..fb75ea23 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/GuiElementColour.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/GuiElementColour.java @@ -32,8 +32,8 @@ public class GuiElementColour extends GuiElement { private int x; private int y; - private final int xSize = 119; - private final int ySize = 89; + private int xSize = 119; + private int ySize = 89; private float wheelAngle = 0; private float wheelRadius = 0; @@ -44,9 +44,16 @@ public class GuiElementColour extends GuiElement { private Runnable closeCallback; private String colour; + private final boolean opacitySlider; + private final boolean valueSlider; + public GuiElementColour(int x, int y, String initialColour, Consumer<String> colourChangedCallback, Runnable closeCallback) { + this(x, y, initialColour, colourChangedCallback, closeCallback, true, true); + } + public GuiElementColour(int x, int y, String initialColour, Consumer<String> colourChangedCallback, + Runnable closeCallback, boolean opacitySlider, boolean valueSlider) { final ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft()); this.y = Math.max(10, Math.min(scaledResolution.getScaledHeight()-ySize-10, y)); @@ -60,6 +67,12 @@ public class GuiElementColour extends GuiElement { Color c = new Color(colour); float[] hsv = Color.RGBtoHSB(c.getRed(), c.getGreen(), c.getBlue(), null); updateAngleAndRadius(hsv); + + this.opacitySlider = opacitySlider; + this.valueSlider = valueSlider; + + if(!valueSlider) xSize -= 15; + if(!opacitySlider) xSize -= 15; } public void updateAngleAndRadius(float[] hsv) { @@ -127,19 +140,29 @@ public class GuiElementColour extends GuiElement { int selx = (int)(Math.cos(Math.toRadians(wheelAngle))*selradius); int sely = (int)(Math.sin(Math.toRadians(wheelAngle))*selradius); - Minecraft.getMinecraft().getTextureManager().bindTexture(colour_selector_bar_alpha); - GlStateManager.color(1, 1, 1, 1); - RenderUtils.drawTexturedRect(x+5+64+5+10+5, y+5, 10, 64, GL11.GL_NEAREST); + int valueOffset = 0; + if(valueSlider) { + valueOffset = 15; - Minecraft.getMinecraft().getTextureManager().loadTexture(colourPickerBarValueLocation, new DynamicTexture(bufferedImageValue)); - Minecraft.getMinecraft().getTextureManager().bindTexture(colourPickerBarValueLocation); - GlStateManager.color(1, 1, 1, 1); - RenderUtils.drawTexturedRect(x+5+64+5, y+5, 10, 64, GL11.GL_NEAREST); + Minecraft.getMinecraft().getTextureManager().loadTexture(colourPickerBarValueLocation, new DynamicTexture(bufferedImageValue)); + Minecraft.getMinecraft().getTextureManager().bindTexture(colourPickerBarValueLocation); + GlStateManager.color(1, 1, 1, 1); + RenderUtils.drawTexturedRect(x+5+64+5, y+5, 10, 64, GL11.GL_NEAREST); + } - Minecraft.getMinecraft().getTextureManager().loadTexture(colourPickerBarOpacityLocation, new DynamicTexture(bufferedImageOpacity)); - Minecraft.getMinecraft().getTextureManager().bindTexture(colourPickerBarOpacityLocation); - GlStateManager.color(1, 1, 1, 1); - RenderUtils.drawTexturedRect(x+5+64+5+10+5, y+5, 10, 64, GL11.GL_NEAREST); + int opacityOffset = 0; + if(opacitySlider) { + opacityOffset = 15; + + Minecraft.getMinecraft().getTextureManager().bindTexture(colour_selector_bar_alpha); + GlStateManager.color(1, 1, 1, 1); + RenderUtils.drawTexturedRect(x+5+64+5+valueOffset, y+5, 10, 64, GL11.GL_NEAREST); + + Minecraft.getMinecraft().getTextureManager().loadTexture(colourPickerBarOpacityLocation, new DynamicTexture(bufferedImageOpacity)); + Minecraft.getMinecraft().getTextureManager().bindTexture(colourPickerBarOpacityLocation); + GlStateManager.color(1, 1, 1, 1); + RenderUtils.drawTexturedRect(x+5+64+5+valueOffset, y+5, 10, 64, GL11.GL_NEAREST); + } int chromaSpeed = ChromaColour.getSpeed(colour); int currentColourChroma = ChromaColour.specialToChromaRGB(colour); @@ -147,35 +170,35 @@ public class GuiElementColour extends GuiElement { float hsvChroma[] = Color.RGBtoHSB(cChroma.getRed(), cChroma.getGreen(), cChroma.getBlue(), null); if(chromaSpeed > 0) { - Gui.drawRect(x+5+64+5+10+5+10+5+1, y+5+1, - x+5+64+5+10+5+10+5+10-1, y+5+64-1, + Gui.drawRect(x+5+64+valueOffset+opacityOffset+5+1, y+5+1, + x+5+64+valueOffset+opacityOffset+5+10-1, y+5+64-1, Color.HSBtoRGB(hsvChroma[0], 0.8f, 0.8f)); } else { - Gui.drawRect(x+5+64+5+10+5+10+5+1, y+5+27+1, - x+5+64+5+10+5+10+5+10-1, y+5+37-1, + Gui.drawRect(x+5+64+valueOffset+opacityOffset+5+1, y+5+27+1, + x+5+64+valueOffset+opacityOffset+5+10-1, y+5+37-1, Color.HSBtoRGB((hsvChroma[0]+(System.currentTimeMillis()-ChromaColour.startTime)/1000f)%1, 0.8f, 0.8f)); } Minecraft.getMinecraft().getTextureManager().bindTexture(colour_selector_bar); GlStateManager.color(1, 1, 1, 1); - RenderUtils.drawTexturedRect(x+5+64+5, y+5, 10, 64, GL11.GL_NEAREST); - RenderUtils.drawTexturedRect(x+5+64+5+10+5, y+5, 10, 64, GL11.GL_NEAREST); + if(valueSlider) RenderUtils.drawTexturedRect(x+5+64+5, y+5, 10, 64, GL11.GL_NEAREST); + if(opacitySlider) RenderUtils.drawTexturedRect(x+5+64+5+valueOffset, y+5, 10, 64, GL11.GL_NEAREST); if(chromaSpeed > 0) { - RenderUtils.drawTexturedRect(x+5+64+5+10+5+10+5, y+5, 10, 64, GL11.GL_NEAREST); + RenderUtils.drawTexturedRect(x+5+64+valueOffset+opacityOffset+5, y+5, 10, 64, GL11.GL_NEAREST); } else { Minecraft.getMinecraft().getTextureManager().bindTexture(colour_selector_chroma); - RenderUtils.drawTexturedRect(x+5+64+5+10+5+10+5, y+5+27, 10, 10, GL11.GL_NEAREST); + RenderUtils.drawTexturedRect(x+5+64+valueOffset+opacityOffset+5, y+5+27, 10, 10, GL11.GL_NEAREST); } - Gui.drawRect(x+5+64+5, y+5+64-(int)(64*hsv[2]), - x+5+64+5+10, y+5+64-(int)(64*hsv[2])+1, 0xFF000000); - Gui.drawRect(x+5+64+5+10+5, y+5+64-c.getAlpha()/4, - x+5+64+5+10+5+10, y+5+64-c.getAlpha()/4-1, 0xFF000000); + if(valueSlider) Gui.drawRect(x+5+64+5, y+5+64-(int)(64*hsv[2]), + x+5+64+valueOffset, y+5+64-(int)(64*hsv[2])+1, 0xFF000000); + if(opacitySlider) Gui.drawRect(x+5+64+5+valueOffset, y+5+64-c.getAlpha()/4, + x+5+64+valueOffset+opacityOffset, y+5+64-c.getAlpha()/4-1, 0xFF000000); if(chromaSpeed > 0) { - Gui.drawRect(x+5+64+5+10+5+10+5, + Gui.drawRect(x+5+64+valueOffset+opacityOffset+5, y+5+64-(int)(chromaSpeed/255f*64), - x+5+64+5+10+5+10+5+10, + x+5+64+valueOffset+opacityOffset+5+10, y+5+64-(int)(chromaSpeed/255f*64)+1, 0xFF000000); } @@ -191,14 +214,16 @@ public class GuiElementColour extends GuiElement { TextRenderUtils.drawStringCenteredScaledMaxWidth(EnumChatFormatting.GRAY.toString()+Math.round(hsv[2]*100)+"", Minecraft.getMinecraft().fontRendererObj, x+5+64+5+5-(Math.round(hsv[2]*100)==100?1:0), y+5+64+5+5, true, 13, -1); - TextRenderUtils.drawStringCenteredScaledMaxWidth(EnumChatFormatting.GRAY.toString()+Math.round(c.getAlpha()/255f*100)+"", - Minecraft.getMinecraft().fontRendererObj, - x+5+64+5+15+5, y+5+64+5+5, true, 13, -1); + if(opacitySlider) { + TextRenderUtils.drawStringCenteredScaledMaxWidth(EnumChatFormatting.GRAY.toString()+Math.round(c.getAlpha()/255f*100)+"", + Minecraft.getMinecraft().fontRendererObj, + x+5+64+5+15+5, y+5+64+5+5, true, 13, -1); + } if(chromaSpeed > 0) { TextRenderUtils.drawStringCenteredScaledMaxWidth(EnumChatFormatting.GRAY.toString()+ (int)ChromaColour.getSecondsForSpeed(chromaSpeed)+"s", Minecraft.getMinecraft().fontRendererObj, - x+5+64+5+30+6, y+5+64+5+5, true, 13, -1); + x+5+64+5+valueOffset+15+6, y+5+64+5+5, true, 13, -1); } hexField.setSize(48, 10); @@ -250,20 +275,27 @@ public class GuiElementColour extends GuiElement { int xValue = mouseX - (x+5+64+5); int y = mouseY - this.y - 5; + int opacityOffset = opacitySlider ? 15 : 0; + int valueOffset = valueSlider ? 15 : 0; + if(y > -5 && y <= 69) { - if(xValue > 0 && xValue < 10) { - clickedComponent = 1; + if(valueSlider) { + if(xValue > 0 && xValue < 10) { + clickedComponent = 1; + } } - int xOpacity = mouseX - (x+5+64+5+10+5); + if(opacitySlider) { + int xOpacity = mouseX - (x+5+64+5+valueOffset); - if(xOpacity > 0 && xOpacity < 10) { - clickedComponent = 2; + if(xOpacity > 0 && xOpacity < 10) { + clickedComponent = 2; + } } } int chromaSpeed = ChromaColour.getSpeed(colour); - int xChroma = mouseX - (x+5+64+5+10+5+10+5); + int xChroma = mouseX - (x+5+64+valueOffset+opacityOffset+5); if(xChroma > 0 && xChroma < 10) { if(chromaSpeed > 0) { if(y > -5 && y <= 69) { 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 111803e8..965c705d 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/GuiElementTextField.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/GuiElementTextField.java @@ -16,6 +16,7 @@ import java.util.regex.Pattern; public class GuiElementTextField { + public static final int DISABLE_BG = 0b1000000; public static final int SCALE_TEXT = 0b100000; public static final int NUM_ONLY = 0b10000; public static final int NO_SPACE = 0b01000; @@ -35,6 +36,7 @@ public class GuiElementTextField { private int y; private String prependText = ""; + private int customTextColour = 0xffffffff; private final GuiTextField textField = new GuiTextField(0, Minecraft.getMinecraft().fontRendererObj, 0 , 0, 0, 0); @@ -63,6 +65,10 @@ public class GuiElementTextField { this.customBorderColour = colour; } + public void setCustomTextColour(int colour) { + this.customTextColour = colour; + } + public String getText() { return textField.getText(); } @@ -142,7 +148,7 @@ public class GuiElementTextField { int lineNum = Math.round(((yComp - (searchBarYSize-8)/2))/extraSize); - Pattern patternControlCode = Pattern.compile("(?i)\\u00A7([^\\u00B6])(?!\\u00B6)"); + Pattern patternControlCode = Pattern.compile("(?i)\\u00A7([^\\u00B6]|$)(?!\\u00B6)"); String text = renderText; String textNoColour = renderText; if((options & COLOUR) != 0) { @@ -150,7 +156,11 @@ public class GuiElementTextField { Matcher matcher = patternControlCode.matcher(text); if(!matcher.find() || matcher.groupCount() < 1) break; String code = matcher.group(1); - text = matcher.replaceFirst("\u00A7"+code+"\u00B6"+code); + if(code.isEmpty()) { + text = matcher.replaceFirst("\u00A7r\u00B6"); + } else { + text = matcher.replaceFirst("\u00A7"+code+"\u00B6"+code); + } } } while(true) { @@ -169,7 +179,6 @@ public class GuiElementTextField { } } - String textNC = textNoColour.substring(0, cursorIndex); int colorCodes = org.apache.commons.lang3.StringUtils.countMatches(textNC, "\u00B6"); String line = text.substring(cursorIndex+(((options & COLOUR) != 0)?colorCodes*2:0)).split("\n")[0]; @@ -223,7 +232,7 @@ public class GuiElementTextField { public void keyTyped(char typedChar, int keyCode) { if(focus) { if((options & MULTILINE) != 0) { //Carriage return - Pattern patternControlCode = Pattern.compile("(?i)\\u00A7([^\\u00B6\n])(?!\\u00B6)"); + Pattern patternControlCode = Pattern.compile("(?i)\\u00A7([^\\u00B6\n]|$)(?!\\u00B6)"); String text = textField.getText(); String textNoColour = textField.getText(); @@ -231,7 +240,11 @@ public class GuiElementTextField { Matcher matcher = patternControlCode.matcher(text); if(!matcher.find() || matcher.groupCount() < 1) break; String code = matcher.group(1); - text = matcher.replaceFirst("\u00A7"+code+"\u00B6"+code); + if(code.isEmpty()) { + text = matcher.replaceFirst("\u00A7r\u00B6"); + } else { + text = matcher.replaceFirst("\u00A7"+code+"\u00B6"+code); + } } while(true) { Matcher matcher = patternControlCode.matcher(textNoColour); @@ -389,18 +402,20 @@ public class GuiElementTextField { if(customBorderColour != -1) { borderColour = customBorderColour; } - //bar background - Gui.drawRect(x - paddingUnscaled, - y - paddingUnscaled, - x + searchBarXSize + paddingUnscaled, - bottomTextBox + paddingUnscaled, borderColour); - Gui.drawRect(x, - y, - x + searchBarXSize, - bottomTextBox, Color.BLACK.getRGB()); + if((options & DISABLE_BG) == 0) { + //bar background + Gui.drawRect(x - paddingUnscaled, + y - paddingUnscaled, + x + searchBarXSize + paddingUnscaled, + bottomTextBox + paddingUnscaled, borderColour); + Gui.drawRect(x, + y, + x + searchBarXSize, + bottomTextBox, Color.BLACK.getRGB()); + } //bar text - Pattern patternControlCode = Pattern.compile("(?i)\\u00A7([^\\u00B6\n])(?!\\u00B6)"); + Pattern patternControlCode = Pattern.compile("(?i)\\u00A7([^\\u00B6\n]|$)(?!\\u00B6)"); String text = renderText; String textNoColor = renderText; @@ -409,7 +424,11 @@ public class GuiElementTextField { Matcher matcher = patternControlCode.matcher(text); if(!matcher.find() || matcher.groupCount() < 1) break; String code = matcher.group(1); - text = matcher.replaceFirst("\u00A7"+code+"\u00B6"+code); + if(code.isEmpty()) { + text = matcher.replaceFirst("\u00A7r\u00B6"); + } else { + text = matcher.replaceFirst("\u00A7"+code+"\u00B6"+code); + } } } while(true) { @@ -433,10 +452,10 @@ public class GuiElementTextField { TextRenderUtils.drawStringCenteredScaledMaxWidth(texts[yOffI], Minecraft.getMinecraft().fontRendererObj, x+searchBarXSize/2f, y+searchBarYSize/2f+yOff, false, - searchBarXSize-2, Color.WHITE.getRGB()); + searchBarXSize-2, customTextColour); } else { Minecraft.getMinecraft().fontRendererObj.drawString(StringUtils.trimToWidth(texts[yOffI], searchBarXSize-10), x + 5, - y+(searchBarYSize-8)/2+yOff, Color.WHITE.getRGB()); + y+(searchBarYSize-8)/2+yOff, customTextColour); } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/KeybindHelper.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/KeybindHelper.java new file mode 100644 index 00000000..306bc95e --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/KeybindHelper.java @@ -0,0 +1,49 @@ +package io.github.moulberry.notenoughupdates.core.config; + +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import org.lwjgl.input.Keyboard; +import org.lwjgl.input.Mouse; + +public class KeybindHelper { + + public static String getKeyName(int keyCode) { + if(keyCode == 0) { + return "NONE"; + } else if(keyCode < 0) { + return "Button "+(keyCode+101); + } else { + String keyName = Keyboard.getKeyName(keyCode); + if(keyName.equalsIgnoreCase("LMENU")) { + keyName = "LALT"; + } else if(keyName.equalsIgnoreCase("RMENU")) { + keyName = "RALT"; + } + return keyName; + } + } + + public static boolean isKeyValid(int keyCode) { + return keyCode != 0; + } + + public static boolean isKeyDown(int keyCode) { + if(!isKeyValid(keyCode)) { + return false; + } else if(keyCode < 0) { + return Mouse.isButtonDown(keyCode+100); + } else { + return Keyboard.isKeyDown(keyCode); + } + } + + public static boolean isKeyPressed(int keyCode) { + if(!isKeyValid(keyCode)) { + return false; + } else if(keyCode < 0) { + return Mouse.getEventButtonState() && Mouse.getEventButton() == keyCode+100; + } else { + return Keyboard.getEventKeyState() && Keyboard.getEventKey() == keyCode; + } + } + +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorKeybind.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorKeybind.java new file mode 100644 index 00000000..527171f2 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorKeybind.java @@ -0,0 +1,14 @@ +package io.github.moulberry.notenoughupdates.core.config.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface ConfigEditorKeybind { + + int defaultKey(); + +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorKeybind.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorKeybind.java new file mode 100644 index 00000000..0c0514fe --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorKeybind.java @@ -0,0 +1,94 @@ +package io.github.moulberry.notenoughupdates.core.config.gui; + +import io.github.moulberry.notenoughupdates.core.config.Config; +import io.github.moulberry.notenoughupdates.core.config.KeybindHelper; +import io.github.moulberry.notenoughupdates.core.config.struct.ConfigProcessor; +import io.github.moulberry.notenoughupdates.core.util.render.RenderUtils; +import io.github.moulberry.notenoughupdates.core.util.render.TextRenderUtils; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.util.ResourceLocation; +import org.lwjgl.input.Keyboard; +import org.lwjgl.input.Mouse; +import org.lwjgl.opengl.GL11; + +import static io.github.moulberry.notenoughupdates.util.GuiTextures.button_tex; + +public class GuiOptionEditorKeybind extends GuiOptionEditor { + + private static final ResourceLocation RESET = new ResourceLocation("notenoughupdates:itemcustomize/reset.png"); + + private int keyCode; + private int defaultKeyCode; + private boolean editingKeycode; + + public GuiOptionEditorKeybind(ConfigProcessor.ProcessedOption option, int keyCode, int defaultKeyCode) { + super(option); + this.keyCode = keyCode; + this.defaultKeyCode = defaultKeyCode; + } + + @Override + public void render(int x, int y, int width) { + super.render(x, y, width); + + int height = getHeight(); + + GlStateManager.color(1, 1, 1, 1); + Minecraft.getMinecraft().getTextureManager().bindTexture(button_tex); + RenderUtils.drawTexturedRect(x+width/6-24, y+height-7-14, 48, 16); + + String keyName = KeybindHelper.getKeyName(keyCode); + String text = editingKeycode ? "> "+keyName+" <" : keyName; + TextRenderUtils.drawStringCenteredScaledMaxWidth(text, + Minecraft.getMinecraft().fontRendererObj, + x+width/6, y+height-7-6, + false, 40, 0xFF303030); + + Minecraft.getMinecraft().getTextureManager().bindTexture(RESET); + GlStateManager.color(1, 1, 1, 1); + RenderUtils.drawTexturedRect(x+width/6-24+48+3, y+height-7-14+3, 10, 11, GL11.GL_NEAREST); + } + + @Override + public boolean mouseInput(int x, int y, int width, int mouseX, int mouseY) { + if(Mouse.getEventButtonState() && Mouse.getEventButton() != -1 && editingKeycode) { + editingKeycode = false; + keyCode = Mouse.getEventButton()-100; + option.set(keyCode); + return true; + } + + if(Mouse.getEventButtonState() && Mouse.getEventButton() == 0) { + int height = getHeight(); + if(mouseX > x+width/6-24 && mouseX < x+width/6+24 && + mouseY > y+height-7-14 && mouseY < y+height-7+2) { + editingKeycode = true; + return true; + } + if(mouseX > x+width/6-24+48+3 && mouseX < x+width/6-24+48+13 && + mouseY > y+height-7-14+3 && mouseY < y+height-7-14+3+11) { + keyCode = defaultKeyCode; + option.set(keyCode); + return true; + } + } + + return false; + } + + @Override + public boolean keyboardInput() { + if(editingKeycode) { + editingKeycode = false; + if(Keyboard.getEventKey() == Keyboard.KEY_ESCAPE) { + keyCode = 0; + } else { + keyCode = Keyboard.getEventKey() == 0 ? Keyboard.getEventCharacter() + 256 : Keyboard.getEventKey(); + } + option.set(keyCode); + return true; + } + return false; + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/struct/ConfigProcessor.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/struct/ConfigProcessor.java index 794d4837..4ce10162 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/config/struct/ConfigProcessor.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/struct/ConfigProcessor.java @@ -107,6 +107,11 @@ public class ConfigProcessor { GuiOptionEditor editor = null; Class<?> optionType = optionField.getType(); + if(optionType.isAssignableFrom(int.class) && + optionField.isAnnotationPresent(ConfigEditorKeybind.class)) { + ConfigEditorKeybind configEditorAnnotation = optionField.getAnnotation(ConfigEditorKeybind.class); + editor = new GuiOptionEditorKeybind(option, (int)option.get(), configEditorAnnotation.defaultKey()); + } if(optionField.isAnnotationPresent(ConfigEditorButton.class)) { ConfigEditorButton configEditorAnnotation = optionField.getAnnotation(ConfigEditorButton.class); editor = new GuiOptionEditorButton(option, configEditorAnnotation.runnableId(), configEditorAnnotation.buttonText(), config); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/CapeManager.java b/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/CapeManager.java index 21f6baaf..a8cd30d8 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/CapeManager.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/CapeManager.java @@ -49,10 +49,10 @@ public class CapeManager { private String[] capes = new String[]{"patreon1", "patreon2", "fade", "contrib", "nullzee", "gravy", "space", "mcworld", "lava", "packshq", "mbstaff", "thebakery", "negative", - "void", "ironmoon", "krusty", "furf", "soldier", "dsm", "zera", "tunnel", "alexxoffi", "parallax", "jakethybro", "planets" }; + "void", "ironmoon", "krusty", "furf", "soldier", "dsm", "zera", "tunnel", "alexxoffi", "parallax", "jakethybro", "planets", "skytils" }; public Boolean[] specialCapes = new Boolean[]{ true, true, false, true, true, true, false, false, false, true, true, true, false, - false, true, false, true, true, true, true, false, true, true, true, false }; + false, true, false, true, true, true, true, false, true, true, true, true, true }; public static CapeManager getInstance() { return INSTANCE; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonMap.java b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonMap.java index 8a591398..01b27f3d 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonMap.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonMap.java @@ -1042,7 +1042,7 @@ public class DungeonMap { String line = ScorePlayerTeam.formatPlayerName(scoreplayerteam1, score.getPlayerName()); line = Utils.cleanColour(line); - if(line.contains("(F1)") || line.contains("(E)")) { + if(line.contains("(F1)") || line.contains("(E)") || line.contains("(M1)")) { isFloorOne = true; break; } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/BetterContainers.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/BetterContainers.java index b2ab13e6..5af6e8bb 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/BetterContainers.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/BetterContainers.java @@ -1,6 +1,7 @@ package io.github.moulberry.notenoughupdates.miscfeatures; import com.google.gson.JsonObject; +import io.github.moulberry.notenoughupdates.NEUEventListener; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.util.TexLoc; import io.github.moulberry.notenoughupdates.util.Utils; @@ -67,40 +68,26 @@ public class BetterContainers { } public static void bindHook(TextureManager textureManager, ResourceLocation location) { - if(isChestOpen()) { - Container container = ((GuiChest)Minecraft.getMinecraft().currentScreen).inventorySlots; - if(container instanceof ContainerChest) { - usingCached = true; - IInventory lower = ((ContainerChest)container).getLowerChestInventory(); - int size = lower.getSizeInventory(); - for(int index=0; index<size; index++) { - if(lower.getStackInSlot(index) != null) { - for(int index2=0; index2<size; index2++) { - itemCache.put(index2, lower.getStackInSlot(index2)); - } - usingCached = false; - break; - } - } - } - - if((texture != null && loaded && lastClickedSlot != getClickedSlot()) || - lastUsingCached != getUsingCache() || - (texture == null && !loaded)) { + if(isChestOpen() && NEUEventListener.inventoryLoaded) { + if((texture != null && lastClickedSlot != getClickedSlot()) || + lastUsingCached != getUsingCache() || !loaded) { lastUsingCached = getUsingCache(); lastClickedSlot = getClickedSlot(); generateTex(location); } if(texture != null && loaded) { - if(!usingCached) lastRenderMillis = System.currentTimeMillis(); lastRenderMillis = System.currentTimeMillis(); GlStateManager.color(1, 1, 1, 1); - textureManager.loadTexture(rl, texture); textureManager.bindTexture(rl); return; } + } else if(System.currentTimeMillis() - lastRenderMillis < 200 && texture != null) { + GlStateManager.color(1, 1, 1, 1); + textureManager.loadTexture(rl, texture); + textureManager.bindTexture(rl); + return; } GlStateManager.enableBlend(); textureManager.bindTexture(location); @@ -120,7 +107,7 @@ public class BetterContainers { } public static boolean isOverriding() { - return isChestOpen() && ((loaded && texture != null)) && !isBlacklistedInventory(); + return isChestOpen() && ((loaded && texture != null) || System.currentTimeMillis() - lastRenderMillis < 200) && !isBlacklistedInventory(); } public static boolean isBlankStack(ItemStack stack) { @@ -166,7 +153,7 @@ public class BetterContainers { private static void generateTex(ResourceLocation location) { if(!hasItem()) return; - texture = null; + loaded = true; Container container = ((GuiChest)Minecraft.getMinecraft().currentScreen).inventorySlots; @@ -300,19 +287,25 @@ public class BetterContainers { } } } - texture = new DynamicTexture(bufferedImageNew); + if(texture != null) { + bufferedImageNew.getRGB(0, 0, bufferedImageNew.getWidth(), bufferedImageNew.getHeight(), + texture.getTextureData(), 0, bufferedImageNew.getWidth()); + texture.updateDynamicTexture(); + } else { + texture = new DynamicTexture(bufferedImageNew); + } + return; } catch(Exception e) { e.printStackTrace(); } } + texture = null; } public static void reset() { - texture = null; loaded = false; clickedSlot = -1; clickedSlotMillis = 0; - textColour = 4210752; } private static boolean isChestOpen() { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalOverlay.java index b96fefef..e953ba60 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalOverlay.java @@ -129,6 +129,7 @@ public class CrystalOverlay { private static ExecutorService es = Executors.newSingleThreadExecutor(); public static void tick() { + if(!NotEnoughUpdates.INSTANCE.config.itemOverlays.enableCrystalOverlay) return; if(Minecraft.getMinecraft().theWorld == null) return; EntityPlayerSP p = Minecraft.getMinecraft().thePlayer; @@ -136,23 +137,28 @@ public class CrystalOverlay { long currentTime = System.currentTimeMillis(); - if(currentTime - displayMillis > 10*1000) { - crystals.clear(); - displayMillis = -1; - } + if(NotEnoughUpdates.INSTANCE.config.itemOverlays.alwaysShowCrystal) { + displayMillis = currentTime; + } else { + if(currentTime - displayMillis > 10*1000) { + crystals.clear(); + displayMillis = -1; + } - ItemStack held = p.getHeldItem(); - String internal = NotEnoughUpdates.INSTANCE.manager.getInternalNameForItem(held); - if(internal != null) { - if(internal.endsWith("_CRYSTAL") && !internal.equals("POWER_CRYSTAL")) { - displayMillis = System.currentTimeMillis(); + ItemStack held = p.getHeldItem(); + String internal = NotEnoughUpdates.INSTANCE.manager.getInternalNameForItem(held); + if(internal != null) { + if(internal.endsWith("_CRYSTAL") && !internal.equals("POWER_CRYSTAL")) { + displayMillis = currentTime; + } } - } - if(displayMillis < 0) { - return; + if(displayMillis < 0) { + return; + } } + Set<CrystalType> foundTypes = new HashSet<>(); for(Entity entity : Minecraft.getMinecraft().theWorld.loadedEntityList) { if(entity instanceof EntityArmorStand) { @@ -198,6 +204,8 @@ public class CrystalOverlay { @SubscribeEvent public void onTick(TickEvent.ClientTickEvent event) { + if(!NotEnoughUpdates.INSTANCE.config.itemOverlays.enableCrystalOverlay) return; + if(displayMillis < 0) { return; } @@ -248,6 +256,8 @@ public class CrystalOverlay { @SubscribeEvent public void onRenderLast(RenderWorldLastEvent event) { + if(!NotEnoughUpdates.INSTANCE.config.itemOverlays.enableCrystalOverlay) return; + if(displayMillis < 0) { return; } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CustomItemEffects.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CustomItemEffects.java index 20915503..e49644bf 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CustomItemEffects.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CustomItemEffects.java @@ -209,7 +209,7 @@ public class CustomItemEffects { if(NotEnoughUpdates.INSTANCE.config.itemOverlays.highlightTargeted) { List<Entity> entities = Minecraft.getMinecraft().theWorld.getEntitiesWithinAABBExcludingEntity(Minecraft.getMinecraft().thePlayer, bb); for(Entity entity : entities) { - if(entity instanceof EntityLivingBase && !(entity instanceof EntityArmorStand)) { + if(entity instanceof EntityLivingBase && !(entity instanceof EntityArmorStand) && !entity.isInvisible()) { if(!bonemeragedEntities.contains(entity)) { bonemeragedEntities.add((EntityLivingBase)entity); } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DwarvenMinesTextures.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DwarvenMinesTextures.java index caa1441c..65b47ec0 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DwarvenMinesTextures.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DwarvenMinesTextures.java @@ -50,6 +50,7 @@ public class DwarvenMinesTextures { private static boolean error = false; public static int retexture(BlockPos pos) { + if(!NotEnoughUpdates.INSTANCE.config.mining.dwarvenTextures) return 0; if(error) return 0; if(Minecraft.getMinecraft().theWorld == null) return 0; @@ -220,6 +221,8 @@ public class DwarvenMinesTextures { //Don't render clay - mesaPlateau_F public static void tick() { + if(!NotEnoughUpdates.INSTANCE.config.mining.dwarvenTextures) return; + time = System.currentTimeMillis(); Set<ChunkCoordIntPair> remove = new HashSet<>(); for(Map.Entry<ChunkCoordIntPair, Long> entry : lastRetextureCheck.entrySet()) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/EnchantingSolvers.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/EnchantingSolvers.java index 26e87ae9..01d81460 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/EnchantingSolvers.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/EnchantingSolvers.java @@ -311,12 +311,19 @@ public class EnchantingSolvers { if(chronomatronReplayIndex < chronomatronOrder.size()) { String chronomatronCurrent = chronomatronOrder.get(chronomatronReplayIndex); - if(true) { + /*if(!NotEnoughUpdates.INSTANCE.config.enchantingSolvers.preventMisclicks || + chronomatronCurrent.equals(displayName)) { chronomatronReplayIndex++; Minecraft.getMinecraft().playerController.windowClick(windowId, slotId, 2, mode, Minecraft.getMinecraft().thePlayer); millisLastClick = currentTime; + }*/ + if(chronomatronCurrent.equals(displayName)) { + chronomatronReplayIndex++; } + Minecraft.getMinecraft().playerController.windowClick(windowId, slotId, + 2, mode, Minecraft.getMinecraft().thePlayer); + millisLastClick = currentTime; } return true; } @@ -333,11 +340,21 @@ public class EnchantingSolvers { return true; } long currentTime = System.currentTimeMillis(); - if(currentTime - millisLastClick > 150) { + /*if(currentTime - millisLastClick > 150 && + (!NotEnoughUpdates.INSTANCE.config.enchantingSolvers.preventMisclicks || + current.containerIndex == slotId)) { ultrasequencerReplayIndex++; Minecraft.getMinecraft().playerController.windowClick(windowId, slotId, 2, mode, Minecraft.getMinecraft().thePlayer); millisLastClick = currentTime; + }*/ + if(currentTime - millisLastClick > 150) { + if(current.containerIndex == slotId) { + ultrasequencerReplayIndex++; + } + Minecraft.getMinecraft().playerController.windowClick(windowId, slotId, + 2, mode, Minecraft.getMinecraft().thePlayer); + millisLastClick = currentTime; } return true; } else { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/ItemCooldowns.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/ItemCooldowns.java index 4a572110..c36f619e 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/ItemCooldowns.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/ItemCooldowns.java @@ -12,20 +12,30 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.gameevent.TickEvent; import java.util.*; +import java.util.regex.Matcher; import java.util.regex.Pattern; public class ItemCooldowns { private static Map<ItemStack, Float> durabilityOverrideMap = new HashMap<>(); - private static long pickaxeUseCooldownMillisRemaining = -1; + public static long pickaxeUseCooldownMillisRemaining = -1; private static long treecapitatorCooldownMillisRemaining = -1; private static long lastMillis = 0; + public static long pickaxeCooldown = -1; + public static TreeMap<Long, BlockPos> blocksClicked = new TreeMap<>(); + private static int tickCounter = 0; + @SubscribeEvent public void tick(TickEvent.ClientTickEvent event) { - if(event.phase == TickEvent.Phase.END) { + if(event.phase == TickEvent.Phase.END && NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) { + if(tickCounter++ >= 20*10) { + tickCounter = 0; + pickaxeCooldown = -1; + } + long currentTime = System.currentTimeMillis(); Long key; @@ -48,8 +58,10 @@ public class ItemCooldowns { } @SubscribeEvent - public void onWorldUnload(WorldEvent.Unload event) { + public void onWorldUnload(WorldEvent.Load event) { blocksClicked.clear(); + pickaxeCooldown = -1; + pickaxeUseCooldownMillisRemaining = 60*1000; } public static long getTreecapCooldownWithPet(){ @@ -95,15 +107,42 @@ public class ItemCooldowns { private static Pattern PICKAXE_ABILITY_REGEX = Pattern.compile("\\u00a7r\\u00a7aYou used your " + "\\u00a7r\\u00a7..+ \\u00a7r\\u00a7aPickaxe Ability!\\u00a7r"); + private static Pattern PICKAXE_COOLDOWN_LORE_REGEX = Pattern.compile("\\u00a78Cooldown: \\u00a7a(\\d+)s"); + + private static void updatePickaxeCooldown() { + if(pickaxeCooldown == -1) { + for(ItemStack stack : Minecraft.getMinecraft().thePlayer.inventory.mainInventory) { + if(stack != null && stack.hasTagCompound()) { + String internalname = NotEnoughUpdates.INSTANCE.manager.getInternalNameForItem(stack); + if(internalname != null && (internalname.endsWith("_PICKAXE") || internalname.contains("_DRILL_"))) { + for(String line : NotEnoughUpdates.INSTANCE.manager.getLoreFromNBT(stack.getTagCompound())) { + Matcher matcher = PICKAXE_COOLDOWN_LORE_REGEX.matcher(line); + if(matcher.find()) { + try { + pickaxeCooldown = Integer.parseInt(matcher.group(1)); + return; + } catch(Exception ignored) {} + } + } + } + } + } + pickaxeCooldown = 120; + } + } + + @SubscribeEvent public void onChatMessage(ClientChatReceivedEvent event) { if(PICKAXE_ABILITY_REGEX.matcher(event.message.getFormattedText()).matches()) { - pickaxeUseCooldownMillisRemaining = 120*1000; + updatePickaxeCooldown(); + pickaxeUseCooldownMillisRemaining = pickaxeCooldown*1000; } } public static float getDurabilityOverride(ItemStack stack) { if(Minecraft.getMinecraft().theWorld == null) return -1; + if(!NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) return -1; if(durabilityOverrideMap.containsKey(stack)) { return durabilityOverrideMap.get(stack); @@ -116,15 +155,17 @@ public class ItemCooldowns { } if(internalname.endsWith("_PICKAXE") || internalname.contains("_DRILL_")) { + updatePickaxeCooldown(); + if(pickaxeUseCooldownMillisRemaining < 0) { durabilityOverrideMap.put(stack, -1f); return -1; } - if(pickaxeUseCooldownMillisRemaining > 120*1000) { + if(pickaxeUseCooldownMillisRemaining > pickaxeCooldown*1000) { return stack.getItemDamage(); } - float dura = (float)(pickaxeUseCooldownMillisRemaining/(120.0*1000.0)); + float dura = (float)(pickaxeUseCooldownMillisRemaining/(pickaxeCooldown*1000.0)); durabilityOverrideMap.put(stack, dura); return dura; } else if(internalname.equals("TREECAPITATOR_AXE") || internalname.equals("JUNGLE_AXE")) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/ItemCustomizeManager.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/ItemCustomizeManager.java new file mode 100644 index 00000000..b07408a8 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/ItemCustomizeManager.java @@ -0,0 +1,278 @@ +package io.github.moulberry.notenoughupdates.miscfeatures; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.core.ChromaColour; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.texture.DynamicTexture; +import net.minecraft.client.renderer.texture.TextureMap; +import net.minecraft.client.resources.IResourceManager; +import net.minecraft.client.resources.IResourceManagerReloadListener; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL14; + +import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.*; +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.function.Consumer; + +public class ItemCustomizeManager { + + public static class ReloadListener implements IResourceManagerReloadListener { + @Override + public void onResourceManagerReload(IResourceManager resourceManager) { + ItemCustomizeManager.loadedCustomGlintTexture = false; + } + } + + public static boolean disableTextureBinding = false; + + private static ResourceLocation CUSTOM_GLINT_TEXTURE = new ResourceLocation("notenoughupdates:dynamic/custom_glint_texture"); + private static boolean loadedCustomGlintTexture = false; + + public static final String DEFAULT_GLINT_COLOR = ChromaColour.special(0, 0xcc, 0x6419FF); //A050FF 0x8040cc 100,25,255 64,19 + + private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); + private static ItemDataMap itemDataMap = new ItemDataMap(); + private static HashMap<Integer, String> itemUuidCache = new HashMap<>(); + + public static class ItemDataMap { + public HashMap<String, ItemData> itemData = new HashMap<>(); + } + + public static class ItemData { + public String customName = null; + public boolean overrideEnchantGlint = false; + public boolean enchantGlintValue; + + public String customGlintColour = DEFAULT_GLINT_COLOR; + + public String customLeatherColour = null; + } + + public static void putItemData(String uuid, ItemData data) { + itemDataMap.itemData.put(uuid, data); + } + + public static void setCustomBlendFunc(String colour) { + + /*int argb = ChromaColour.specialToChromaRGB(colour); + float[] hsv = Color.RGBtoHSB((argb >> 16) & 0xff, (argb >> 8) & 0xff, argb & 0xff, null); + GL14.glBlendColor(1, 1, 1, hsv[2]);*/ + + GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_CONSTANT_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA); + //GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE, GL11.GL_ONE); + } + + private static void renderEffect(Consumer<Integer> renderModelCallback, int color) { + GL11.glPushMatrix(); + + GlStateManager.enableBlend(); + GlStateManager.depthMask(false); + GlStateManager.depthFunc(GL11.GL_EQUAL); + GlStateManager.disableLighting(); + Minecraft.getMinecraft().getTextureManager().bindTexture(getCustomGlintTexture()); + GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR); + GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR); + + GlStateManager.matrixMode(5890); + GlStateManager.pushMatrix(); + GlStateManager.scale(8.0F, 8.0F, 8.0F); + float f = (float)(Minecraft.getSystemTime() % 3000L) / 3000.0F / 8.0F; + GlStateManager.translate(f, 0.0F, 0.0F); + GlStateManager.rotate(-50.0F, 0.0F, 0.0F, 1.0F); + renderModelCallback.accept(color); + GlStateManager.matrixMode(5890); + GlStateManager.popMatrix(); + + GlStateManager.pushMatrix(); + GlStateManager.scale(8.0F, 8.0F, 8.0F); + float f1 = (float)(Minecraft.getSystemTime() % 4873L) / 4873.0F / 8.0F; + GlStateManager.translate(-f1, 0.0F, 0.0F); + GlStateManager.rotate(10.0F, 0.0F, 0.0F, 1.0F); + renderModelCallback.accept(color); + GlStateManager.matrixMode(5890); + GlStateManager.popMatrix(); + + GlStateManager.matrixMode(5888); + GlStateManager.blendFunc(770, 771); + GlStateManager.enableLighting(); + GlStateManager.depthFunc(515); + GlStateManager.depthMask(true); + Minecraft.getMinecraft().getTextureManager().bindTexture(TextureMap.locationBlocksTexture); + + GL11.glPopMatrix(); + } + + private static void renderArmorGlint(Runnable renderModelCallback, float existed, int color) { + Minecraft.getMinecraft().getTextureManager().bindTexture(getCustomGlintTexture()); + GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR); + GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR); + GlStateManager.enableBlend(); + GlStateManager.depthFunc(514); + GlStateManager.depthMask(false); + float f1 = 0.5F; + GlStateManager.color(f1, f1, f1, 1.0F); + + for (int i = 0; i < 2; ++i) + { + GlStateManager.disableLighting(); + + float red = ((color >> 16) & 0xFF) / 255f; + float green = ((color >> 8) & 0xFF) / 255f; + float blue = (color & 0xFF) / 255f; + float alpha = ((color >> 24) & 0xFF) / 255f; + + GlStateManager.color(red, green, blue, alpha); + GlStateManager.matrixMode(5890); + GlStateManager.loadIdentity(); + float f3 = 0.33333334F; + GlStateManager.scale(f3, f3, f3); + GlStateManager.rotate(30.0F - (float)i * 60.0F, 0.0F, 0.0F, 1.0F); + GlStateManager.translate(0.0F, existed * (0.001F + (float)i * 0.003F) * 20.0F, 0.0F); + GlStateManager.matrixMode(5888); + renderModelCallback.run(); + } + + GlStateManager.matrixMode(5890); + GlStateManager.loadIdentity(); + GlStateManager.matrixMode(5888); + GlStateManager.enableLighting(); + GlStateManager.depthMask(true); + GlStateManager.depthFunc(515); + GlStateManager.disableBlend(); + } + + public static void pre() { + GlStateManager.matrixMode(GL11.GL_MODELVIEW); + } + + public static boolean render3DGlint(String customEnchantGlint, float existed, Runnable renderModelCallback) { + if(customEnchantGlint != null) { + int colour = ChromaColour.specialToChromaRGB(customEnchantGlint); + + float[] hsv = Color.RGBtoHSB((colour >> 16) & 0xff, (colour >> 8) & 0xff, colour & 0xff, null); + GL14.glBlendColor(1, 1, 1, hsv[2]); + + GlStateManager.tryBlendFuncSeparate(GL11.GL_ZERO, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ZERO, GL11.GL_ONE_MINUS_SRC_ALPHA); + int alphaValue = (int)((1-hsv[2]*hsv[2])*0xff) * ((colour >> 24) & 0xff) / 0xff; + renderArmorGlint(renderModelCallback, existed, alphaValue << 24); + GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE, GL11.GL_ONE); + renderArmorGlint(renderModelCallback, existed, colour); + + return true; + } + return false; + } + + public static boolean renderEffectHook(String customEnchantGlint, Consumer<Integer> renderModelCallback) { + if(customEnchantGlint != null) { + int colour = ChromaColour.specialToChromaRGB(customEnchantGlint); + + float[] hsv = Color.RGBtoHSB((colour >> 16) & 0xff, (colour >> 8) & 0xff, colour & 0xff, null); + GL14.glBlendColor(1, 1, 1, hsv[2]); + + GL11.glPushMatrix(); + + GlStateManager.tryBlendFuncSeparate(GL11.GL_ZERO, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ZERO, GL11.GL_ONE_MINUS_SRC_ALPHA); + int alphaValue = (int)((1-hsv[2]*hsv[2])*0xff) * ((colour >> 24) & 0xff) / 0xff; + renderEffect(renderModelCallback, alphaValue << 24); + GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE, GL11.GL_ONE); + renderEffect(renderModelCallback, colour); + + GL11.glPopMatrix(); + + return true; + } + return false; + } + + public static ResourceLocation getCustomGlintTexture() { + if(!loadedCustomGlintTexture) { + loadedCustomGlintTexture = true; + + final ResourceLocation RES_ITEM_GLINT = new ResourceLocation("textures/misc/enchanted_item_glint.png"); + + try { + BufferedImage originalGlint = ImageIO.read(Minecraft.getMinecraft().getResourceManager().getResource(RES_ITEM_GLINT).getInputStream()); + BufferedImage newGlint = new BufferedImage(originalGlint.getWidth(), originalGlint.getHeight(), BufferedImage.TYPE_INT_ARGB); + + for(int x=0; x<originalGlint.getWidth(); x++) { + for(int y=0; y<originalGlint.getHeight(); y++) { + int argb = originalGlint.getRGB(x, y); + + int avgRGB = ((((argb >> 16) & 0xff) + ((argb >> 8) & 0xff) + (argb & 0xff))/3) & 0xff; + + int newArgb = (avgRGB << 24) | (avgRGB << 16) | (avgRGB << 8) | avgRGB; + + newGlint.setRGB(x, y, newArgb); + } + } + + Minecraft.getMinecraft().getTextureManager().loadTexture(CUSTOM_GLINT_TEXTURE, new DynamicTexture(newGlint)); + } catch(Exception e) { + e.printStackTrace(); + CUSTOM_GLINT_TEXTURE = RES_ITEM_GLINT; + } + } + return CUSTOM_GLINT_TEXTURE; + } + + private static String getUuidForItem(ItemStack stack) { + if(!stack.hasTagCompound()) return null; + + int nbtHash = stack.getTagCompound().hashCode(); + + if(itemUuidCache.containsKey(nbtHash)) { + return itemUuidCache.get(nbtHash); + } + + String uuid = NotEnoughUpdates.INSTANCE.manager.getUUIDForItem(stack); + + itemUuidCache.put(nbtHash, uuid); + return uuid; + } + + public static ItemData getDataForItem(ItemStack stack) { + if(stack == null) return null; + + String uuid = getUuidForItem(stack); + + if(uuid == null) { + return null; + } else { + return itemDataMap.itemData.get(uuid); + } + } + + public static void tick() { + itemUuidCache.clear(); + disableTextureBinding = false; + } + + public static void loadCustomization(File file) { + try(BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8))) { + itemDataMap = GSON.fromJson(reader, ItemDataMap.class); + } catch(Exception ignored) {} + if(itemDataMap == null) { + itemDataMap = new ItemDataMap(); + } + } + + public static void saveCustomization(File file) { + try { + file.createNewFile(); + try(BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8))) { + writer.write(GSON.toJson(itemDataMap)); + } + } catch(Exception ignored) {} + } + +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/NPCRetexturing.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/NPCRetexturing.java new file mode 100644 index 00000000..465d3ea9 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/NPCRetexturing.java @@ -0,0 +1,99 @@ +package io.github.moulberry.notenoughupdates.miscfeatures; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.AbstractClientPlayer; +import net.minecraft.client.renderer.block.model.ModelBlock; +import net.minecraft.client.resources.IResourceManager; +import net.minecraft.client.resources.IResourceManagerReloadListener; +import net.minecraft.client.resources.model.ModelRotation; +import net.minecraft.util.ResourceLocation; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Map; + +public class NPCRetexturing implements IResourceManagerReloadListener { + + private static final NPCRetexturing INSTANCE = new NPCRetexturing(); + + private static final ResourceLocation npcRetexturingJson = new ResourceLocation("notenoughupdates:npccustomtextures/config.json"); + + private final Gson gson = new GsonBuilder().create(); + + public static class Skin { + public ResourceLocation skinLocation; + public boolean skinny; + + public Skin(ResourceLocation skinLocation, boolean skinny) { + this.skinLocation = skinLocation; + this.skinny = skinny; + } + } + + private HashMap<AbstractClientPlayer, Skin> skinOverrideCache = new HashMap<>(); + private HashMap<String, Skin> skinMap = new HashMap<>(); + + private boolean gettingSkin = false; + + public Skin getSkin(AbstractClientPlayer player) { + if(gettingSkin) return null; + + if(player.getUniqueID().version() == 4) return null; + + if(skinOverrideCache.containsKey(player)) { + return skinOverrideCache.get(player); + } + + gettingSkin = true; + ResourceLocation loc = player.getLocationSkin(); + gettingSkin = false; + + if(skinMap.containsKey(loc.getResourcePath())) { + Skin skin = skinMap.get(loc.getResourcePath()); + skinOverrideCache.put(player, skin); + return skin; + } + + skinOverrideCache.put(player, null); + return null; + } + + public void tick() { + skinOverrideCache.clear(); + } + + @Override + public void onResourceManagerReload(IResourceManager resourceManager) { + skinMap.clear(); + + try(BufferedReader reader = new BufferedReader(new InputStreamReader( + Minecraft.getMinecraft().getResourceManager().getResource(npcRetexturingJson).getInputStream(), StandardCharsets.UTF_8))) { + JsonObject json = gson.fromJson(reader, JsonObject.class); + + if(json == null) return; + + for(Map.Entry<String, JsonElement> entry : json.entrySet()) { + if(entry.getValue().isJsonObject()) { + JsonObject val = entry.getValue().getAsJsonObject(); + + Skin skin = new Skin(new ResourceLocation(val.get("skin").getAsString()), val.get("skinny").getAsBoolean()); + skinMap.put("skins/"+entry.getKey(), skin); + } + } + } catch(Exception e) { + e.printStackTrace(); + } + } + + + public static NPCRetexturing getInstance() { + return INSTANCE; + } + +} 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 f759ba7d..ecd38bfd 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/PetInfoOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/PetInfoOverlay.java @@ -1,9 +1,8 @@ package io.github.moulberry.notenoughupdates.miscfeatures; import com.google.common.collect.Lists; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; +import com.google.gson.*; +import io.github.moulberry.notenoughupdates.NEUEventListener; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.core.config.Position; import io.github.moulberry.notenoughupdates.core.util.lerp.LerpUtils; @@ -35,6 +34,8 @@ import org.apache.commons.lang3.text.WordUtils; import org.lwjgl.input.Keyboard; import org.lwjgl.util.vector.Vector2f; +import java.io.*; +import java.nio.charset.StandardCharsets; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.text.NumberFormat; @@ -50,6 +51,8 @@ public class PetInfoOverlay extends TextOverlay { private static final Pattern PET_NAME_PATTERN = Pattern.compile("\u00a77\\[Lvl \\d+] \u00a7(.+)"); private static final Pattern XP_LINE_PATTERN = Pattern.compile("-------------------- (\\d+(?:,\\d+)*(?:\\.\\d+)?)/(\\d+(?:\\.\\d+)?[B|M|k]?)"); + private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); + public PetInfoOverlay(Position position, Supplier<List<String>> dummyStrings, Supplier<TextOverlayStyle> styleSupplier) { super(position, dummyStrings, styleSupplier); } @@ -93,16 +96,18 @@ public class PetInfoOverlay extends TextOverlay { private static long lastXpGain = 0; - private static HashMap<Integer, Pet> petMap = new HashMap<>(); - private static int selectedPet = -1; - private static int selectedPet2 = -1; - private static long lastPetSelect = -1; - //public static Pet currentPet = null; - //public static HashMap<String, Set<Pet>> petList = new HashMap<>(); + public static class PetConfig { + public HashMap<Integer, Pet> petMap = new HashMap<>(); - public static int tamingLevel = 1; - public static float beastMultiplier = 0; - public static boolean setActivePet = false; + private int selectedPet = -1; + private int selectedPet2 = -1; + + public int tamingLevel = 1; + public float beastMultiplier = 0; + } + + private static long lastPetSelect = -1; + private static PetConfig config = new PetConfig(); private static long lastUpdate = 0; private static float levelXpLast = 0; @@ -115,35 +120,52 @@ public class PetInfoOverlay extends TextOverlay { private int xpAddTimer = 0; + public static void loadConfig(File file) { + try(BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8))) { + config = GSON.fromJson(reader, PetConfig.class); + } catch(Exception ignored) {} + if(config == null) { + config = new PetConfig(); + } + } + + public static void saveConfig(File file) { + try { + file.createNewFile(); + try(BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8))) { + writer.write(GSON.toJson(config)); + } + } catch(Exception ignored) {} + } + public static void clearPet() { - selectedPet = -1; - selectedPet2 = -1; + config.selectedPet = -1; + config.selectedPet2 = -1; } public static void setCurrentPet(int index) { - selectedPet2 = selectedPet; + config.selectedPet2 = config.selectedPet; xpGainHourSecondPet = xpGainHour; xpGainHourLast = xpGainHour; xpGainQueue.clear(); - selectedPet = index; + config.selectedPet = index; } public static Pet getCurrentPet() { - return petMap.get(selectedPet); + return config.petMap.get(config.selectedPet); } public static Pet getCurrentPet2() { if(!NotEnoughUpdates.INSTANCE.config.petOverlay.dualPets) return null; - if(selectedPet == selectedPet2) return null; - return petMap.get(selectedPet2); + if(config.selectedPet == config.selectedPet2) return null; + return config.petMap.get(config.selectedPet2); } - public float getLevelPercent() { + public float getLevelPercent(Pet pet) { DecimalFormat df = new DecimalFormat("#.#", DecimalFormatSymbols.getInstance(Locale.ENGLISH)); - Pet pet = getCurrentPet(); if(pet == null) return 0; try { - return Float.parseFloat(df.format(getCurrentPet().petLevel.levelPercentage * 100f)); + return Float.parseFloat(df.format(pet.petLevel.levelPercentage * 100f)); } catch(Exception ignored) { return 0; } @@ -151,7 +173,7 @@ public class PetInfoOverlay extends TextOverlay { private static int getIdForPet(Pet pet) { System.out.println("getting for id"); - for(Map.Entry<Integer, Pet> entry : petMap.entrySet()) { + for(Map.Entry<Integer, Pet> entry : config.petMap.entrySet()) { if(entry.getValue() == pet) { return entry.getKey(); } @@ -171,7 +193,7 @@ public class PetInfoOverlay extends TextOverlay { private static Pet getClosestPet(String petType, int petId, String petItem, float petLevel) { Set<Pet> pets = new HashSet<>(); - for(Pet pet : petMap.values()) { + for(Pet pet : config.petMap.values()) { if(pet.petType.equals(petType) && pet.rarity.petId == petId) { pets.add(pet); } @@ -247,13 +269,13 @@ public class PetInfoOverlay extends TextOverlay { int mk = stats.get("mythos_kills").getAsInt(); float petXpBoost = mk > 10000 ? 1f : mk > 7500 ? 0.9f : mk > 5000 ? 0.8f : mk > 2500 ? 0.7f : mk > 1000 ? 0.6f : mk > 500 ? 0.5f : mk > 250 ? 0.4f : mk > 100 ? 0.3f : mk > 25 ? 0.2f : 0.1f; - beastMultiplier = petXpBoost * currentBeastRarity.beastcreatMultiplyer; + config.beastMultiplier = petXpBoost * currentBeastRarity.beastcreatMultiplyer; } else { - beastMultiplier = 0.1f * currentBeastRarity.beastcreatMultiplyer; + config.beastMultiplier = 0.1f * currentBeastRarity.beastcreatMultiplyer; } } } - if(skillInfo != null) tamingLevel = skillInfo.get("level_skill_taming").getAsInt(); + if(skillInfo != null) config.tamingLevel = skillInfo.get("level_skill_taming").getAsInt(); //JsonObject petObject = profile.getPetsInfo(profile.getLatestProfile()); /*JsonObject petsJson = Constants.PETS; if(petsJson != null) { @@ -334,11 +356,11 @@ public class PetInfoOverlay extends TextOverlay { String lvlStringShort = EnumChatFormatting.AQUA + "" + roundFloat(levelXp) + "/" + roundFloat(currentPet.petLevel.currentLevelRequirement) - + EnumChatFormatting.YELLOW + " (" + getLevelPercent() + "%)"; + + EnumChatFormatting.YELLOW + " (" + getLevelPercent(currentPet) + "%)"; String lvlString = EnumChatFormatting.AQUA + "" + Utils.shortNumberFormat(levelXp, 0) + "/" + Utils.shortNumberFormat(currentPet.petLevel.currentLevelRequirement, 0) - + EnumChatFormatting.YELLOW + " (" + getLevelPercent() + "%)"; + + EnumChatFormatting.YELLOW + " (" + getLevelPercent(currentPet) + "%)"; float xpGain; if(!secondPet) { @@ -441,12 +463,10 @@ public class PetInfoOverlay extends TextOverlay { return; } - NEUConfig config = NotEnoughUpdates.INSTANCE.config; int updateTime = 60000; if(NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) { - ProfileApiSyncer.getInstance().requestResync("petinfo", updateTime, () -> { - }, PetInfoOverlay::getAndSetPet); + ProfileApiSyncer.getInstance().requestResync("petinfo", updateTime, () -> {}, PetInfoOverlay::getAndSetPet); } Pet currentPet = getCurrentPet(); @@ -526,6 +546,11 @@ public class PetInfoOverlay extends TextOverlay { } public static Pet getPetFromStack(String name, String[] lore) { + if(Constants.PETS == null || Constants.PETS.get("pet_levels") == null || Constants.PETS.get("pet_levels") instanceof JsonNull) { + Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("\u00a7cInvalid PET constants. Please run /neuresetrepo and restart game in order to fix. If that doesn't fix it, please join discord.gg/moulberry and post in #neu-support-1")); + return null; + } + String petType = null; Rarity rarity = null; String heldItem = null; @@ -640,7 +665,7 @@ public class PetInfoOverlay extends TextOverlay { @SubscribeEvent public void onTick(TickEvent.ClientTickEvent event) { - if(Minecraft.getMinecraft().currentScreen instanceof GuiChest) { + if(Minecraft.getMinecraft().currentScreen instanceof GuiChest && NEUEventListener.inventoryLoaded) { GuiChest chest = (GuiChest) Minecraft.getMinecraft().currentScreen; ContainerChest container = (ContainerChest) chest.inventorySlots; IInventory lower = container.getLowerChestInventory(); @@ -675,12 +700,12 @@ public class PetInfoOverlay extends TextOverlay { if(!hasItem) return; Set<Integer> clear = new HashSet<>(); - for(int i : petMap.keySet()) { + for(int i : config.petMap.keySet()) { if(i >= maxPage*28) { clear.add(i); } } - petMap.keySet().removeAll(clear); + config.petMap.keySet().removeAll(clear); Set<Integer> removeSet = new HashSet<>(); long currentTime = System.currentTimeMillis(); @@ -698,7 +723,7 @@ public class PetInfoOverlay extends TextOverlay { if(stackNext == null || !stackNext.hasTagCompound()) { int old = removeMap.getOrDefault(petIndex, 0); if(old >= 20) { - petMap.remove(petIndex); + config.petMap.remove(petIndex); } else { removeSet.add(petIndex); removeMap.put(petIndex, old+1); @@ -709,18 +734,18 @@ public class PetInfoOverlay extends TextOverlay { String[] lore = NotEnoughUpdates.INSTANCE.manager.getLoreFromNBT(stack.getTagCompound()); Pet pet = getPetFromStack(stack.getDisplayName(), lore); if(pet != null) { - petMap.put(petIndex, pet); + config.petMap.put(petIndex, pet); if(currentTime - lastPetSelect > 500) { boolean foundDespawn = false; for(String line : lore) { if(line.equals("\u00a77\u00a7cClick to despawn ")) { - selectedPet = petIndex; + config.selectedPet = petIndex; foundDespawn = true; break; } } - if(!foundDespawn && selectedPet == petIndex) { + if(!foundDespawn && config.selectedPet == petIndex) { clearPet(); } } @@ -876,13 +901,10 @@ public class PetInfoOverlay extends TextOverlay { lastPetSelect = System.currentTimeMillis(); if(isRemoving) { - System.out.println("removing"); - System.out.println("new:"+newSelected+":OLD:"+selectedPet); - if(newSelected == selectedPet) { + if(newSelected == config.selectedPet) { clearPet(); - } else if(selectedPet > newSelected) { - System.out.println("decrementing"); - selectedPet--; + } else if(config.selectedPet > newSelected) { + config.selectedPet--; } } else { setCurrentPet(newSelected); @@ -890,7 +912,7 @@ public class PetInfoOverlay extends TextOverlay { String[] lore = NotEnoughUpdates.INSTANCE.manager.getLoreFromNBT(stack.getTagCompound()); Pet pet = getPetFromStack(stack.getDisplayName(), lore); if(pet != null) { - petMap.put(selectedPet, pet); + config.petMap.put(config.selectedPet, pet); } } @@ -907,9 +929,9 @@ public class PetInfoOverlay extends TextOverlay { if(validXpTypes == null) validXpTypes = Lists.newArrayList("mining","foraging","enchanting","farming","combat","fishing","alchemy"); if(!validXpTypes.contains(xpType.toLowerCase())) return 0; - float tamingPercent = 1.0f + (tamingLevel / 100f); + float tamingPercent = 1.0f + (config.tamingLevel / 100f); xp = xp * tamingPercent; - xp = xp + (xp * beastMultiplier / 100f); + xp = xp + (xp * config.beastMultiplier / 100f); if(pet.petXpType != null && !pet.petXpType.equalsIgnoreCase(xpType)) { xp = xp / 3f; @@ -1095,7 +1117,7 @@ public class PetInfoOverlay extends TextOverlay { .replace(" ", "_").toUpperCase(); setCurrentPet(getClosestPetIndex(pet, rarity.petId, "", lastLevelHovered)); - if(selectedPet == -1) { + if(PetInfoOverlay.config.selectedPet == -1) { Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED+"[NEU] Can't find pet \u00a7" + petStringMatch + EnumChatFormatting.RED + " try revisiting all pages of /pets.")); } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/SlotLocking.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/SlotLocking.java new file mode 100644 index 00000000..99ab6a84 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/SlotLocking.java @@ -0,0 +1,357 @@ +package io.github.moulberry.notenoughupdates.miscfeatures; + +import com.google.gson.JsonObject; +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.core.config.KeybindHelper; +import io.github.moulberry.notenoughupdates.core.util.render.RenderUtils; +import io.github.moulberry.notenoughupdates.util.SBInfo; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Gui; +import net.minecraft.client.gui.ScaledResolution; +import net.minecraft.client.gui.inventory.GuiContainer; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.WorldRenderer; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.inventory.Slot; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.client.event.GuiScreenEvent; +import net.minecraftforge.fml.common.eventhandler.EventPriority; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import org.apache.commons.lang3.tuple.Triple; +import org.lwjgl.input.Keyboard; +import org.lwjgl.input.Mouse; +import org.lwjgl.opengl.GL11; +import org.lwjgl.util.vector.Vector2f; +import org.lwjgl.util.vector.Vector3f; + +import java.util.HashMap; +import java.util.function.Consumer; + +public class SlotLocking { + + private static final SlotLocking INSTANCE = new SlotLocking(); + + private static final LockedSlot DEFAULT_LOCKED_SLOT = new LockedSlot(); + private final ResourceLocation LOCK = new ResourceLocation("notenoughupdates:slotlocking/lock.png"); + + public static SlotLocking getInstance() { + return INSTANCE; + } + + public static class LockedSlot { + public boolean locked = false; + public int boundTo = -1; + } + + public static class SlotLockData { + public LockedSlot[] lockedSlots = new LockedSlot[40]; + } + + public static class SlotLockProfile { + int currentProfile = 0; + + public SlotLockData[] slotLockData = new SlotLockData[9]; + } + + public static class SlotLockingConfig { + public HashMap<String, SlotLockProfile> profileData = new HashMap<>(); + } + + private SlotLockingConfig config = new SlotLockingConfig(); + private boolean lockKeyHeld = false; + private Slot pairingSlot = null; + + private LockedSlot[] getDataForProfile() { + if(!NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) return null; + if(SBInfo.getInstance().currentProfile == null) return null; + + SlotLockProfile profile = config.profileData.computeIfAbsent(SBInfo.getInstance().currentProfile, + k->new SlotLockProfile()); + + if(profile.currentProfile < 0) profile.currentProfile = 0; + if(profile.currentProfile >= 9) profile.currentProfile = 8; + + if(profile.slotLockData[profile.currentProfile] == null) { + profile.slotLockData[profile.currentProfile] = new SlotLockData(); + } + + return profile.slotLockData[profile.currentProfile].lockedSlots; + } + + private LockedSlot getLockedSlot(LockedSlot[] lockedSlots, int index) { + if(lockedSlots == null) { + return DEFAULT_LOCKED_SLOT; + } + + LockedSlot slot = lockedSlots[index]; + + if(slot == null) { + return DEFAULT_LOCKED_SLOT; + } + + return slot; + } + + @SubscribeEvent + public void keyboardInput(GuiScreenEvent.KeyboardInputEvent.Post event) { + if(!NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) { + return; + } + if(!(Minecraft.getMinecraft().currentScreen instanceof GuiContainer)) { + return; + } + GuiContainer container = (GuiContainer) Minecraft.getMinecraft().currentScreen; + + int key = Keyboard.KEY_L; + if(!lockKeyHeld && KeybindHelper.isKeyPressed(key)) { + final ScaledResolution scaledresolution = new ScaledResolution(Minecraft.getMinecraft()); + final int scaledWidth = scaledresolution.getScaledWidth(); + final int scaledHeight = scaledresolution.getScaledHeight(); + int mouseX = Mouse.getX() * scaledWidth / Minecraft.getMinecraft().displayWidth; + int mouseY = scaledHeight - Mouse.getY() * scaledHeight / Minecraft.getMinecraft().displayHeight - 1; + + Slot slot = container.getSlotAtPosition(mouseX, mouseY); + if(slot != null && slot.inventory == Minecraft.getMinecraft().thePlayer.inventory) { + int slotNum = slot.getSlotIndex(); + if(slotNum >= 0 && slotNum <= 39) { + boolean isHotbar = slotNum < 9; + boolean isInventory = !isHotbar && slotNum < 36; + boolean isArmor = !isHotbar && !isInventory; + + if(isInventory || isArmor) { + pairingSlot = slot; + } else { + pairingSlot = null; + } + + LockedSlot[] lockedSlots = getDataForProfile(); + + if(lockedSlots != null) { + if(lockedSlots[slotNum] == null) { + lockedSlots[slotNum] = new LockedSlot(); + lockedSlots[slotNum].locked = true; + lockedSlots[slotNum].boundTo = -1; + } else { + lockedSlots[slotNum].locked = !lockedSlots[slotNum].locked; + lockedSlots[slotNum].boundTo = -1; + } + } + } + } + } + lockKeyHeld = KeybindHelper.isKeyDown(key); + if(!lockKeyHeld) { + pairingSlot = null; + } + } + + @SubscribeEvent + public void mouseEvent(GuiScreenEvent.MouseInputEvent event) { + if(!NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) { + return; + } + if(!(Minecraft.getMinecraft().currentScreen instanceof GuiContainer)) { + return; + } + GuiContainer container = (GuiContainer) Minecraft.getMinecraft().currentScreen; + + if(lockKeyHeld && pairingSlot != null) { + final ScaledResolution scaledresolution = new ScaledResolution(Minecraft.getMinecraft()); + final int scaledWidth = scaledresolution.getScaledWidth(); + final int scaledHeight = scaledresolution.getScaledHeight(); + int mouseX = Mouse.getX() * scaledWidth / Minecraft.getMinecraft().displayWidth; + int mouseY = scaledHeight - Mouse.getY() * scaledHeight / Minecraft.getMinecraft().displayHeight - 1; + + Slot slot = container.getSlotAtPosition(mouseX, mouseY); + if(slot != null && slot.inventory == Minecraft.getMinecraft().thePlayer.inventory) { + int slotNum = slot.getSlotIndex(); + if(slotNum >= 0 && slotNum <= 39) { + boolean isHotbar = slotNum < 9; + boolean isInventory = !isHotbar && slotNum < 36; + boolean isArmor = !isHotbar && !isInventory; + + int pairingNum = pairingSlot.getSlotIndex(); + if(isHotbar && slotNum != pairingNum) { + LockedSlot[] lockedSlots = getDataForProfile(); + if(lockedSlots != null) { + if(lockedSlots[pairingNum] == null) { + lockedSlots[pairingNum] = new LockedSlot(); + } + lockedSlots[pairingNum].boundTo = slotNum; + lockedSlots[pairingNum].locked = false; + } + } + } + } + } + } + + + @SubscribeEvent(priority = EventPriority.LOW) + public void drawScreenEvent(GuiScreenEvent.DrawScreenEvent.Post event) { + if(!event.isCanceled() && pairingSlot != null && lockKeyHeld) { + if(!(Minecraft.getMinecraft().currentScreen instanceof GuiContainer)) { + return; + } + GuiContainer container = (GuiContainer) Minecraft.getMinecraft().currentScreen; + + int x2 = event.mouseX; + int y2 = event.mouseY; + + LockedSlot[] lockedSlots = getDataForProfile(); + LockedSlot lockedSlot = getLockedSlot(lockedSlots, pairingSlot.getSlotIndex()); + if(lockedSlot.boundTo >= 0 && lockedSlot.boundTo < 9) { + Slot boundSlot = container.inventorySlots.getSlotFromInventory(Minecraft.getMinecraft().thePlayer.inventory, lockedSlot.boundTo); + x2 = container.guiLeft+boundSlot.xDisplayPosition+8; + y2 = container.guiTop+boundSlot.yDisplayPosition+8; + } + + drawLinkArrow(container.guiLeft+pairingSlot.xDisplayPosition+8, + container.guiTop+pairingSlot.yDisplayPosition+8, + x2, y2); + } + } + + private void drawLinkArrow(int x1, int y1, int x2, int y2) { + GlStateManager.color(0x33/255f, 0xff/255f, 0xcc/255f, 1f); + GlStateManager.disableLighting(); + RenderHelper.disableStandardItemLighting(); + GlStateManager.disableTexture2D(); + GlStateManager.enableBlend(); + GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0); + + GlStateManager.translate(0, 0, 500); + drawLine(x1, y1, x2, y2); + GlStateManager.translate(0, 0, -500); + + GlStateManager.enableTexture2D(); + } + + private void drawLine(int x1, int y1, int x2, int y2) { + Vector2f vec = new Vector2f(x2 - x1, y2 - y1); + vec.normalise(vec); + Vector2f side = new Vector2f(vec.y, -vec.x); + + GL11.glLineWidth(1f); + GL11.glEnable(GL11.GL_LINE_SMOOTH); + + /*worldrenderer.begin(GL11.GL_TRIANGLE_STRIP, DefaultVertexFormats.POSITION); + worldrenderer.pos(x1, y1, 0.0D).endVertex(); + worldrenderer.pos(x1+vec.x-side.x, y1+vec.y-side.y, 0.0D).endVertex(); + worldrenderer.pos(x1+vec.x+side.x, y1+vec.y+side.y, 0.0D).endVertex(); + worldrenderer.pos(x2-vec.x-side.x, y2-vec.y-side.y, 0.0D).endVertex(); + worldrenderer.pos(x2-vec.x+side.x, y2-vec.y+side.y, 0.0D).endVertex(); + worldrenderer.pos(x2, y2, 0.0D).endVertex();*/ + + Tessellator tessellator = Tessellator.getInstance(); + WorldRenderer worldrenderer = tessellator.getWorldRenderer(); + worldrenderer.begin(GL11.GL_LINES, DefaultVertexFormats.POSITION); + worldrenderer.pos(x1, y1, 0.0D).endVertex(); + worldrenderer.pos(x2, y2, 0.0D).endVertex(); + tessellator.draw(); + + worldrenderer.begin(GL11.GL_LINES, DefaultVertexFormats.POSITION); + worldrenderer.pos(x1-side.x/2f, y1-side.y/2f, 0.0D).endVertex(); + worldrenderer.pos(x2-side.x/2f, y2-side.y/2f, 0.0D).endVertex(); + tessellator.draw(); + + worldrenderer.begin(GL11.GL_LINES, DefaultVertexFormats.POSITION); + worldrenderer.pos(x1+side.x/2f, y1+side.y/2f, 0.0D).endVertex(); + worldrenderer.pos(x2+side.x/2f, y2+side.y/2f, 0.0D).endVertex(); + tessellator.draw(); + } + + public void onWindowClick(Slot slotIn, int slotId, int clickedButton, int clickType, Consumer<Triple<Integer, Integer, Integer>> consumer) { + LockedSlot locked = getLockedSlot(slotIn); + if(locked == null) { + return; + } else if(isSlotLocked(slotIn) || (clickType == 2 && SlotLocking.getInstance().isSlotIndexLocked(clickedButton))) { + consumer.accept(null); + } else if(clickType == 1 && locked.boundTo >= 0 && locked.boundTo < 9) { + if(slotId > 9) { + consumer.accept(Triple.of(slotId, locked.boundTo, 2)); + + GuiContainer container = (GuiContainer) Minecraft.getMinecraft().currentScreen; + Slot boundSlot = container.inventorySlots.getSlotFromInventory(Minecraft.getMinecraft().thePlayer.inventory, locked.boundTo); + + LockedSlot boundLocked = getLockedSlot(boundSlot); + + + } + + } + } + + public void drawSlot(Slot slot) { + LockedSlot locked = getLockedSlot(slot); + if(locked != null) { + if(locked.locked) { + GlStateManager.translate(0, 0, 400); + Minecraft.getMinecraft().getTextureManager().bindTexture(LOCK); + GlStateManager.color(1, 1, 1, 0.5f); + GlStateManager.depthMask(false); + RenderUtils.drawTexturedRect(slot.xDisplayPosition, slot.yDisplayPosition, 16, 16, 0, 1, 0, 1, GL11.GL_NEAREST); + GlStateManager.depthMask(true); + GlStateManager.enableBlend(); + GlStateManager.translate(0, 0, -400); + } else if(slot.canBeHovered() && locked.boundTo >= 0 && locked.boundTo < 9) { + if(!(Minecraft.getMinecraft().currentScreen instanceof GuiContainer)) { + return; + } + GuiContainer container = (GuiContainer) Minecraft.getMinecraft().currentScreen; + + final ScaledResolution scaledresolution = new ScaledResolution(Minecraft.getMinecraft()); + final int scaledWidth = scaledresolution.getScaledWidth(); + final int scaledHeight = scaledresolution.getScaledHeight(); + int mouseX = Mouse.getX() * scaledWidth / Minecraft.getMinecraft().displayWidth; + int mouseY = scaledHeight - Mouse.getY() * scaledHeight / Minecraft.getMinecraft().displayHeight - 1; + + if(container.isMouseOverSlot(slot, mouseX, mouseY)) { + Slot boundSlot = container.inventorySlots.getSlotFromInventory(Minecraft.getMinecraft().thePlayer.inventory, locked.boundTo); + int x2 = boundSlot.xDisplayPosition+8; + int y2 = boundSlot.yDisplayPosition+8; + + drawLinkArrow(slot.xDisplayPosition+8, + slot.yDisplayPosition+8, x2, y2); + } + } + } + } + + public LockedSlot getLockedSlot(Slot slot) { + if(!NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) return null; + if(slot == null) { + return null; + } + if(slot.inventory != Minecraft.getMinecraft().thePlayer.inventory) { + return null; + } + int index = slot.getSlotIndex(); + if(index < 0 || index > 39) { + return null; + } + return getLockedSlotIndex(index); + } + + public LockedSlot getLockedSlotIndex(int index) { + if(!NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) return null; + + LockedSlot[] lockedSlots = getDataForProfile(); + if(lockedSlots == null) return null; + return getLockedSlot(lockedSlots, index); + } + + public boolean isSlotLocked(Slot slot) { + LockedSlot locked = getLockedSlot(slot); + return locked != null && locked.locked; + } + + public boolean isSlotIndexLocked(int index) { + LockedSlot locked = getLockedSlotIndex(index); + + return locked != null && locked.locked; + } + +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/StorageManager.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/StorageManager.java new file mode 100644 index 00000000..54478fa4 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/StorageManager.java @@ -0,0 +1,595 @@ +package io.github.moulberry.notenoughupdates.miscfeatures; + +import com.google.gson.*; +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +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.gui.inventory.GuiChest; +import net.minecraft.init.Blocks; +import net.minecraft.inventory.ContainerChest; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.*; +import net.minecraft.network.play.client.C0EPacketClickWindow; +import net.minecraft.network.play.server.S2DPacketOpenWindow; +import net.minecraft.network.play.server.S2EPacketCloseWindow; +import net.minecraft.network.play.server.S2FPacketSetSlot; +import net.minecraft.network.play.server.S30PacketWindowItems; +import org.lwjgl.input.Keyboard; + +import java.io.*; +import java.lang.reflect.Type; +import java.nio.charset.StandardCharsets; +import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.zip.GZIPInputStream; +import java.util.zip.GZIPOutputStream; + +public class StorageManager { + + private static final StorageManager INSTANCE = new StorageManager(); + private static final Gson GSON = new GsonBuilder() + .registerTypeAdapter(ItemStack.class, new ItemStackSerializer()) + .registerTypeAdapter(ItemStack.class, new ItemStackDeserilizer()).create(); + + public static class ItemStackSerializer implements JsonSerializer<ItemStack> { + @Override + public JsonElement serialize(ItemStack src, Type typeOfSrc, + JsonSerializationContext context) { + NBTTagCompound tag = src.serializeNBT(); + return nbtToJson(tag); + } + } + + private static final Pattern JSON_FIX_REGEX = Pattern.compile("\"([^,:]+)\":"); + + public static class ItemStackDeserilizer implements JsonDeserializer<ItemStack> { + @Override + public ItemStack deserialize(JsonElement json, Type typeOfT, + JsonDeserializationContext context) throws JsonParseException { + try { + JsonObject object = json.getAsJsonObject(); + + NBTTagCompound tag = JsonToNBT.getTagFromJson(JSON_FIX_REGEX.matcher(object.toString()).replaceAll("$1:")); + + Item item; + if(tag.hasKey("id", 8)) { + item = Item.getByNameOrId(tag.getString("id")); + } else { + item = Item.getItemById(tag.getShort("id")); + } + if(item == null) { + return null; + } + int stackSize = tag.getInteger("Count"); + int damage = tag.getInteger("Damage"); + + ItemStack stack = new ItemStack(item, stackSize, damage); + + if(tag.hasKey("tag")) { + NBTTagCompound itemTag = tag.getCompoundTag("tag"); + stack.setTagCompound(itemTag); + } + + return stack; + } catch(Exception e) { + e.printStackTrace(); + return null; + } + } + } + + private static JsonObject nbtToJson(NBTTagCompound NBTTagCompound) { + return (JsonObject) loadJson(NBTTagCompound); + } + + private static JsonElement loadJson(NBTBase tag) { + if (tag instanceof NBTTagCompound) { + NBTTagCompound compoundTag = (NBTTagCompound) tag; + JsonObject jsonObject = new JsonObject(); + for (String key : compoundTag.getKeySet()) { + jsonObject.add(key, loadJson(compoundTag.getTag(key))); + } + return jsonObject; + } else if (tag instanceof NBTTagList) { + NBTTagList listTag = (NBTTagList) tag; + JsonArray jsonArray = new JsonArray(); + for(int i=0; i<listTag.tagCount(); i++) { + jsonArray.add(loadJson(listTag.get(i))); + } + return jsonArray; + } else if (tag instanceof NBTTagIntArray) { + NBTTagIntArray listTag = (NBTTagIntArray) tag; + int[] arr = listTag.getIntArray(); + JsonArray jsonArray = new JsonArray(); + for(int i=0; i<arr.length; i++) { + jsonArray.add(new JsonPrimitive(arr[i])); + } + return jsonArray; + } else if (tag instanceof NBTTagByteArray) { + NBTTagByteArray listTag = (NBTTagByteArray) tag; + byte[] arr = listTag.getByteArray(); + JsonArray jsonArray = new JsonArray(); + for(int i=0; i<arr.length; i++) { + jsonArray.add(new JsonPrimitive(arr[i])); + } + return jsonArray; + }else if (tag instanceof NBTTagShort) { + return new JsonPrimitive(((NBTTagShort) tag).getShort()); + } else if (tag instanceof NBTTagInt) { + return new JsonPrimitive(((NBTTagInt) tag).getInt()); + } else if (tag instanceof NBTTagLong) { + return new JsonPrimitive(((NBTTagLong) tag).getLong()); + } else if (tag instanceof NBTTagFloat) { + return new JsonPrimitive(((NBTTagFloat) tag).getFloat()); + } else if (tag instanceof NBTTagDouble) { + return new JsonPrimitive(((NBTTagDouble) tag).getDouble()); + } else if (tag instanceof NBTTagByte) { + return new JsonPrimitive(((NBTTagByte) tag).getByte()); + } else if(tag instanceof NBTTagString){ + return new JsonPrimitive(((NBTTagString)tag).getString()); + } else { + return new JsonPrimitive("Broken_Json_Deserialize_Tag"); + } + } + + public static StorageManager getInstance() { + return INSTANCE; + } + + private AtomicInteger searchId = new AtomicInteger(0); + + public static class StoragePage { + public ItemStack[] items = new ItemStack[45]; + public ItemStack backpackDisplayStack; + public int rows = -1; + + public transient boolean matchesSearch; + public transient int searchedId; + } + + public static int MAX_ENDER_CHEST_PAGES = 9; + + public static final ItemStack LOCKED_ENDERCHEST_STACK = Utils.createItemStack(Item.getItemFromBlock(Blocks.stained_glass_pane), + "\u00a7cLocked Page", 14, + "\u00a77Unlock more Ender Chest", + "\u00a77pages in the community", + "\u00a77shop!"); + + public static class StorageConfig { + public HashMap<String, StoragePage[]> pages = new HashMap<>(); + public final HashMap<Integer, Integer> displayToStorageIdMap = new HashMap<>(); + } + + public StorageConfig storageConfig = new StorageConfig(); + + private int currentStoragePage = -1; + public boolean onStorageMenu = false; + + private String lastSearch = ""; + + private boolean[] storagePresent = new boolean[27]; + + //TODO: Replace with /storage {id} when hypixel becomes not lazy + public int desiredStoragePage = -1; + public long storageOpenSwitchMillis = 0; + + private ItemStack[] missingBackpackStacks = new ItemStack[18]; + + private boolean shouldRenderStorageOverlayCached = false; + + private static final Pattern WINDOW_REGEX = Pattern.compile(".+ Backpack \\((\\d+)/(\\d+)\\)"); + private static final Pattern ECHEST_WINDOW_REGEX = Pattern.compile("Ender Chest \\((\\d+)/(\\d+)\\)"); + + public void loadConfig(File file) { + try(BufferedReader reader = new BufferedReader(new InputStreamReader(new GZIPInputStream(new FileInputStream(file)), StandardCharsets.UTF_8))) { + storageConfig = GSON.fromJson(reader, StorageConfig.class); + } catch(Exception ignored) { } + if(storageConfig == null) { + storageConfig = new StorageConfig(); + } + } + + public void saveConfig(File file) { + try { + file.createNewFile(); + try(BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new GZIPOutputStream(new FileOutputStream(file)), StandardCharsets.UTF_8))) { + writer.write(GSON.toJson(storageConfig)); + } + } catch(Exception ignored) { + ignored.printStackTrace(); + } + } + + public ItemStack getMissingBackpackStack(int storageId) { + if(missingBackpackStacks[storageId] != null) { + return missingBackpackStacks[storageId]; + } + + ItemStack stack = Utils.createItemStack(Item.getItemFromBlock(Blocks.stained_glass_pane), + "\u00a7cEmpty Backpack Slot "+(storageId+1), 12, + "", + "\u00a7eLeft-click a backpack", + "\u00a7eitem on this slot to place", + "\u00a7eit!"); + + missingBackpackStacks[storageId] = stack; + return stack; + } + + public boolean shouldRenderStorageOverlay(String containerName) { + if(!NotEnoughUpdates.INSTANCE.config.storageGUI.enableStorageGUI) { + shouldRenderStorageOverlayCached = false; + return false; + } + + if(!NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) { + shouldRenderStorageOverlayCached = false; + return false; + } + + if(!(Minecraft.getMinecraft().currentScreen instanceof GuiChest)) { + shouldRenderStorageOverlayCached = false; + return false; + } + + if(getCurrentWindowId() != -1 && getCurrentPageId() != -1) { + shouldRenderStorageOverlayCached = true; + return true; + } + + shouldRenderStorageOverlayCached = containerName != null && containerName.trim().startsWith("Storage"); + return shouldRenderStorageOverlayCached; + } + + public boolean shouldRenderStorageOverlayFast() { + return shouldRenderStorageOverlayCached; + } + + private StoragePage[] getPagesForProfile() { + if(!NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) return null; + if(SBInfo.getInstance().currentProfile == null) return null; + + return storageConfig.pages.computeIfAbsent(SBInfo.getInstance().currentProfile, k -> new StoragePage[27]); + } + + public StoragePage getPage(int pageIndex, boolean createPage) { + if(pageIndex == -1) return null; + + StoragePage[] pages = getPagesForProfile(); + if(pages == null) return null; + + if(createPage && pages[pageIndex] == null) pages[pageIndex] = new StoragePage(); + + return pages[pageIndex]; + } + + public void removePage(int pageIndex) { + if(pageIndex == -1) return; + + StoragePage[] pages = getPagesForProfile(); + if(pages == null) return; + + pages[pageIndex] = null; + } + + public StoragePage getCurrentPage() { + return getPage(getCurrentPageId(), true); + } + + private void setItemSlot(int index, ItemStack item) { + StoragePage page = getCurrentPage(); + if(page != null) { + page.items[index] = item; + } + } + + public int getCurrentPageId() { + if(!(Minecraft.getMinecraft().currentScreen instanceof GuiChest)) { + currentStoragePage = -1; + return -1; + } + + return currentStoragePage; + } + + public int getCurrentWindowId() { + if(!(Minecraft.getMinecraft().currentScreen instanceof GuiChest)) { + currentStoragePage = -1; + return -1; + } + + GuiChest chest = (GuiChest)Minecraft.getMinecraft().currentScreen; + + return chest.inventorySlots.windowId; + } + + public void sendToPage(int page) { + if(desiredStoragePage != getCurrentPageId() && + System.currentTimeMillis() - storageOpenSwitchMillis < 1000) return; + if(getCurrentPageId() == page) return; + + if(getCurrentWindowId() != -1 && onStorageMenu) { + if(page < 9) { + sendMouseClick(getCurrentWindowId(), 9+page); + } else { + sendMouseClick(getCurrentWindowId(), 27+page-MAX_ENDER_CHEST_PAGES); + } + } else { + storageOpenSwitchMillis = System.currentTimeMillis(); + desiredStoragePage = page; + + NotEnoughUpdates.INSTANCE.sendChatMessage("/storage"); + } + } + + private void sendMouseClick(int windowId, int slotIndex) { + Minecraft.getMinecraft().playerController.windowClick(windowId, slotIndex, 0, 0, + Minecraft.getMinecraft().thePlayer); + } + + public int getDisplayIdForStorageId(int storageId) { + if(storageId < 0) return -1; + for(Map.Entry<Integer, Integer> entry : storageConfig.displayToStorageIdMap.entrySet()) { + if(entry.getValue() == storageId) { + return entry.getKey(); + } + } + return -1; + } + + public void openWindowPacket(S2DPacketOpenWindow packet) { + shouldRenderStorageOverlayCached = false; + if(!NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) return; + + String windowTitle = Utils.cleanColour(packet.getWindowTitle().getUnformattedText()); + + Matcher matcher = WINDOW_REGEX.matcher(windowTitle); + Matcher matcherEchest = ECHEST_WINDOW_REGEX.matcher(windowTitle); + + currentStoragePage = -1; + onStorageMenu = false; + + 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)); + + if(page > 0 && page <= 18) { + currentStoragePage = page-1+MAX_ENDER_CHEST_PAGES; + + int displayId = getDisplayIdForStorageId(currentStoragePage); + if(displayId >= 0) StorageOverlay.getInstance().scrollToStorage(displayId, false); + + StoragePage spage = getCurrentPage(); + if(spage != null) { + spage.rows = packet.getSlotCount()/9 - 1; + } + } + } else if(matcherEchest.matches()) { + int page = Integer.parseInt(matcherEchest.group(1)); + + if(page > 0 && page <= 9) { + currentStoragePage = page-1; + + int displayId = getDisplayIdForStorageId(currentStoragePage); + if(displayId >= 0) StorageOverlay.getInstance().scrollToStorage(displayId, false); + + StoragePage spage = getCurrentPage(); + if(spage != null) { + spage.rows = packet.getSlotCount()/9 - 1; + } + } + } else { + StorageOverlay.getInstance().clearSearch(); + } + } + + public void closeWindowPacket(S2EPacketCloseWindow packet) { + shouldRenderStorageOverlayCached = false; + } + + public void setSlotPacket(S2FPacketSetSlot packet) { + if(!NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) return; + if(getCurrentWindowId() == -1 || getCurrentWindowId() != packet.func_149175_c()) return; + + if(getCurrentPageId() != -1) { + StoragePage page = getCurrentPage(); + + int slot = packet.func_149173_d(); + if(page != null && slot >= 9 && slot < 9+page.rows*9) { + setItemSlot(packet.func_149173_d()-9, packet.func_149174_e()); + } + } else if(onStorageMenu) { + int slot = packet.func_149173_d(); + ItemStack stack = packet.func_149174_e(); + + if(slot >= 9 && slot < 18) { + int index = slot-9; + + boolean changed = false; + if(stack.getItem() == Item.getItemFromBlock(Blocks.stained_glass_pane) && + stack.getMetadata() == 14) { + if(storagePresent[index]) changed = true; + storagePresent[index] = false; + removePage(index); + } else { + if(!storagePresent[index]) changed = true; + storagePresent[index] = true; + getPage(index, true).backpackDisplayStack = stack; + } + + if(changed) { + synchronized(storageConfig.displayToStorageIdMap) { + storageConfig.displayToStorageIdMap.clear(); + int displayIndex = 0; + for(int i=0; i<storagePresent.length; i++) { + if(storagePresent[i]) { + if(lastSearch == null || lastSearch.isEmpty()) { + storageConfig.displayToStorageIdMap.put(displayIndex++, i); + } else { + StoragePage page = getPage(i, false); + + if(page != null) { + updateSearchForPage(lastSearch, page); + if(page.matchesSearch) { + storageConfig.displayToStorageIdMap.put(displayIndex++, i); + } + } + } + } + } + } + } + } + + if(slot >= 27 && slot < 45) { + int index = (slot-27)%9 + (slot-27)/9*9 + MAX_ENDER_CHEST_PAGES; + + boolean changed = false; + + if(stack.getItem() == Item.getItemFromBlock(Blocks.stained_glass_pane)) { + if(storagePresent[index]) changed = true; + storagePresent[index] = false; + removePage(index); + } else { + if(!storagePresent[index]) changed = true; + storagePresent[index] = true; + getPage(index, true).backpackDisplayStack = stack; + } + + if(changed) { + synchronized(storageConfig.displayToStorageIdMap) { + storageConfig.displayToStorageIdMap.clear(); + int displayIndex = 0; + for(int i=0; i<storagePresent.length; i++) { + if(storagePresent[i]) { + if(lastSearch == null || lastSearch.isEmpty()) { + storageConfig.displayToStorageIdMap.put(displayIndex++, i); + } else { + StoragePage page = getPage(i, false); + + if(page != null) { + updateSearchForPage(lastSearch, page); + if(page.matchesSearch) { + storageConfig.displayToStorageIdMap.put(displayIndex++, i); + } + } + } + } + } + } + } + } + } + } + + public void updateSearchForPage(String searchStr, StoragePage page) { + if(page == null) { + return; + } + + if(page.rows <= 0) { + page.matchesSearch = true; + return; + } + + if(page.searchedId > searchId.get()) { + page.searchedId = -1; + return; + } + if(page.searchedId == searchId.get()) { + return; + } + + page.searchedId = searchId.get(); + + if(searchStr == null || searchStr.trim().isEmpty()) { + page.matchesSearch = true; + return; + } + + for(ItemStack stack : page.items) { + if(stack != null && NotEnoughUpdates.INSTANCE.manager.doesStackMatchSearch(stack, searchStr)) { + page.matchesSearch = true; + return; + } + } + page.matchesSearch = false; + } + + public void searchDisplay(String searchStr) { + synchronized(storageConfig.displayToStorageIdMap) { + storageConfig.displayToStorageIdMap.clear(); + + lastSearch = searchStr; + int sid = searchId.incrementAndGet(); + int displayIndex = 0; + for(int i=0; i<storagePresent.length; i++) { + if(storagePresent[i]) { + StoragePage page = getPage(i, false); + if(page != null) { + if(page.rows > 0) { + updateSearchForPage(searchStr, page); + if(page.matchesSearch) { + storageConfig.displayToStorageIdMap.put(displayIndex++, i); + } + } else { + storageConfig.displayToStorageIdMap.put(displayIndex++, i); + page.matchesSearch = true; + page.searchedId = sid; + } + } + } + } + } + } + + public void setItemsPacket(S30PacketWindowItems packet) { + if(!NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) return; + if(getCurrentWindowId() == -1 || getCurrentWindowId() != packet.func_148911_c()) return; + + if(getCurrentPageId() != -1) { + StoragePage page = getPage(getCurrentPageId(), false); + + if(page != null) { + int max = Math.min(page.rows*9, packet.getItemStacks().length-9); + for(int i=0; i<max; i++) { + setItemSlot(i, packet.getItemStacks()[i+9]); + } + } + + } + } + + public void clientSendWindowClick(C0EPacketClickWindow packet) { + if(!NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) return; + if(getCurrentWindowId() == -1 || getCurrentWindowId() != packet.getWindowId()) return; + if(!(Minecraft.getMinecraft().currentScreen instanceof GuiChest)) return; + ContainerChest containerChest = (ContainerChest)((GuiChest)Minecraft.getMinecraft().currentScreen).inventorySlots; + + if(getCurrentPageId() != -1) { + StoragePage page = getCurrentPage(); + if(page == null) return; + + IInventory inv = containerChest.getLowerChestInventory(); + int max = Math.min(9+page.rows*9, inv.getSizeInventory()); + for(int i=9; i<max; i++) { + setItemSlot(i-9, inv.getStackInSlot(i)); + } + } + } +} 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 a6042134..760b7bab 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/AccessoryBagOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/AccessoryBagOverlay.java @@ -3,6 +3,7 @@ package io.github.moulberry.notenoughupdates.miscgui; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; +import io.github.moulberry.notenoughupdates.NEUEventListener; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.core.util.StringUtils; import io.github.moulberry.notenoughupdates.profileviewer.PlayerStats; @@ -578,7 +579,7 @@ public class AccessoryBagOverlay { } public static void renderOverlay() { - if(Minecraft.getMinecraft().currentScreen instanceof GuiChest) { + if(Minecraft.getMinecraft().currentScreen instanceof GuiChest && NEUEventListener.inventoryLoaded) { GuiChest eventGui = (GuiChest) Minecraft.getMinecraft().currentScreen; ContainerChest cc = (ContainerChest) eventGui.inventorySlots; String containerName = cc.getLowerChestInventory().getDisplayName().getUnformattedText(); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiItemCustomize.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiItemCustomize.java new file mode 100644 index 00000000..166e6ba2 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiItemCustomize.java @@ -0,0 +1,372 @@ +package io.github.moulberry.notenoughupdates.miscgui; + +import io.github.moulberry.notenoughupdates.core.*; +import io.github.moulberry.notenoughupdates.core.util.lerp.LerpingFloat; +import io.github.moulberry.notenoughupdates.core.util.render.RenderUtils; +import io.github.moulberry.notenoughupdates.miscfeatures.ItemCustomizeManager; +import io.github.moulberry.notenoughupdates.util.Utils; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Gui; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.gui.ScaledResolution; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.resources.model.IBakedModel; +import net.minecraft.item.ItemArmor; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; +import org.lwjgl.input.Keyboard; +import org.lwjgl.input.Mouse; +import org.lwjgl.opengl.GL11; + +import java.awt.*; +import java.io.*; +import java.net.URL; + +public class GuiItemCustomize extends GuiScreen { + + private static final ResourceLocation RESET = new ResourceLocation("notenoughupdates:itemcustomize/reset.png"); + + private final ItemStack stack; + private final String itemUUID; + private final GuiElementTextField textFieldRename = new GuiElementTextField("", 178, 20, GuiElementTextField.COLOUR); + private final GuiElementBoolean enchantGlintButton; + + private int renderHeight = 0; + + private final LerpingFloat enchantGlintCustomColourAnimation = new LerpingFloat(0, 200); + + private boolean enchantGlint; + private String customGlintColour = null; + + private String customLeatherColour = null; + private final boolean supportCustomLeatherColour; + + private GuiElement editor = null; + + public GuiItemCustomize(ItemStack stack, String itemUUID) { + this.stack = stack; + this.itemUUID = itemUUID; + + IBakedModel model = Minecraft.getMinecraft().getRenderItem().getItemModelMesher().getItemModel(stack); + boolean stackHasEffect = stack.hasEffect() && !model.isBuiltInRenderer(); + + ItemCustomizeManager.ItemData data = ItemCustomizeManager.getDataForItem(stack); + if(data != null) { + this.enchantGlint = data.overrideEnchantGlint ? data.enchantGlintValue : stackHasEffect; + if(data.customName != null) { + textFieldRename.setText(data.customName); + } + this.customGlintColour = data.customGlintColour; + this.customLeatherColour = data.customLeatherColour; + } else { + this.enchantGlint = stackHasEffect; + } + + supportCustomLeatherColour = stack.getItem() instanceof ItemArmor && ((ItemArmor)stack.getItem()).hasColor(stack); + + enchantGlintCustomColourAnimation.setValue(enchantGlint ? 17 : 0); + this.enchantGlintButton = new GuiElementBoolean(0, 0, enchantGlint, (bool) -> { + enchantGlint = bool; + updateData(); + }); + + } + + @Override + public void onGuiClosed() { + updateData(); + } + + public String getChromaStrFromLeatherColour() { + return ChromaColour.special(0, 0xff, ((ItemArmor)stack.getItem()).getColor(stack)); + } + + public void updateData() { + ItemCustomizeManager.ItemData data = new ItemCustomizeManager.ItemData(); + + IBakedModel model = Minecraft.getMinecraft().getRenderItem().getItemModelMesher().getItemModel(stack); + boolean stackHasEffect = stack.hasEffect() && !model.isBuiltInRenderer(); + + if(this.enchantGlint != stackHasEffect) { + data.overrideEnchantGlint = true; + data.enchantGlintValue = this.enchantGlint; + } + + if(this.customGlintColour != null && !this.customGlintColour.equals(ItemCustomizeManager.DEFAULT_GLINT_COLOR)) { + data.customGlintColour = this.customGlintColour; + } else if(model.isBuiltInRenderer() && data.overrideEnchantGlint && data.enchantGlintValue) { + data.customGlintColour = ItemCustomizeManager.DEFAULT_GLINT_COLOR; + } else { + data.customGlintColour = null; + } + + if(supportCustomLeatherColour && this.customLeatherColour != null && !this.customLeatherColour.equals(getChromaStrFromLeatherColour())) { + data.customLeatherColour = this.customLeatherColour; + } else { + data.customLeatherColour = null; + } + + if(!this.textFieldRename.getText().isEmpty()) { + data.customName = this.textFieldRename.getText(); + } + + ItemCustomizeManager.putItemData(itemUUID, data); + } + + private int getGlintColour() { + int col = customGlintColour == null ? ChromaColour.specialToChromaRGB(ItemCustomizeManager.DEFAULT_GLINT_COLOR) : ChromaColour.specialToChromaRGB(customGlintColour); + return 0xff000000 | col; + } + + private int getLeatherColour() { + if(!supportCustomLeatherColour) return 0xff000000; + + int col = customLeatherColour == null ? ((ItemArmor)stack.getItem()).getColor(stack) : ChromaColour.specialToChromaRGB(customLeatherColour); + return 0xff000000 | col; + } + + @Override + public void drawScreen(int mouseX, int mouseY, float partialTicks) { + drawDefaultBackground(); + + ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft()); + + int xCenter = scaledResolution.getScaledWidth()/2; + int yTopStart = (scaledResolution.getScaledHeight()-renderHeight)/2; + int yTop = yTopStart; + + RenderUtils.drawFloatingRectDark(xCenter-100, yTop-9, 200, renderHeight); + + RenderUtils.drawFloatingRectDark(xCenter-90, yTop-5, 180, 14); + Utils.renderShadowedString("\u00a75\u00a7lNEU Item Customizer", xCenter, yTop-1, 180); + + yTop += 14; + + if(!textFieldRename.getFocus() && textFieldRename.getText().isEmpty()) { + textFieldRename.setOptions(0); + textFieldRename.setPrependText("\u00a77Enter Custom Name..."); + } else { + textFieldRename.setOptions(GuiElementTextField.COLOUR); + textFieldRename.setPrependText(""); + } + + textFieldRename.render(xCenter-textFieldRename.getWidth()/2, yTop); + yTop += 25; + + RenderUtils.drawFloatingRectDark(xCenter-90, yTop, 180, 110); + GlStateManager.enableDepth(); + GlStateManager.pushMatrix(); + GlStateManager.translate(xCenter-48, yTop+7, 0); + GlStateManager.scale(6, 6, 1); + Utils.drawItemStack(stack, 0, 0); + GlStateManager.popMatrix(); + + yTop += 115; + + RenderUtils.drawFloatingRectDark(xCenter-90, yTop, 180, 20); + + Minecraft.getMinecraft().fontRendererObj.drawString("Enchant Glint", + xCenter-85, yTop+6, 0xff8040cc); + + enchantGlintButton.x = xCenter+90-5-48; + enchantGlintButton.y = yTop+3; + enchantGlintButton.render(); + + yTop += 25; + + enchantGlintCustomColourAnimation.tick(); + if(enchantGlintCustomColourAnimation.getValue() > 0) { + yTop -= 5; + + int glintColour = getGlintColour(); + + GlScissorStack.push(0, yTop, scaledResolution.getScaledWidth(), scaledResolution.getScaledHeight(), scaledResolution); + GlStateManager.translate(0, enchantGlintCustomColourAnimation.getValue()-17, 0); + + Gui.drawRect(xCenter-90, yTop, xCenter+92, yTop+17, 0x70000000); + Gui.drawRect(xCenter-90, yTop, xCenter+90, yTop+15, 0xff101016); + Gui.drawRect(xCenter-89, yTop+1, xCenter+89, yTop+14, 0xff000000 | glintColour); + + Utils.renderShadowedString("\u00a7a\u00a7lCustom Glint Colour", xCenter, yTop+4, 180); + + Minecraft.getMinecraft().getTextureManager().bindTexture(RESET); + GlStateManager.color(1, 1, 1, 1); + RenderUtils.drawTexturedRect(xCenter+90-12, yTop+2, 10, 11, GL11.GL_NEAREST); + + GlStateManager.translate(0, -enchantGlintCustomColourAnimation.getValue()+17, 0); + GlScissorStack.pop(scaledResolution); + + yTop += enchantGlintCustomColourAnimation.getValue()+3; + } + + if(supportCustomLeatherColour) { + int leatherColour = getLeatherColour(); + + Gui.drawRect(xCenter-90, yTop, xCenter+92, yTop+17, 0x70000000); + Gui.drawRect(xCenter-90, yTop, xCenter+90, yTop+15, 0xff101016); + Gui.drawRect(xCenter-89, yTop+1, xCenter+89, yTop+14, 0xff000000 | leatherColour); + + Utils.renderShadowedString("\u00a7b\u00a7lCustom Leather Colour", xCenter, yTop+4, 180); + + Minecraft.getMinecraft().getTextureManager().bindTexture(RESET); + GlStateManager.color(1, 1, 1, 1); + RenderUtils.drawTexturedRect(xCenter+90-12, yTop+2, 10, 11, GL11.GL_NEAREST); + + yTop += 20; + } + + /*if(true) { + yTop += 20; + + String titleStr = "\u00a76\u00a7lWant other players to see your customized item?"; + String buttonStr = "\u00a76Purchase Item Customize Tag"; + if(true) { + buttonStr = "\u00a76Use item customize tag (3 remaining)"; + } + + int w = Minecraft.getMinecraft().fontRendererObj.getStringWidth(titleStr)+8; + if(w > scaledResolution.getScaledWidth()/2) w= scaledResolution.getScaledWidth()/2; + + RenderUtils.drawFloatingRectDark(xCenter-w/2, yTop, w, 50); + Utils.renderShadowedString(titleStr, xCenter, yTop+8, scaledResolution.getScaledWidth()/2); + + int ctw = Minecraft.getMinecraft().fontRendererObj.getStringWidth(buttonStr)+8; + + RenderUtils.drawFloatingRectDark(xCenter-ctw/2, yTop+25, ctw, 15); + Utils.renderShadowedString(buttonStr, xCenter, yTop+28, w); + + + + }*/ + + + renderHeight = yTop - yTopStart; + + if(editor != null) { + editor.render(); + } + + super.drawScreen(mouseX, mouseY, partialTicks); + } + + @Override + public void updateScreen() { + if(enchantGlint) { + if(enchantGlintCustomColourAnimation.getTarget() != 17) { + enchantGlintCustomColourAnimation.setTarget(17); + enchantGlintCustomColourAnimation.resetTimer(); + } + } else { + if(enchantGlintCustomColourAnimation.getTarget() != 0) { + enchantGlintCustomColourAnimation.setTarget(0); + enchantGlintCustomColourAnimation.resetTimer(); + } + } + + super.updateScreen(); + } + + @Override + protected void keyTyped(char typedChar, int keyCode) throws IOException { + if(textFieldRename.getFocus()) { + if(keyCode == Keyboard.KEY_ESCAPE) { + textFieldRename.setFocus(false); + return; + } else { + textFieldRename.keyTyped(typedChar, keyCode); + } + } + + super.keyTyped(typedChar, keyCode); + } + + @Override + public void handleKeyboardInput() throws IOException { + if(editor == null || !editor.keyboardInput()) { + if(editor != null && Keyboard.getEventKeyState() && Keyboard.getEventKey() == Keyboard.KEY_ESCAPE) { + editor = null; + } else { + super.handleKeyboardInput(); + } + } + } + + @Override + public void handleMouseInput() throws IOException { + int mouseX = Mouse.getEventX() * this.width / this.mc.displayWidth; + int mouseY = this.height - Mouse.getEventY() * this.height / this.mc.displayHeight - 1; + + if(editor == null || !editor.mouseInput(mouseX, mouseY)) { + super.handleMouseInput(); + enchantGlintButton.mouseInput(mouseX, mouseY); + } + } + + @Override + protected void mouseClickMove(int mouseX, int mouseY, int clickedMouseButton, long timeSinceLastClick) { + textFieldRename.mouseClickMove(mouseX, mouseY, clickedMouseButton, timeSinceLastClick); + } + + @Override + protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException { + ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft()); + int xCenter = scaledResolution.getScaledWidth()/2; + int yTop = (scaledResolution.getScaledHeight()-renderHeight)/2; + + if(mouseX >= xCenter-textFieldRename.getWidth()/2 && mouseX <= xCenter+textFieldRename.getWidth()/2 && + mouseY >= yTop+14 && mouseY <= yTop+14+textFieldRename.getHeight()) { + textFieldRename.mouseClicked(mouseX, mouseY, mouseButton); + } else { + textFieldRename.unfocus(); + } + + if(enchantGlint && mouseX >= xCenter-90 && mouseX <= xCenter+90 && + mouseY >= yTop+174 && mouseY <= yTop+174+enchantGlintCustomColourAnimation.getValue()) { + if(mouseX >= xCenter+90-12) { + editor = null; + customGlintColour = ItemCustomizeManager.DEFAULT_GLINT_COLOR; + updateData(); + } else { + editor = new GuiElementColour(mouseX, mouseY, customGlintColour == null ? ItemCustomizeManager.DEFAULT_GLINT_COLOR : customGlintColour, + (colour) -> { + customGlintColour = colour; + updateData(); + }, () -> editor = null); + } + } + + float belowEnchGlint = yTop+174+enchantGlintCustomColourAnimation.getValue()+5; + + if(supportCustomLeatherColour && mouseX >= xCenter-90 && mouseX <= xCenter+90 && + mouseY >= belowEnchGlint && + mouseY <= belowEnchGlint+15) { + if(mouseX >= xCenter+90-12) { + editor = null; + customLeatherColour = null; + updateData(); + } else { + editor = new GuiElementColour(mouseX, mouseY, + customLeatherColour == null ? getChromaStrFromLeatherColour() : customLeatherColour, + (colour) -> { + customLeatherColour = colour; + updateData(); + }, () -> editor = null, false, true); + } + } + + /*if(mouseX >= xCenter-90 && mouseX <= xCenter+90 && + mouseY >= belowEnchGlint+65 && mouseY <= belowEnchGlint+80) { + if(true) { + String userName = Minecraft.getMinecraft().thePlayer.getName(); + String serverId = "1872398172739"; + try { + Desktop.getDesktop().browse(new URL("https://moulberry.codes/purchaseitemtag?uniqueId="+serverId+"&username="+userName).toURI()); + } catch(Exception ignored) {} + } else { + + } + }*/ + + super.mouseClicked(mouseX, mouseY, mouseButton); + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/InventoryStorageSelector.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/InventoryStorageSelector.java new file mode 100644 index 00000000..010dc3e2 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/InventoryStorageSelector.java @@ -0,0 +1,318 @@ +package io.github.moulberry.notenoughupdates.miscgui; + +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.core.config.KeybindHelper; +import io.github.moulberry.notenoughupdates.miscfeatures.StorageManager; +import io.github.moulberry.notenoughupdates.util.Utils; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.gui.ScaledResolution; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.settings.KeyBinding; +import net.minecraft.init.Blocks; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.client.event.MouseEvent; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.gameevent.InputEvent; +import org.lwjgl.input.Keyboard; +import org.lwjgl.input.Mouse; +import org.lwjgl.opengl.GL11; + +public class InventoryStorageSelector { + + private static final InventoryStorageSelector INSTANCE = new InventoryStorageSelector(); + + private static final ResourceLocation ICONS = new ResourceLocation("notenoughupdates:storage_gui/hotbar_icons.png"); + + public boolean isOverridingSlot = false; + public int selectedIndex = 0; + + public static InventoryStorageSelector getInstance() { + return INSTANCE; + } + + public boolean isSlotSelected() { + if(!NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard() || !NotEnoughUpdates.INSTANCE.config.storageGUI.showInvBackpack) { + isOverridingSlot = false; + return false; + } + if(Minecraft.getMinecraft().currentScreen != null) { + isOverridingSlot = false; + return false; + } + if(Minecraft.getMinecraft().thePlayer == null) { + isOverridingSlot = false; + return false; + } + if(Minecraft.getMinecraft().thePlayer.inventory.currentItem != 0) { + isOverridingSlot = false; + return false; + } + return isOverridingSlot; + } + + @SubscribeEvent + public void onMousePress(MouseEvent event) { + if(!NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard() || !NotEnoughUpdates.INSTANCE.config.storageGUI.showInvBackpack) { + return; + } + + if(KeybindHelper.isKeyPressed(NotEnoughUpdates.INSTANCE.config.storageGUI.arrowLeftKey)) { + selectedIndex--; + + int max = StorageManager.getInstance().storageConfig.displayToStorageIdMap.size()-1; + if(selectedIndex > max) selectedIndex = max; + if(selectedIndex < 0) selectedIndex = 0; + } else if(KeybindHelper.isKeyPressed(NotEnoughUpdates.INSTANCE.config.storageGUI.arrowRightKey)) { + selectedIndex++; + + int max = StorageManager.getInstance().storageConfig.displayToStorageIdMap.size()-1; + if(selectedIndex > max) selectedIndex = max; + if(selectedIndex < 0) selectedIndex = 0; + } else if(KeybindHelper.isKeyPressed(NotEnoughUpdates.INSTANCE.config.storageGUI.arrowDownKey)) { + sendToPage(selectedIndex); + } + + if(isSlotSelected()) { + int useKeycode = Minecraft.getMinecraft().gameSettings.keyBindUseItem.getKeyCode() + 100; + int attackKeycode = Minecraft.getMinecraft().gameSettings.keyBindAttack.getKeyCode() + 100; + + if(Mouse.getEventButton() == useKeycode || Mouse.getEventButton() == attackKeycode) { + if(Mouse.getEventButtonState() && + Mouse.getEventButton() != NotEnoughUpdates.INSTANCE.config.storageGUI.backpackScrollKey+100) { + sendToPage(selectedIndex); + } + + event.setCanceled(true); + } + } + } + + private void sendToPage(int displayId) { + if(!StorageManager.getInstance().storageConfig.displayToStorageIdMap.containsKey(displayId)) { + return; + } + if(getPage(selectedIndex) == null) { + NotEnoughUpdates.INSTANCE.sendChatMessage("/storage"); + } else { + int index = StorageManager.getInstance().storageConfig.displayToStorageIdMap.get(selectedIndex); + StorageManager.getInstance().sendToPage(index); + } + } + + @SubscribeEvent + public void onKeyPress(InputEvent.KeyInputEvent event) { + if(Minecraft.getMinecraft().gameSettings.keyBindsHotbar[0].isKeyDown()) { + isOverridingSlot = false; + } + + if(!NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard() || !NotEnoughUpdates.INSTANCE.config.storageGUI.showInvBackpack) { + return; + } + + if(KeybindHelper.isKeyPressed(NotEnoughUpdates.INSTANCE.config.storageGUI.arrowLeftKey)) { + selectedIndex--; + + int max = StorageManager.getInstance().storageConfig.displayToStorageIdMap.size()-1; + if(selectedIndex > max) selectedIndex = max; + if(selectedIndex < 0) selectedIndex = 0; + } else if(KeybindHelper.isKeyPressed(NotEnoughUpdates.INSTANCE.config.storageGUI.arrowRightKey)) { + selectedIndex++; + + int max = StorageManager.getInstance().storageConfig.displayToStorageIdMap.size()-1; + if(selectedIndex > max) selectedIndex = max; + if(selectedIndex < 0) selectedIndex = 0; + } else if(KeybindHelper.isKeyPressed(NotEnoughUpdates.INSTANCE.config.storageGUI.arrowDownKey)) { + sendToPage(selectedIndex); + } + + if(isSlotSelected()) { + KeyBinding attack = Minecraft.getMinecraft().gameSettings.keyBindAttack; + KeyBinding use = Minecraft.getMinecraft().gameSettings.keyBindUseItem; + + if(attack.isPressed() || attack.isKeyDown()) { + if(attack.getKeyCode() != NotEnoughUpdates.INSTANCE.config.storageGUI.backpackScrollKey) { + sendToPage(selectedIndex); + } + + KeyBinding.setKeyBindState(attack.getKeyCode(), false); + while(attack.isPressed()){} + } + + if(use.isPressed() || use.isKeyDown()) { + if(attack.getKeyCode() != NotEnoughUpdates.INSTANCE.config.storageGUI.backpackScrollKey) { + sendToPage(selectedIndex); + } + + KeyBinding.setKeyBindState(use.getKeyCode(), false); + while(use.isPressed()){} + } + } + } + + public int onScroll(int direction, int resultantSlot) { + if(!NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard() || !NotEnoughUpdates.INSTANCE.config.storageGUI.showInvBackpack) { + return resultantSlot; + } + + int keyCode = NotEnoughUpdates.INSTANCE.config.storageGUI.backpackScrollKey; + if(isOverridingSlot && KeybindHelper.isKeyDown(keyCode)) { + selectedIndex -= direction; + int max = StorageManager.getInstance().storageConfig.displayToStorageIdMap.size()-1; + + if(selectedIndex > max) selectedIndex = max; + if(selectedIndex < 0) selectedIndex = 0; + return 0; + } + + if(resultantSlot == 0 && direction == -1 && !isOverridingSlot) { + isOverridingSlot = true; + Minecraft.getMinecraft().getItemRenderer().resetEquippedProgress(); + return 0; + } else if(resultantSlot == 1 && direction == -1 && isOverridingSlot) { + isOverridingSlot = false; + Minecraft.getMinecraft().getItemRenderer().resetEquippedProgress(); + return 0; + } else if(resultantSlot == 8 && direction == 1 && !isOverridingSlot) { + isOverridingSlot = true; + Minecraft.getMinecraft().getItemRenderer().resetEquippedProgress(); + return 0; + } + return resultantSlot; + } + + private StorageManager.StoragePage getPage(int selectedIndex) { + if(!StorageManager.getInstance().storageConfig.displayToStorageIdMap.containsKey(selectedIndex)) { + return null; + } + int index = StorageManager.getInstance().storageConfig.displayToStorageIdMap.get(selectedIndex); + return StorageManager.getInstance().getPage(index, false); + } + + public ItemStack getNamedHeldItemOverride() { + StorageManager.StoragePage page = getPage(selectedIndex); + if(page != null && page.backpackDisplayStack != null) { + return page.backpackDisplayStack; + } + return new ItemStack(Item.getItemFromBlock(Blocks.chest)); + } + + public ItemStack getHeldItemOverride() { + return getHeldItemOverride(selectedIndex); + } + + public ItemStack getHeldItemOverride(int selectedIndex) { + StorageManager.StoragePage page = getPage(selectedIndex); + if(page != null) { + ItemStack stack = page.backpackDisplayStack; + if(stack == null || stack.getItem() == Item.getItemFromBlock(Blocks.stained_glass_pane)) { + return new ItemStack(Item.getItemFromBlock(Blocks.ender_chest)); + } + return stack; + } + return new ItemStack(Item.getItemFromBlock(Blocks.chest)); + } + + public void render(ScaledResolution scaledResolution, float partialTicks) { + if(!NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard() || !NotEnoughUpdates.INSTANCE.config.storageGUI.showInvBackpack) { + return; + } + + int max = StorageManager.getInstance().storageConfig.displayToStorageIdMap.size()-1; + if(selectedIndex > max) selectedIndex = max; + if(selectedIndex < 0) selectedIndex = 0; + + int width = scaledResolution.getScaledWidth(); + int height = scaledResolution.getScaledHeight(); + FontRenderer fontRendererObj = Minecraft.getMinecraft().fontRendererObj; + int centerX = width / 2; + + int offset = 91 + 10 + 12; + + if(NotEnoughUpdates.INSTANCE.config.storageGUI.backpackHotbarSide == 1) { + offset *= -1; + } + + ItemStack held = getHeldItemOverride(); + int left = centerX - offset - 12; + int top = scaledResolution.getScaledHeight() - 22; + + if(NotEnoughUpdates.INSTANCE.config.storageGUI.showInvBackpackPreview && isSlotSelected()) { + StorageManager.StoragePage page = getPage(selectedIndex); + + if(page != null && page.rows > 0) { + int rows = page.rows; + + ResourceLocation storagePreviewTexture = StorageOverlay.STORAGE_PREVIEW_TEXTURES[NotEnoughUpdates.INSTANCE.config.storageGUI.displayStyle]; + + int startX = centerX - 172/2; + int startY = height - 70 - (10+18*rows); + + GlStateManager.translate(0, 0, 100); + GL11.glDepthMask(false); + + Minecraft.getMinecraft().getTextureManager().bindTexture(storagePreviewTexture); + GlStateManager.color(1, 1, 1, + NotEnoughUpdates.INSTANCE.config.storageGUI.backpackOpacity/100f); + Utils.drawTexturedRect(startX, startY, 176, 7, 0, 1, 0, 7/32f, GL11.GL_NEAREST); + for(int i=0; i<rows; i++) { + Utils.drawTexturedRect(startX, startY+7+18*i, 176, 18, 0, 1, 7/32f, 25/32f, GL11.GL_NEAREST); + } + Utils.drawTexturedRect(startX, startY+7+18*rows, 176, 7, 0, 1, 25/32f, 1, GL11.GL_NEAREST); + + GL11.glDepthMask(true); + + for(int i=0; i<rows*9; i++) { + ItemStack stack = page.items[i]; + if(stack != null) { + Utils.drawItemStack(stack, startX+8+18*(i%9), startY+8+18*(i/9)); + } + } + + ItemStack named = getNamedHeldItemOverride(); + + Utils.drawItemStack(held, centerX-8, startY-8); + + GlStateManager.translate(0, 0, 100); + Utils.drawStringCentered(named.getDisplayName(), fontRendererObj, centerX, height - 66, true, 0xffff0000); + int keyCode = NotEnoughUpdates.INSTANCE.config.storageGUI.backpackScrollKey; + if(KeybindHelper.isKeyValid(keyCode) && !KeybindHelper.isKeyDown(keyCode)) { + String keyName = KeybindHelper.getKeyName(keyCode); + Utils.drawStringCentered("["+keyName+"] Scroll Backpacks", fontRendererObj, centerX, startY-10, true, 0xff32CD32); + } + GlStateManager.translate(0, 0, -200); + + } else if(page == null) { + Utils.drawStringCentered("Run /storage to enable this feature!", fontRendererObj, centerX, height - 80, true, 0xffff0000); + } else { + Utils.drawStringCentered("Right-click to load items", fontRendererObj, centerX, height - 80, true, 0xffff0000); + } + } + + Minecraft.getMinecraft().getTextureManager().bindTexture(ICONS); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(left + 1, top, + 22, 22, 0, 22/64f, 0, 22/64f, GL11.GL_NEAREST); + if(isSlotSelected()) { + Utils.drawTexturedRect(left, top - 1, + 24, 22, 0, 24/64f, 22/64f, 44/64f, GL11.GL_NEAREST); + } + + int index = 1; + if(StorageManager.getInstance().storageConfig.displayToStorageIdMap.containsKey(selectedIndex)) { + int displayIndex = StorageManager.getInstance().storageConfig.displayToStorageIdMap.get(selectedIndex); + if(displayIndex < 9) { + index = displayIndex+1; + } else { + index = displayIndex-8; + } + } + + Utils.drawItemStackWithText(held, left + 4, top + 3, ""+index); + + GlStateManager.enableBlend(); + } + +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/StorageOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/StorageOverlay.java new file mode 100644 index 00000000..f22ed9ae --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/StorageOverlay.java @@ -0,0 +1,1026 @@ +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.util.lerp.LerpingInteger; +import io.github.moulberry.notenoughupdates.core.util.render.RenderUtils; +import io.github.moulberry.notenoughupdates.miscfeatures.StorageManager; +import io.github.moulberry.notenoughupdates.util.Utils; +import net.minecraft.client.Minecraft; +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.renderer.GlStateManager; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.init.Blocks; +import net.minecraft.inventory.Container; +import net.minecraft.inventory.ContainerChest; +import net.minecraft.inventory.Slot; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumChatFormatting; +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.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.awt.*; +import java.util.List; +import java.util.Map; + +public class StorageOverlay extends GuiElement { + + private static final int CHEST_TOP_OFFSET = 17; + private static final int CHEST_SLOT_SIZE = 18; + private static final int CHEST_BOTTOM_OFFSET = 215; + + 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"); + private static final ResourceLocation[] LOAD_CIRCLE_SEQ = new ResourceLocation[11]; + static { + for(int i=0; i<STORAGE_TEXTURES.length; i++) { + STORAGE_TEXTURES[i] = new ResourceLocation("notenoughupdates:storage_gui/storage_gui_"+i+".png"); + } + for(int i=0; i<STORAGE_PREVIEW_TEXTURES.length; i++) { + STORAGE_PREVIEW_TEXTURES[i] = new ResourceLocation("notenoughupdates:storage_gui/storage_preview_"+i+".png"); + } + + LOAD_CIRCLE_SEQ[0] = new ResourceLocation("notenoughupdates:loading_circle_seq/1.png"); + LOAD_CIRCLE_SEQ[1] = new ResourceLocation("notenoughupdates:loading_circle_seq/1.png"); + LOAD_CIRCLE_SEQ[2] = new ResourceLocation("notenoughupdates:loading_circle_seq/2.png"); + for(int i=2; i<=7; i++) { + LOAD_CIRCLE_SEQ[i+1] = new ResourceLocation("notenoughupdates:loading_circle_seq/"+i+".png"); + } + LOAD_CIRCLE_SEQ[9] = new ResourceLocation("notenoughupdates:loading_circle_seq/7.png"); + LOAD_CIRCLE_SEQ[10] = new ResourceLocation("notenoughupdates:loading_circle_seq/1.png"); + } + + private static final StorageOverlay INSTANCE = new StorageOverlay(); + public static StorageOverlay getInstance() { + return INSTANCE; + } + + private GuiElementTextField searchBar = new GuiElementTextField("", 88, 10, + GuiElementTextField.SCALE_TEXT | GuiElementTextField.DISABLE_BG); + + private int guiLeft; + private int guiTop; + + private int loadCircleIndex = 0; + private int loadCircleRotation = 0; + + private long millisAccumIndex = 0; + private long millisAccumRotation = 0; + + private long lastMillis = 0; + + private int scrollVelocity = 0; + private long lastScroll = 0; + + private int desiredHeightSwitch = -1; + private int desiredHeightMX = -1; + private int desiredHeightMY = -1; + + private int scrollGrabOffset = -1; + + private LerpingInteger scroll = new LerpingInteger(0, 200); + + private int getMaximumScroll() { + synchronized(StorageManager.getInstance().storageConfig.displayToStorageIdMap) { + int lastDisplayId = StorageManager.getInstance().storageConfig.displayToStorageIdMap.size()-1; + int coords = (int)Math.ceil(lastDisplayId/3f)*3+3; + + return getPageCoords(coords).y+scroll.getValue()-getStorageViewSize()-14; + } + } + + private void scrollToY(int y) { + int target = y; + if(target < 0) target = 0; + + int maxY = getMaximumScroll(); + if(target > maxY) target = maxY; + + float factor = (scroll.getValue()-target)/(float)(scroll.getValue()-y+1E-5); + + scroll.setTarget(target); + scroll.setTimeToReachTarget(Math.min(200, Math.max(20, (int)(200*factor)))); + scroll.resetTimer(); + } + + public void scrollToStorage(int displayId, boolean forceScroll) { + if(displayId < 0) return; + + int y = getPageCoords(displayId).y-17; + if(y < 3) { + scrollToY(y + scroll.getValue()); + } else { + int storageViewSize = getStorageViewSize(); + int y2 = getPageCoords(displayId+3).y-17-storageViewSize; + if(y2 > 3) { + if(forceScroll) { + scrollToY(y + scroll.getValue()); + } else { + scrollToY(y2+scroll.getValue()); + } + } + } + } + + private int getStorageViewSize() { + return NotEnoughUpdates.INSTANCE.config.storageGUI.storageHeight; + } + + private int getScrollBarHeight() { + return getStorageViewSize() - 21; + } + + @Override + public void render() { + if(!(Minecraft.getMinecraft().currentScreen instanceof GuiChest)) return; + + 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; + FontRenderer fontRendererObj = Minecraft.getMinecraft().fontRendererObj; + + scroll.tick(); + + int displayStyle = NotEnoughUpdates.INSTANCE.config.storageGUI.displayStyle; + ResourceLocation storageTexture = STORAGE_TEXTURES[displayStyle]; + ResourceLocation storagePreviewTexture = STORAGE_PREVIEW_TEXTURES[displayStyle]; + int textColour = 0x404040; + int searchTextColour = 0xe0e0e0; + if(displayStyle == 2) { + textColour = 0x000000; + searchTextColour = 0xa0a0a0; + } else if(displayStyle == 3) { + textColour = 0xFBCC6C; + } else if(displayStyle == 0) { + textColour = 0x909090; + searchTextColour = 0xa0a0a0; + } + + long currentTime = System.currentTimeMillis(); + if(lastMillis > 0) { + long deltaTime = currentTime - lastMillis; + millisAccumIndex += deltaTime; + loadCircleIndex += millisAccumIndex / (1000/15); + millisAccumIndex %= (1000/15); + + millisAccumRotation += deltaTime; + loadCircleRotation += millisAccumRotation / (1000/107); + millisAccumRotation %= (1000/107); + } + + lastMillis = currentTime; + loadCircleIndex %= LOAD_CIRCLE_SEQ.length; + loadCircleRotation %= 360; + + Color loadCircleColour = Color.getHSBColor(loadCircleRotation/360f, 0.3f, 0.9f); + ItemStack stackOnMouse = Minecraft.getMinecraft().thePlayer.inventory.getItemStack(); + if(stackOnMouse != null) { + String stackDisplay = Utils.cleanColour(stackOnMouse.getDisplayName()); + if(stackDisplay.startsWith("Backpack Slot ") || stackDisplay.startsWith("Empty Backpack Slot ") || + stackDisplay.startsWith("Ender Chest Page ")) { + stackOnMouse = null; + } + } + + List<String> tooltipToDisplay = null; + int slotPreview = -1; + + int storageViewSize = getStorageViewSize(); + + int sizeX = 540; + int sizeY = 100+storageViewSize; + int searchNobX = 18; + + int itemHoverX = -1; + int itemHoverY = -1; + + guiLeft = width/2 - (sizeX-searchNobX)/2; + guiTop = height/2 - sizeY/2; + + if(displayStyle == 0) { + BackgroundBlur.renderBlurredBackground(7, width, height, guiLeft, guiTop, sizeX, storageViewSize); + BackgroundBlur.renderBlurredBackground(7, width, height, guiLeft+5, guiTop+storageViewSize, sizeX-searchNobX-10, sizeY-storageViewSize-4); + } + + Utils.drawGradientRect(0, 0, width, height, 0xc0101010, 0xd0101010); + + GL11.glPushMatrix(); + GlStateManager.translate(guiLeft, guiTop, 0); + + boolean hoveringOtherBackpack = false; + + //Gui + Minecraft.getMinecraft().getTextureManager().bindTexture(storageTexture); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(0, 0, sizeX, 10, 0, sizeX/600f, 0, 10/400f, GL11.GL_NEAREST); + Utils.drawTexturedRect(0, 10, sizeX, storageViewSize-20, 0, sizeX/600f, 10/400f, 94/400f, GL11.GL_NEAREST); + Utils.drawTexturedRect(0, storageViewSize-10, sizeX, 110, 0, sizeX/600f, 94/400f, 204/400f, GL11.GL_NEAREST); + + int maxScroll = getMaximumScroll(); + if(scroll.getValue() > maxScroll) { + scroll.setValue(maxScroll); + } + if(scroll.getValue() < 0) { + scroll.setValue(0); + } + + //Scroll bar + int scrollBarY = Math.round(getScrollBarHeight()*scroll.getValue()/(float)maxScroll); + float uMin = scrollGrabOffset >= 0 ? 12/600f : 0; + Utils.drawTexturedRect(520, 8+scrollBarY, 12, 15, uMin, uMin+12/600f, 250/400f, 265/400f, GL11.GL_NEAREST); + + int currentPage = StorageManager.getInstance().getCurrentPageId(); + + boolean mouseInsideStorages = mouseY > guiTop+3 && mouseY < guiTop+3+storageViewSize; + + //Storages + 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(); + int storageId = entry.getValue(); + + IntPair coords = getPageCoords(displayId); + int storageX = coords.x; + int storageY = coords.y; + + if(coords.y-11 > 3+storageViewSize || coords.y+90 < 3) continue; + + if(storageId < 9) { + fontRendererObj.drawString("Ender Chest Page "+(storageId+1), storageX, storageY-11, textColour); + } else { + fontRendererObj.drawString("Backpack Slot "+(storageId-8), storageX, storageY-11, textColour); + } + + StorageManager.StoragePage page = StorageManager.getInstance().getPage(storageId, false); + if(page == null) { + Minecraft.getMinecraft().getTextureManager().bindTexture(storageTexture); + GlStateManager.color(1, 1, 1, 1); + int h = 18*3; + + Utils.drawTexturedRect(storageX, storageY, 162, h, 0, 162 / 600f, 265 / 400f, (265+h) / 400f, GL11.GL_NEAREST); + + Gui.drawRect(storageX, storageY, storageX + 162, storageY + h, 0x80000000); + + if(storageId < 9) { + Utils.drawStringCenteredScaledMaxWidth("Locked Page", fontRendererObj, + storageX+81, storageY+h/2, true, 150, 0xd94c00); + } else { + Utils.drawStringCenteredScaledMaxWidth("Empty Backpack Slot", fontRendererObj, + storageX+81, storageY+h/2, true, 150, 0xd94c00); + } + } else if(page.rows <= 0) { + Minecraft.getMinecraft().getTextureManager().bindTexture(storageTexture); + GlStateManager.color(1, 1, 1, 1); + int h = 18*3; + + Utils.drawTexturedRect(storageX, storageY, 162, h, 0, 162 / 600f, 265 / 400f, (265 + h) / 400f, GL11.GL_NEAREST); + + Gui.drawRect(storageX, storageY, storageX + 162, storageY + h, 0x80000000); + + Utils.drawStringCenteredScaledMaxWidth("Click to load items", fontRendererObj, + storageX+81, storageY+h/2, true, 150, 0xffdf00); + } else { + int rows = page.rows; + + int storageW = 162; + int storageH = 18*rows; + + Minecraft.getMinecraft().getTextureManager().bindTexture(storageTexture); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(storageX, storageY, storageW, storageH, 0, 162/600f, 265/400f, (265+storageH)/400f, GL11.GL_NEAREST); + + boolean whiteOverlay = false; + + GlStateManager.enableDepth(); + for(int k=0; k<rows*9; k++) { + 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(!searchBar.getText().isEmpty()) { + if(stack == null || !NotEnoughUpdates.INSTANCE.manager.doesStackMatchSearch(stack, searchBar.getText())) { + GlStateManager.disableDepth(); + Gui.drawRect(itemX, itemY, itemX+16, itemY+16, 0x80000000); + GlStateManager.enableDepth(); + } + } + + GlStateManager.disableLighting(); + + if(mouseInsideStorages && mouseX >= guiLeft+itemX && mouseX < guiLeft+itemX+18 && mouseY >= guiTop+itemY && mouseY < guiTop+itemY+18) { + if(storageId != StorageManager.getInstance().getCurrentPageId()) { + hoveringOtherBackpack = true; + whiteOverlay = stackOnMouse == null; + } else { + itemHoverX = itemX; + itemHoverY = itemY; + } + + if(stack != null) { + tooltipToDisplay = stack.getTooltip(Minecraft.getMinecraft().thePlayer, Minecraft.getMinecraft().gameSettings.advancedItemTooltips); + } + } + } + + GlStateManager.disableDepth(); + if(storageId == currentPage) { + Gui.drawRect(storageX+1, storageY, storageX, storageY+storageH, 0xffffdf00); + Gui.drawRect(storageX+storageW-1, storageY, storageX+storageW, storageY+storageH, 0xffffdf00); + Gui.drawRect(storageX, storageY, storageX+storageW, storageY+1, 0xffffdf00); + Gui.drawRect(storageX, storageY+storageH-1, storageX+storageW, storageY+storageH, 0xffffdf00); + } else if(currentTime - StorageManager.getInstance().storageOpenSwitchMillis < 1000 && + StorageManager.getInstance().desiredStoragePage == storageId && + StorageManager.getInstance().getCurrentPageId() != storageId) { + Gui.drawRect(storageX, storageY, storageX+storageW, storageY+storageH, 0x30000000); + + Minecraft.getMinecraft().getTextureManager().bindTexture(LOAD_CIRCLE_SEQ[loadCircleIndex]); + GlStateManager.color(loadCircleColour.getRed()/255f, loadCircleColour.getGreen()/255f, + loadCircleColour.getBlue()/255f, 1); + + GlStateManager.pushMatrix(); + GlStateManager.translate(storageX+storageW/2, storageY+storageH/2, 0); + GlStateManager.rotate(loadCircleRotation, 0, 0, 1); + Utils.drawTexturedRect(-10, -10, 20, 20, GL11.GL_LINEAR); + GlStateManager.popMatrix(); + } else if(whiteOverlay) { + Gui.drawRect(storageX, storageY, storageX+storageW, storageY+storageH, 0x80ffffff); + } else { + Gui.drawRect(storageX, storageY, storageX+storageW, storageY+storageH, 0x30000000); + } + GlStateManager.enableDepth(); + } + } + GlScissorStack.pop(scaledResolution); + + //Inventory Text + fontRendererObj.drawString("Inventory", 180, storageViewSize+6, textColour); + searchBar.setCustomTextColour(searchTextColour); + searchBar.render(252, storageViewSize+5); + + //Player Inventory + GuiChest guiChest = (GuiChest) Minecraft.getMinecraft().currentScreen; + ContainerChest containerChest = (ContainerChest) guiChest.inventorySlots; + ItemStack[] playerItems = Minecraft.getMinecraft().thePlayer.inventory.mainInventory; + int inventoryStartIndex = containerChest.getLowerChestInventory().getSizeInventory(); + GlStateManager.enableDepth(); + for(int i=0; i<9; i++) { + 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)); + GlStateManager.popMatrix(); + + if(!searchBar.getText().isEmpty()) { + if(playerItems[i] == null || !NotEnoughUpdates.INSTANCE.manager.doesStackMatchSearch(playerItems[i], searchBar.getText())) { + GlStateManager.disableDepth(); + Gui.drawRect(itemX, itemY, itemX+16, itemY+16, 0x80000000); + GlStateManager.enableDepth(); + } + } + + if(mouseX >= guiLeft+itemX && mouseX < guiLeft+itemX+18 && mouseY >= guiTop+itemY && mouseY < guiTop+itemY+18) { + itemHoverX = itemX; + itemHoverY = itemY; + + if(playerItems[i] != null) { + tooltipToDisplay = playerItems[i].getTooltip(Minecraft.getMinecraft().thePlayer, Minecraft.getMinecraft().gameSettings.advancedItemTooltips); + } + } + } + for(int i=0; i<27; i++) { + int itemX = 181+18*(i%9); + int itemY = storageViewSize+18+18*(i/9); + + //Utils.drawItemStack(playerItems[i+9], itemX, itemY); + GlStateManager.pushMatrix(); + GlStateManager.translate(181-8, storageViewSize+18-(inventoryStartIndex/9*18+31), 0); + guiChest.drawSlot(containerChest.inventorySlots.get(inventoryStartIndex+9+i)); + GlStateManager.popMatrix(); + + if(!searchBar.getText().isEmpty()) { + if(playerItems[i+9] == null || !NotEnoughUpdates.INSTANCE.manager.doesStackMatchSearch(playerItems[i+9], searchBar.getText())) { + GlStateManager.disableDepth(); + Gui.drawRect(itemX, itemY, itemX+16, itemY+16, 0x80000000); + GlStateManager.enableDepth(); + } + } + + if(mouseX >= guiLeft+itemX && mouseX < guiLeft+itemX+18 && mouseY >= guiTop+itemY && mouseY < guiTop+itemY+18) { + itemHoverX = itemX; + itemHoverY = itemY; + + if(playerItems[i+9] != null) { + tooltipToDisplay = playerItems[i+9].getTooltip(Minecraft.getMinecraft().thePlayer, Minecraft.getMinecraft().gameSettings.advancedItemTooltips); + } + } + } + + //Backpack Selector + fontRendererObj.drawString("Ender Chest Pages", 9, storageViewSize+12, textColour); + fontRendererObj.drawString("Storage Pages", 9, storageViewSize+44, textColour); + if(StorageManager.getInstance().onStorageMenu) { + for(int i=0; i<9; i++) { + int itemX = 10+i*18; + int itemY = storageViewSize+24; + ItemStack stack = containerChest.getLowerChestInventory().getStackInSlot(i+9); + Utils.drawItemStack(stack, itemX, itemY); + + if(mouseX >= guiLeft+itemX && mouseX < guiLeft+itemX+18 && mouseY >= guiTop+itemY && mouseY < guiTop+itemY+18) { + itemHoverX = itemX; + itemHoverY = itemY; + + if(stack != null) { + if(NotEnoughUpdates.INSTANCE.config.storageGUI.enderchestPreview) slotPreview = i; + tooltipToDisplay = stack.getTooltip(Minecraft.getMinecraft().thePlayer, Minecraft.getMinecraft().gameSettings.advancedItemTooltips); + } + } + } + for(int i=0; i<18; i++) { + int itemX = 10+18*(i%9); + int itemY = storageViewSize+56+18*(i/9); + ItemStack stack = containerChest.getLowerChestInventory().getStackInSlot(i+27); + Utils.drawItemStack(stack, itemX, itemY); + + if(mouseX >= guiLeft+itemX && mouseX < guiLeft+itemX+18 && mouseY >= guiTop+itemY && mouseY < guiTop+itemY+18) { + itemHoverX = itemX; + itemHoverY = itemY; + + if(stack != null) { + if(NotEnoughUpdates.INSTANCE.config.storageGUI.backpackPreview) slotPreview = i+StorageManager.MAX_ENDER_CHEST_PAGES; + tooltipToDisplay = stack.getTooltip(Minecraft.getMinecraft().thePlayer, Minecraft.getMinecraft().gameSettings.advancedItemTooltips); + } + } + } + } else { + for(int i=0; i<9; i++) { + StorageManager.StoragePage page = StorageManager.getInstance().getPage(i, false); + int itemX = 10+(i%9)*18; + int itemY = storageViewSize+24+(i/9)*18; + + ItemStack stack; + if(page != null && page.backpackDisplayStack != null) { + stack = page.backpackDisplayStack; + } else { + stack = StorageManager.LOCKED_ENDERCHEST_STACK; + } + + if(stack != null) { + Utils.drawItemStack(stack, itemX, itemY); + + if(mouseX >= guiLeft+itemX && mouseX < guiLeft+itemX+18 && mouseY >= guiTop+itemY && mouseY < guiTop+itemY+18) { + itemHoverX = itemX; + itemHoverY = itemY; + if(NotEnoughUpdates.INSTANCE.config.storageGUI.enderchestPreview) slotPreview = i; + tooltipToDisplay = stack.getTooltip(Minecraft.getMinecraft().thePlayer, Minecraft.getMinecraft().gameSettings.advancedItemTooltips); + } + } + } + for(int i=0; i<18; i++) { + StorageManager.StoragePage page = StorageManager.getInstance().getPage(i+StorageManager.MAX_ENDER_CHEST_PAGES, false); + int itemX = 10+(i%9)*18; + int itemY = storageViewSize+56+(i/9)*18; + + ItemStack stack; + if(page != null && page.backpackDisplayStack != null) { + stack = page.backpackDisplayStack; + } else { + stack = StorageManager.getInstance().getMissingBackpackStack(i); + } + + if(stack != null) { + Utils.drawItemStack(stack, itemX, itemY); + + if(mouseX >= guiLeft+itemX && mouseX < guiLeft+itemX+18 && mouseY >= guiTop+itemY && mouseY < guiTop+itemY+18) { + itemHoverX = itemX; + itemHoverY = itemY; + if(NotEnoughUpdates.INSTANCE.config.storageGUI.backpackPreview) slotPreview = i+StorageManager.MAX_ENDER_CHEST_PAGES; + tooltipToDisplay = stack.getTooltip(Minecraft.getMinecraft().thePlayer, Minecraft.getMinecraft().gameSettings.advancedItemTooltips); + } + } + } + } + + //Buttons + Minecraft.getMinecraft().getTextureManager().bindTexture(STORAGE_ICONS_TEXTURE); + GlStateManager.color(1, 1, 1, 1); + for(int i=0; i<10; i++) { + int buttonX = 388+(i%5)*18; + int buttonY = getStorageViewSize()+35+(i/5)*18; + + float minU = (i*16)/256f; + float maxU = (i*16+16)/256f; + + int vIndex = 0; + + switch(i) { + case 2: + vIndex = NotEnoughUpdates.INSTANCE.config.storageGUI.displayStyle; break; + case 3: + vIndex = NotEnoughUpdates.INSTANCE.config.storageGUI.backpackPreview ? 1 : 0; break; + case 4: + vIndex = NotEnoughUpdates.INSTANCE.config.storageGUI.enderchestPreview ? 1 : 0; break; + } + + Utils.drawTexturedRect(buttonX, buttonY, 16, 16, minU, maxU, (vIndex*16)/256f, (vIndex*16+16)/256f, GL11.GL_NEAREST); + + if(mouseX >= guiLeft+buttonX && mouseX < guiLeft+buttonX+18 && + mouseY >= guiTop+buttonY && mouseY < guiTop+buttonY+18) { + switch(i) { + case 0: + tooltipToDisplay = createTooltip( + "Enable GUI", + 0, + "On", + "Off" + ); break; + case 1: + int tooltipStorageHeight = desiredHeightSwitch != -1 ? desiredHeightSwitch : + NotEnoughUpdates.INSTANCE.config.storageGUI.storageHeight; + tooltipToDisplay = createTooltip( + "Storage View Height", + Math.round((tooltipStorageHeight-104)/52f), + "Tiny", + "Small", + "Medium", + "Large", + "Huge" + ); + if(desiredHeightSwitch != -1) { + tooltipToDisplay.add(""); + tooltipToDisplay.add(EnumChatFormatting.YELLOW+"* Move mouse to apply changes *"); + } + break; + case 2: + tooltipToDisplay = createTooltip( + "Overlay Style", + NotEnoughUpdates.INSTANCE.config.storageGUI.displayStyle, + "Transparent", + "Minecraft", + "Dark", + "Custom" + ); + break; + case 3: + tooltipToDisplay = createTooltip( + "Backpack Preview", + NotEnoughUpdates.INSTANCE.config.storageGUI.backpackPreview ? 0 : 1, + "On", + "Off" + ); + break; + case 4: + tooltipToDisplay = createTooltip( + "Enderchest Preview", + NotEnoughUpdates.INSTANCE.config.storageGUI.enderchestPreview ? 0 : 1, + "On", + "Off" + ); + break; + } + } + } + + if(itemHoverX >= 0 && itemHoverY >= 0) { + GlStateManager.disableDepth(); + GlStateManager.colorMask(true, true, true, false); + Gui.drawRect(itemHoverX, itemHoverY, itemHoverX + 16, itemHoverY + 16, 0x80ffffff); + GlStateManager.colorMask(true, true, true, true); + GlStateManager.enableDepth(); + } + + GlStateManager.popMatrix(); + GlStateManager.translate(0, 0, 100); + if(stackOnMouse != null) { + if(hoveringOtherBackpack) { + Utils.drawItemStack(new ItemStack(Item.getItemFromBlock(Blocks.barrier)), mouseX - 8, mouseY - 8); + } else { + Utils.drawItemStack(stackOnMouse, mouseX - 8, mouseY - 8); + } + } else if(slotPreview >= 0) { + StorageManager.StoragePage page = StorageManager.getInstance().getPage(slotPreview, false); + + if(page != null && page.rows > 0) { + int rows = page.rows; + + 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++) { + Utils.drawTexturedRect(mouseX, mouseY+7+18*i, 176, 18, 0, 1, 7/32f, 25/32f, GL11.GL_NEAREST); + } + Utils.drawTexturedRect(mouseX, mouseY+7+18*rows, 176, 7, 0, 1, 25/32f, 1, GL11.GL_NEAREST); + + for(int i=0; i<rows*9; i++) { + ItemStack stack = page.items[i]; + if(stack != null) { + Utils.drawItemStack(stack, mouseX+8+18*(i%9), mouseY+8+18*(i/9)); + } + } + GlStateManager.translate(0, 0, -100); + } else { + Utils.drawHoveringText(tooltipToDisplay, mouseX, mouseY, width, height, -1, Minecraft.getMinecraft().fontRendererObj); + } + } else if(tooltipToDisplay != null) { + Utils.drawHoveringText(tooltipToDisplay, mouseX, mouseY, width, height, -1, Minecraft.getMinecraft().fontRendererObj); + } + GlStateManager.translate(0, 0, -100); + } + + private List<String> createTooltip(String title, int selectedOption, String... options) { + String selPrefix = EnumChatFormatting.DARK_AQUA + " \u25b6 "; + String unselPrefix = EnumChatFormatting.GRAY.toString(); + + for(int i=0; i<options.length; i++) { + if(i == selectedOption) { + options[i] = selPrefix + options[i]; + } else { + options[i] = unselPrefix + options[i]; + } + } + + List list = Lists.newArrayList(options); + list.add(0, ""); + list.add(0, EnumChatFormatting.GREEN+title); + return list; + } + + private static class IntPair { + int x; + int y; + + public IntPair(int x, int y) { + this.x = x; + this.y = y; + } + } + + public IntPair getPageCoords(int displayId) { + if(displayId < 0) displayId = 0; + + int 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(!StorageManager.getInstance().storageConfig.displayToStorageIdMap.containsKey(j)) { + continue; + } + int storageId = StorageManager.getInstance().storageConfig.displayToStorageIdMap.get(j); + StorageManager.StoragePage page = StorageManager.getInstance().getPage(storageId, false); + if(page == null || page.rows <= 0) { + maxRows = Math.max(maxRows, 3); + } else { + maxRows = Math.max(maxRows, page.rows); + } + } + y -= (5-maxRows)*18; + } + + return new IntPair(8+172*(displayId%3), y); + } + + @Override + public boolean mouseInput(int mouseX, int mouseY) { + if(!(Minecraft.getMinecraft().currentScreen instanceof GuiChest)) return false; + + int dWheel = Mouse.getEventDWheel(); + if(dWheel != 0) { + if(dWheel < 0) { + dWheel = -1; + if(scrollVelocity > 0) scrollVelocity = 0; + } + if(dWheel > 0) { + dWheel = 1; + if(scrollVelocity < 0) scrollVelocity = 0; + } + + long currentTime = System.currentTimeMillis(); + if(currentTime - lastScroll > 200) { + scrollVelocity = 0; + } else { + scrollVelocity = (int)(scrollVelocity / 1.3f); + } + lastScroll = currentTime; + + scrollVelocity += dWheel*10; + scrollToY(scroll.getTarget()-scrollVelocity); + + return true; + } + + if(Mouse.getEventButton() == 0) { + if(!Mouse.getEventButtonState()) { + scrollGrabOffset = -1; + } else if(mouseX >= guiLeft+519 && mouseX <= guiLeft+519+14 && + mouseY >= guiTop+8 && mouseY <= guiTop+106) { + int scrollMouseY = mouseY - (guiTop+8); + int scrollBarY = Math.round(getScrollBarHeight()*scroll.getValue()/(float)getMaximumScroll()); + + if(scrollMouseY >= scrollBarY && scrollMouseY < scrollBarY+12) { + scrollGrabOffset = scrollMouseY - scrollBarY; + } + } + } + if(scrollGrabOffset >= 0 && Mouse.getEventButton() == -1 && !Mouse.getEventButtonState()) { + int scrollMouseY = mouseY - (guiTop+8); + int scrollBarY = scrollMouseY - scrollGrabOffset; + + scrollToY(Math.round(scrollBarY*getMaximumScroll()/(float)getScrollBarHeight())); + scroll.setTimeToReachTarget(10); + } + + ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft()); + int width = scaledResolution.getScaledWidth(); + int height = scaledResolution.getScaledHeight(); + + int storageViewSize = getStorageViewSize(); + + int sizeX = 540; + int sizeY = 100+storageViewSize; + int searchNobX = 18; + + guiLeft = width/2 - (sizeX-searchNobX)/2; + guiTop = height/2 - sizeY/2; + + if(mouseX > guiLeft+181 && mouseX < guiLeft+181+162 && + mouseY > guiTop+storageViewSize+18 && mouseY < guiTop+storageViewSize+94) { + return false; + } + + if(mouseY > guiTop+3 && mouseY < guiTop+storageViewSize+3) { + int currentPage = StorageManager.getInstance().getCurrentPageId(); + + for(Map.Entry<Integer, Integer> entry : StorageManager.getInstance().storageConfig.displayToStorageIdMap.entrySet()) { + IntPair pageCoords = getPageCoords(entry.getKey()); + + if(pageCoords.y > storageViewSize+3 || pageCoords.y+90 < 3) continue; + + StorageManager.StoragePage page = StorageManager.getInstance().getPage(entry.getValue(), false); + int rows = page == null ? 3 : page.rows <= 0 ? 3 : page.rows; + 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) { + return false; + } else { + if(Mouse.getEventButtonState() && Mouse.getEventButton() == 0 && + Minecraft.getMinecraft().thePlayer.inventory.getItemStack() == null && + page != null) { + scrollToStorage(entry.getKey(), false); + StorageManager.getInstance().sendToPage(entry.getValue()); + return true; + } + } + } + } + } + + for(int i=0; i<10; i++) { + int buttonX = 388+(i%5)*18; + int buttonY = getStorageViewSize()+35+(i/5)*18; + + float minU = (i*16)/256f; + float maxU = (i*16+16)/256f; + + int vIndex = 0; + + switch(i) { + case 2: + vIndex = NotEnoughUpdates.INSTANCE.config.storageGUI.displayStyle; break; + /*case 3: + vIndex = */ + } + + Utils.drawTexturedRect(buttonX, buttonY, 16, 16, minU, maxU, (vIndex*16)/256f, (vIndex*16+16)/256f, GL11.GL_NEAREST); + } + if(desiredHeightSwitch != -1 && Mouse.getEventButton() == -1 && !Mouse.getEventButtonState()) { + int delta = Math.abs(desiredHeightMX - mouseX) + Math.abs(desiredHeightMY - mouseY); + if(delta > 3) { + NotEnoughUpdates.INSTANCE.config.storageGUI.storageHeight = desiredHeightSwitch; + desiredHeightSwitch = -1; + } + } + if(Mouse.getEventButtonState() && mouseX >= guiLeft+388 && mouseX < guiLeft+388+90 && + mouseY >= guiTop+storageViewSize+35 && mouseY < guiTop+storageViewSize+35+36) { + int xN = mouseX - (guiLeft+388); + int yN = mouseY - (guiTop+storageViewSize+35); + + int xIndex = xN/18; + int yIndex = yN/18; + + int buttonIndex = xIndex + 5*yIndex; + + switch(buttonIndex) { + case 0: + NotEnoughUpdates.INSTANCE.config.storageGUI.enableStorageGUI = false; break; + case 1: + int size = desiredHeightSwitch != -1 ? desiredHeightSwitch : NotEnoughUpdates.INSTANCE.config.storageGUI.storageHeight; + int sizeIndex = Math.round((size-104)/54f); + if(Mouse.getEventButton() == 0) { + sizeIndex--; + } else { + sizeIndex++; + } + size = sizeIndex*54+104; + if(size < 104) size = 104; + if(size > 312) size = 312; + desiredHeightMX = mouseX; + desiredHeightMY = mouseY; + desiredHeightSwitch = size; break; + case 2: + int displayStyle = NotEnoughUpdates.INSTANCE.config.storageGUI.displayStyle; + if(Mouse.getEventButton() == 0) { + displayStyle--; + } else { + displayStyle++; + } + if(displayStyle < 0) displayStyle = STORAGE_TEXTURES.length-1; + if(displayStyle >= STORAGE_TEXTURES.length) displayStyle = 0; + + NotEnoughUpdates.INSTANCE.config.storageGUI.displayStyle = displayStyle; break; + case 3: + NotEnoughUpdates.INSTANCE.config.storageGUI.backpackPreview = + !NotEnoughUpdates.INSTANCE.config.storageGUI.backpackPreview; break; + case 4: + NotEnoughUpdates.INSTANCE.config.storageGUI.enderchestPreview = + !NotEnoughUpdates.INSTANCE.config.storageGUI.enderchestPreview; break; + } + } + + if(mouseX >= guiLeft+10 && mouseX <= guiLeft+171 && + mouseY >= guiTop+storageViewSize+23 && mouseY <= guiTop+storageViewSize+91) { + if(StorageManager.getInstance().onStorageMenu) { + return false; + } else if(Mouse.getEventButtonState() && Mouse.getEventButton() == 0) { + for(int i=0; i<9; i++) { + int storageId = i; + int displayId = StorageManager.getInstance().getDisplayIdForStorageId(i); + + StorageManager.StoragePage page = StorageManager.getInstance().getPage(storageId, false); + if(page != null) { + int itemX = 10+(i%9)*18; + int itemY = storageViewSize+24+(i/9)*18; + + if(mouseX >= guiLeft+itemX && mouseX < guiLeft+itemX+18 && + mouseY >= guiTop+itemY && mouseY < guiTop+itemY+18) { + StorageManager.getInstance().sendToPage(storageId); + scrollToStorage(displayId, true); + return true; + } + } + } + for(int i=0; i<18; i++) { + int storageId = i+StorageManager.MAX_ENDER_CHEST_PAGES; + int displayId = StorageManager.getInstance().getDisplayIdForStorageId(i); + + StorageManager.StoragePage page = StorageManager.getInstance().getPage(storageId, false); + if(page != null) { + int itemX = 10+(i%9)*18; + int itemY = storageViewSize+56+(i/9)*18; + + if(mouseX >= guiLeft+itemX && mouseX < guiLeft+itemX+18 && + mouseY >= guiTop+itemY && mouseY < guiTop+itemY+18) { + StorageManager.getInstance().sendToPage(storageId); + scrollToStorage(displayId, true); + return true; + } + } + } + } + } + + return true; + } + + public void overrideIsMouseOverSlot(Slot slot, int mouseX, int mouseY, CallbackInfoReturnable<Boolean> cir) { + if(StorageManager.getInstance().shouldRenderStorageOverlayFast()) { + boolean playerInv = slot.inventory == Minecraft.getMinecraft().thePlayer.inventory; + + int slotId = slot.getSlotIndex(); + int storageViewSize = getStorageViewSize(); + + if(playerInv) { + if(slotId < 9) { + if(mouseY >= guiTop+storageViewSize+76 && mouseY <= guiTop+storageViewSize+92) { + int xN = mouseX-(guiLeft+181); + + int xClicked = xN/18; + + if(xClicked == slotId) { + cir.setReturnValue(true); + return; + } + } + } else { + int xN = mouseX-(guiLeft+181); + int yN = mouseY-(guiTop+storageViewSize+18); + + int xClicked = xN/18; + int yClicked = yN/18; + + if(xClicked >= 0 && xClicked <= 8 && + yClicked >= 0 && yClicked <= 2) { + if(xClicked + yClicked*9 + 9 == slotId) { + cir.setReturnValue(true); + return; + } + } + } + } else { + if(StorageManager.getInstance().onStorageMenu) { + if(slotId >= 9 && slotId < 18) { + if(mouseY >= guiTop+storageViewSize+24 && mouseY < guiTop+storageViewSize+24+18) { + int xN = mouseX-(guiLeft+10); + + int xClicked = xN/18; + + if(xClicked == slotId%9) { + cir.setReturnValue(true); + return; + } + } + } else if(slotId >= 27 && slotId < 45) { + int xN = mouseX-(guiLeft+10); + int yN = mouseY-(guiTop+storageViewSize+56); + + int xClicked = xN/18; + int yClicked = yN/18; + + if(xClicked == slotId%9 && + yClicked >= 0 && yClicked == slotId/9-3) { + cir.setReturnValue(true); + return; + } + } + } else { + int currentPage = StorageManager.getInstance().getCurrentPageId(); + int displayId = StorageManager.getInstance().getDisplayIdForStorageId(currentPage); + if(displayId >= 0) { + IntPair pageCoords = getPageCoords(displayId); + + int xN = mouseX-(guiLeft+pageCoords.x); + int yN = mouseY-(guiTop+pageCoords.y); + + int xClicked = xN/18; + int yClicked = yN/18; + + if(xClicked >= 0 && xClicked <= 8 && + yClicked >= 0 && yClicked <= 5) { + if(xClicked + yClicked*9 + 9 == slotId) { + cir.setReturnValue(true); + return; + } + } + } + } + } + cir.setReturnValue(false); + } + } + + public void clearSearch() { + searchBar.setText(""); + StorageManager.getInstance().searchDisplay(searchBar.getText()); + } + + @Override + public boolean keyboardInput() { + if(Keyboard.getEventKey() == Keyboard.KEY_ESCAPE) { + Minecraft.getMinecraft().thePlayer.closeScreen(); + return false; + } + + if(Keyboard.getEventKeyState()) { + String prevText = searchBar.getText(); + searchBar.setFocus(true); + searchBar.keyTyped(Keyboard.getEventCharacter(), Keyboard.getEventKey()); + if(!prevText.equals(searchBar.getText())) { + StorageManager.getInstance().searchDisplay(searchBar.getText()); + } + } + + return false; + } +} 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 91d3b981..165cb494 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/TradeWindow.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/TradeWindow.java @@ -56,23 +56,15 @@ public class TradeWindow { private static int lastBackpackY; - public static boolean hypixelTradeWindowActive() { - if(!NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) return false; - GuiScreen guiScreen = Minecraft.getMinecraft().currentScreen; - if(guiScreen instanceof GuiChest) { - GuiChest eventGui = (GuiChest) guiScreen; - ContainerChest cc = (ContainerChest) eventGui.inventorySlots; - String containerName = cc.getLowerChestInventory().getDisplayName().getUnformattedText(); - return containerName.trim().startsWith("You "); - } - return false; + public static boolean hypixelTradeWindowActive(String containerName) { + return containerName != null && containerName.trim().startsWith("You "); } - public static boolean tradeWindowActive() { - if(!NotEnoughUpdates.INSTANCE.isOnSkyblock()) return false; + public static boolean tradeWindowActive(String containerName) { + if(!NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) return false; if(!NotEnoughUpdates.INSTANCE.config.tradeMenu.enableCustomTrade) return false; - if(hypixelTradeWindowActive()) { + if(hypixelTradeWindowActive(containerName)) { return true; } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/GuiContainerAccessor.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/GuiContainerAccessor.java deleted file mode 100644 index 57d4de2a..00000000 --- a/src/main/java/io/github/moulberry/notenoughupdates/mixins/GuiContainerAccessor.java +++ /dev/null @@ -1,22 +0,0 @@ -package io.github.moulberry.notenoughupdates.mixins; - -import net.minecraft.client.gui.inventory.GuiContainer; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -@Mixin(GuiContainer.class) -public interface GuiContainerAccessor { - - @Accessor - int getXSize(); - - @Accessor - int getYSize(); - - @Accessor - int getGuiLeft(); - - @Accessor - int getGuiTop(); - -} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/GuiEditSignAccessor.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/GuiEditSignAccessor.java deleted file mode 100644 index 64cf488f..00000000 --- a/src/main/java/io/github/moulberry/notenoughupdates/mixins/GuiEditSignAccessor.java +++ /dev/null @@ -1,14 +0,0 @@ -package io.github.moulberry.notenoughupdates.mixins; - -import net.minecraft.client.gui.inventory.GuiEditSign; -import net.minecraft.tileentity.TileEntitySign; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -@Mixin(GuiEditSign.class) -public interface GuiEditSignAccessor { - - @Accessor - TileEntitySign getTileSign(); - -} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinAbstractClientPlayer.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinAbstractClientPlayer.java new file mode 100644 index 00000000..9bf260da --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinAbstractClientPlayer.java @@ -0,0 +1,42 @@ +package io.github.moulberry.notenoughupdates.mixins; + +import io.github.moulberry.notenoughupdates.miscfeatures.NPCRetexturing; +import net.minecraft.client.entity.AbstractClientPlayer; +import net.minecraft.client.network.NetworkPlayerInfo; +import net.minecraft.client.resources.DefaultPlayerSkin; +import net.minecraft.util.ResourceLocation; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(AbstractClientPlayer.class) +public class MixinAbstractClientPlayer { + + @Inject(method="hasSkin", at=@At("HEAD"), cancellable = true) + public void hasSkin(CallbackInfoReturnable<Boolean> cir) { + AbstractClientPlayer $this = (AbstractClientPlayer)(Object)this; + if(NPCRetexturing.getInstance().getSkin($this) != null) { + cir.setReturnValue(true); + } + } + + @Inject(method="getLocationSkin()Lnet/minecraft/util/ResourceLocation;", at=@At("HEAD"), cancellable = true) + public void getLocationSkin(CallbackInfoReturnable<ResourceLocation> cir) { + AbstractClientPlayer $this = (AbstractClientPlayer)(Object)this; + NPCRetexturing.Skin skin = NPCRetexturing.getInstance().getSkin($this); + if(skin != null) { + cir.setReturnValue(skin.skinLocation); + } + } + + @Inject(method="getSkinType", at=@At("HEAD"), cancellable = true) + public void getSkinType(CallbackInfoReturnable<String> cir) { + AbstractClientPlayer $this = (AbstractClientPlayer)(Object)this; + NPCRetexturing.Skin skin = NPCRetexturing.getInstance().getSkin($this); + if(skin != null) { + cir.setReturnValue(skin.skinny ? "slim" : "default"); + } + } + +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinEntityPlayerSP.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinEntityPlayerSP.java new file mode 100644 index 00000000..2cad4011 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinEntityPlayerSP.java @@ -0,0 +1,27 @@ +package io.github.moulberry.notenoughupdates.mixins; + +import io.github.moulberry.notenoughupdates.miscfeatures.SlotLocking; +import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.EntityPlayerSP; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.EnumChatFormatting; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(EntityPlayerSP.class) +public class MixinEntityPlayerSP { + + @Inject(method="dropOneItem", at=@At("HEAD"), cancellable = true) + public void dropOneItem(CallbackInfoReturnable<EntityItem> ci) { + int slot = Minecraft.getMinecraft().thePlayer.inventory.currentItem; + if(SlotLocking.getInstance().isSlotIndexLocked(slot)) { + ci.cancel(); + Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED+ + "NotEnoughUpdates has prevented you from dropping that locked item!")); + } + } + +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinEntityRenderer.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinEntityRenderer.java index 6ca5a308..8520bd01 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinEntityRenderer.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinEntityRenderer.java @@ -1,15 +1,46 @@ package io.github.moulberry.notenoughupdates.mixins; import io.github.moulberry.notenoughupdates.miscfeatures.CustomItemEffects; +import io.github.moulberry.notenoughupdates.miscgui.InventoryStorageSelector; +import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.EntityRenderer; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.ItemRenderer; +import net.minecraft.client.renderer.RenderGlobal; +import net.minecraft.entity.Entity; +import net.minecraft.item.ItemStack; +import net.minecraftforge.client.ForgeHooksClient; import org.lwjgl.util.vector.Vector3f; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.ModifyVariable; +import org.spongepowered.asm.mixin.injection.Redirect; @Mixin(EntityRenderer.class) public class MixinEntityRenderer { + + @Redirect(method="renderWorldPass", at=@At( + value="INVOKE", + target = "Lnet/minecraftforge/client/ForgeHooksClient;dispatchRenderLast(Lnet/minecraft/client/renderer/RenderGlobal;F)V", + remap = false) + ) + public void renderWorldPass_dispatchRenderLast(RenderGlobal context, float partialTicks) { + Vector3f currentPosition = CustomItemEffects.INSTANCE.getCurrentPosition(); + if(currentPosition != null) { + Entity entity = Minecraft.getMinecraft().getRenderViewEntity(); + double d0 = entity.lastTickPosX + (entity.posX - entity.lastTickPosX) * (double)partialTicks; + double d1 = entity.lastTickPosY + (entity.posY - entity.lastTickPosY) * (double)partialTicks; + double d2 = entity.lastTickPosZ + (entity.posZ - entity.lastTickPosZ) * (double)partialTicks; + + GlStateManager.translate(-currentPosition.x + d0, -currentPosition.y + d1, -currentPosition.z + d2); + ForgeHooksClient.dispatchRenderLast(context, partialTicks); + GlStateManager.translate(currentPosition.x - d0, currentPosition.y - d1, currentPosition.z - d2); + } else { + ForgeHooksClient.dispatchRenderLast(context, partialTicks); + } + } + //orientCamera @ModifyVariable(method="orientCamera", at=@At(value="STORE"), ordinal = 0) public double orientCamera_d0(double d0) { 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 0c822827..81f0d857 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiContainer.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiContainer.java @@ -6,6 +6,8 @@ import io.github.moulberry.notenoughupdates.miscfeatures.BetterContainers; import io.github.moulberry.notenoughupdates.miscfeatures.EnchantingSolvers; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.miscfeatures.PetInfoOverlay; +import io.github.moulberry.notenoughupdates.miscfeatures.SlotLocking; +import io.github.moulberry.notenoughupdates.miscgui.StorageOverlay; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Gui; @@ -26,10 +28,18 @@ 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; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.util.concurrent.atomic.AtomicBoolean; @Mixin(GuiContainer.class) public abstract class MixinGuiContainer extends GuiScreen { + @Inject(method="drawSlot", at=@At("RETURN")) + public void drawSlotRet(Slot slotIn, CallbackInfo ci) { + SlotLocking.getInstance().drawSlot(slotIn); + } + @Inject(method="drawSlot", at=@At("HEAD"), cancellable = true) public void drawSlot(Slot slot, CallbackInfo ci) { if(slot == null) return; @@ -56,35 +66,37 @@ public abstract class MixinGuiContainer extends GuiScreen { RenderHelper.enableGUIStandardItemLighting(); - if(stack == null && System.currentTimeMillis() - BetterContainers.lastRenderMillis < 300 && $this instanceof GuiChest) { - Container container = ((GuiChest)$this).inventorySlots; - if(container instanceof ContainerChest) { - IInventory lower = ((ContainerChest)container).getLowerChestInventory(); - int size = lower.getSizeInventory(); - if(slot.slotNumber < size) { - boolean found = false; - for(int index=0; index<size; index++) { - if(lower.getStackInSlot(index) != null) { - found = true; - break; - } - } - if(!found) { - stack = BetterContainers.itemCache.get(slot.slotNumber); - } - } - - } - } - if(BetterContainers.isOverriding() && !BetterContainers.shouldRenderStack(stack)) { ci.cancel(); } } + @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); + } + + @Redirect(method="drawScreen", at=@At(value="INVOKE", target = "Lnet/minecraft/client/gui/inventory/GuiContainer;drawGradientRect(IIIIII)V")) + public void drawScreen_drawGradientRect(GuiContainer container, int left, int top, int right, int bottom, int startColor, int endColor) { + if(startColor == 0x80ffffff && endColor == 0x80ffffff && + theSlot != null && SlotLocking.getInstance().isSlotLocked(theSlot)) { + int col = 0x80ff8080; + drawGradientRect(left, top, right, bottom, col, col); + } else { + drawGradientRect(left, top, right, bottom, startColor, endColor); + } + } + @Shadow private Slot theSlot; + @Inject(method="drawScreen", at=@At("RETURN")) + public void drawScreen(CallbackInfo ci) { + if(theSlot != null && SlotLocking.getInstance().isSlotLocked(theSlot)) { + theSlot = null; + } + } + private static final String TARGET_GETSTACK = "Lnet/minecraft/inventory/Slot;getStack()Lnet/minecraft/item/ItemStack;"; @Redirect(method="drawScreen", at=@At(value="INVOKE", target=TARGET_GETSTACK)) public ItemStack drawScreen_getStack(Slot slot) { @@ -147,6 +159,24 @@ public abstract class MixinGuiContainer extends GuiScreen { @Inject(method="handleMouseClick", at=@At(value="HEAD"), cancellable = true) public void handleMouseClick(Slot slotIn, int slotId, int clickedButton, int clickType, CallbackInfo ci) { GuiContainer $this = (GuiContainer)(Object)this; + + AtomicBoolean ret = new AtomicBoolean(false); + SlotLocking.getInstance().onWindowClick(slotIn, slotId, clickedButton, clickType, (tuple) -> { + ci.cancel(); + + if(tuple == null) { + ret.set(true); + } else { + int newSlotId = tuple.getLeft(); + int newClickedButton = tuple.getMiddle(); + int newClickedType = tuple.getRight(); + + ret.set(true); + $this.mc.playerController.windowClick($this.inventorySlots.windowId, newSlotId, newClickedButton, newClickedType, $this.mc.thePlayer); + } + }); + if(ret.get()) return; + if(slotIn != null && slotIn.getStack() != null) { if(EnchantingSolvers.onStackClick(slotIn.getStack(), $this.inventorySlots.windowId, slotId, clickedButton, clickType)) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiIngame.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiIngame.java index 4ec15bea..28b14bb2 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiIngame.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiIngame.java @@ -2,12 +2,20 @@ package io.github.moulberry.notenoughupdates.mixins; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.miscfeatures.StreamerMode; +import io.github.moulberry.notenoughupdates.miscgui.InventoryStorageSelector; +import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiIngame; +import net.minecraft.client.gui.ScaledResolution; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.item.ItemStack; import net.minecraft.scoreboard.ScorePlayerTeam; import net.minecraft.scoreboard.Team; import org.spongepowered.asm.mixin.Mixin; 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({GuiIngame.class}) public class MixinGuiIngame { @@ -21,4 +29,27 @@ public class MixinGuiIngame { } return ScorePlayerTeam.formatPlayerName(team, name); } + + @Inject(method="renderTooltip", at=@At("HEAD")) + protected void renderTooltip(ScaledResolution sr, float partialTicks, CallbackInfo ci) { + if(Minecraft.getMinecraft().getRenderViewEntity() instanceof EntityPlayer) { + InventoryStorageSelector.getInstance().render(sr, partialTicks); + } + } + + @Redirect(method="renderTooltip", at=@At(value = "INVOKE", target = "Lnet/minecraft/client/gui/GuiIngame;drawTexturedModalRect(IIIIII)V")) + public void renderTooltooltip_drawTexturedModelRect(GuiIngame guiIngame, int x, int y, int textureX, int textureY, int width, int height) { + if(!InventoryStorageSelector.getInstance().isSlotSelected() || textureX != 0 || textureY != 22 || width != 24 || height != 22) { + guiIngame.drawTexturedModalRect(x, y, textureX, textureY, width, height); + } + } + + @Redirect(method="updateTick", at=@At(value = "INVOKE", target = "Lnet/minecraft/entity/player/InventoryPlayer;getCurrentItem()Lnet/minecraft/item/ItemStack;")) + public ItemStack updateTick_getCurrentItem(InventoryPlayer inventory) { + if(!NotEnoughUpdates.INSTANCE.config.storageGUI.showInvBackpackPreview && + InventoryStorageSelector.getInstance().isSlotSelected()) { + return InventoryStorageSelector.getInstance().getNamedHeldItemOverride(); + } + return inventory.getCurrentItem(); + } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinInventoryPlayer.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinInventoryPlayer.java new file mode 100644 index 00000000..d31ab00a --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinInventoryPlayer.java @@ -0,0 +1,20 @@ +package io.github.moulberry.notenoughupdates.mixins; + +import io.github.moulberry.notenoughupdates.miscgui.InventoryStorageSelector; +import net.minecraft.entity.player.InventoryPlayer; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(InventoryPlayer.class) +public class MixinInventoryPlayer { + + @Inject(method="changeCurrentItem", at=@At("RETURN")) + public void changeCurrentItem(int direction, CallbackInfo ci) { + InventoryPlayer $this = (InventoryPlayer)(Object)this; + + $this.currentItem = InventoryStorageSelector.getInstance().onScroll(direction, $this.currentItem); + } + +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinItemRenderer.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinItemRenderer.java new file mode 100644 index 00000000..39586458 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinItemRenderer.java @@ -0,0 +1,34 @@ +package io.github.moulberry.notenoughupdates.mixins; + +import io.github.moulberry.notenoughupdates.miscgui.InventoryStorageSelector; +import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.AbstractClientPlayer; +import net.minecraft.client.renderer.ItemRenderer; +import net.minecraft.item.ItemStack; +import org.spongepowered.asm.lib.Opcodes; +import org.spongepowered.asm.mixin.Final; +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(ItemRenderer.class) +public abstract class MixinItemRenderer { + + @Shadow private ItemStack itemToRender; + + @Redirect(method="renderItemInFirstPerson", at=@At( + value = "FIELD", + target = "Lnet/minecraft/client/renderer/ItemRenderer;itemToRender:Lnet/minecraft/item/ItemStack;", + opcode = Opcodes.GETFIELD + )) + public ItemStack modifyStackToRender(ItemRenderer renderer) { + if(InventoryStorageSelector.getInstance().isSlotSelected()) { + return InventoryStorageSelector.getInstance().getHeldItemOverride(); + } + return itemToRender; + } + +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinItemStack.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinItemStack.java index 239dbe93..4a7f0f5b 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinItemStack.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinItemStack.java @@ -1,7 +1,6 @@ package io.github.moulberry.notenoughupdates.mixins; -import io.github.moulberry.notenoughupdates.NotEnoughUpdates; -import io.github.moulberry.notenoughupdates.miscfeatures.ItemCooldowns; +import io.github.moulberry.notenoughupdates.miscfeatures.ItemCustomizeManager; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; @@ -16,9 +15,10 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; public class MixinItemStack { @Inject(method="hasEffect", at=@At("HEAD"), cancellable = true) - public void hasEffect(CallbackInfoReturnable cir) { + public void hasEffect(CallbackInfoReturnable<Boolean> cir) { if(Utils.getHasEffectOverride()) { cir.setReturnValue(false); + return; } } @@ -32,28 +32,31 @@ public class MixinItemStack { return; } - String customName = NotEnoughUpdates.INSTANCE.manager.itemRenameJson - .get(stackTagCompound.getCompoundTag("ExtraAttributes").getString("uuid")).getAsString(); - if(customName != null && !customName.equals("")) { - String prefix = EnumChatFormatting.RESET.toString(); - if (stackTagCompound != null && stackTagCompound.hasKey("display", 10)) { - NBTTagCompound nbttagcompound = stackTagCompound.getCompoundTag("display"); - - if (nbttagcompound.hasKey("Name", 8)) { - String name = nbttagcompound.getString("Name"); - char[] chars = name.toCharArray(); - - int i; - for(i=0; i<chars.length; i+=2) { - if(chars[i] != '\u00a7'){ - break; + ItemCustomizeManager.ItemData data = ItemCustomizeManager.getDataForItem((ItemStack)(Object)this); + + if(data != null && data.customName != null) { + String customName = data.customName; + if(customName != null && !customName.equals("")) { + String prefix = EnumChatFormatting.RESET.toString(); + if (stackTagCompound != null && stackTagCompound.hasKey("display", 10)) { + NBTTagCompound nbttagcompound = stackTagCompound.getCompoundTag("display"); + + if (nbttagcompound.hasKey("Name", 8)) { + String name = nbttagcompound.getString("Name"); + char[] chars = name.toCharArray(); + + int i; + for(i=0; i<chars.length; i+=2) { + if(chars[i] != '\u00a7'){ + break; + } } - } - prefix = name.substring(0, i); + prefix = name.substring(0, i); + } } + returnable.setReturnValue(prefix+customName); } - returnable.setReturnValue(prefix+customName); } } catch(Exception e) { } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinLayerArmorBase.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinLayerArmorBase.java new file mode 100644 index 00000000..c89ce010 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinLayerArmorBase.java @@ -0,0 +1,67 @@ +package io.github.moulberry.notenoughupdates.mixins; + +import io.github.moulberry.notenoughupdates.core.ChromaColour; +import io.github.moulberry.notenoughupdates.miscfeatures.ItemCustomizeManager; +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.renderer.entity.layers.LayerArmorBase; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.ItemArmor; +import net.minecraft.item.ItemStack; +import org.spongepowered.asm.mixin.Mixin; +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(LayerArmorBase.class) +public abstract class MixinLayerArmorBase<T extends ModelBase> { + + private static String customEnchGlint = null; + + @Redirect(method="renderLayer", + at=@At( + value = "INVOKE", + target = "Lnet/minecraft/item/ItemStack;hasEffect()Z" + ) + ) + public boolean renderItem_hasEffect(ItemStack stack) { + ItemCustomizeManager.ItemData data = ItemCustomizeManager.getDataForItem(stack); + if(data != null) { + customEnchGlint = data.customGlintColour; + if(data.overrideEnchantGlint) { + return data.enchantGlintValue; + } + } else { + customEnchGlint = null; + } + + return stack.hasEffect(); + } + + @Inject(method="renderGlint", at=@At("HEAD"), cancellable = true) + public void renderGlint(EntityLivingBase entitylivingbaseIn, T modelbaseIn, float p_177183_3_, float p_177183_4_, + float partialTicks, float p_177183_6_, float p_177183_7_, float p_177183_8_, float scale, CallbackInfo ci) { + float existed = (float)entitylivingbaseIn.ticksExisted + partialTicks; + if(ItemCustomizeManager.render3DGlint(customEnchGlint, existed, () -> { + modelbaseIn.render(entitylivingbaseIn, p_177183_3_, p_177183_4_, p_177183_6_, p_177183_7_, p_177183_8_, scale); + })) { + ci.cancel(); + } + } + + @Redirect(method="renderLayer", + at=@At( + value = "INVOKE", + target = "Lnet/minecraft/item/ItemArmor;getColor(Lnet/minecraft/item/ItemStack;)I" + ) + ) + public int renderItem_getColor(ItemArmor item, ItemStack stack) { + ItemCustomizeManager.ItemData data = ItemCustomizeManager.getDataForItem(stack); + if(data != null && data.customLeatherColour != null) { + return ChromaColour.specialToChromaRGB(data.customLeatherColour); + } + + return item.getColor(stack); + } + +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinLayerCustomHead.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinLayerCustomHead.java new file mode 100644 index 00000000..5a780edf --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinLayerCustomHead.java @@ -0,0 +1,71 @@ +package io.github.moulberry.notenoughupdates.mixins; + +import com.mojang.authlib.GameProfile; +import io.github.moulberry.notenoughupdates.miscfeatures.ItemCustomizeManager; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.entity.layers.LayerCustomHead; +import net.minecraft.client.renderer.tileentity.TileEntitySkullRenderer; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumFacing; +import org.lwjgl.opengl.GL11; +import org.spongepowered.asm.mixin.Mixin; +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(LayerCustomHead.class) +public class MixinLayerCustomHead { + + private static String customGlintColour = null; + + @Inject(method="doRenderLayer", at=@At("HEAD")) + public void doRenderLayer(EntityLivingBase entitylivingbaseIn, float p_177141_2_, float p_177141_3_, float partialTicks, + float p_177141_5_, float p_177141_6_, float p_177141_7_, float scale, CallbackInfo ci) { + ItemStack stack = entitylivingbaseIn.getCurrentArmor(3); + + ItemCustomizeManager.ItemData data = ItemCustomizeManager.getDataForItem(stack); + if(data != null && data.overrideEnchantGlint && data.enchantGlintValue) { + customGlintColour = data.customGlintColour; + } else { + customGlintColour = null; + } + } + + @Redirect(method="doRenderLayer", + at=@At( + value = "INVOKE", + target = "Lnet/minecraft/client/renderer/tileentity/TileEntitySkullRenderer;renderSkull(FFFLnet/minecraft/util/EnumFacing;FILcom/mojang/authlib/GameProfile;I)V" + ) + ) + public void renderItem_renderSkull(TileEntitySkullRenderer tileEntitySkullRenderer, float p_180543_1_, float p_180543_2_, + float p_180543_3_, EnumFacing p_180543_4_, float p_180543_5_, int p_180543_6_, + GameProfile p_180543_7_, int p_180543_8_) { + GL11.glPushMatrix(); + tileEntitySkullRenderer.renderSkull(p_180543_1_, p_180543_2_, p_180543_3_, p_180543_4_, p_180543_5_, + p_180543_6_, p_180543_7_, p_180543_8_); + GL11.glPopMatrix(); + + if(customGlintColour != null) { + ItemCustomizeManager.renderEffectHook(customGlintColour, (color) -> { + float red = ((color >> 16) & 0xFF) / 255f; + float green = ((color >> 8) & 0xFF) / 255f; + float blue = (color & 0xFF) / 255f; + float alpha = ((color >> 24) & 0xFF) / 255f; + + GlStateManager.color(red, green, blue, alpha); + + GlStateManager.scale(1/8f, 1/8f, 1/8f); + GlStateManager.matrixMode(GL11.GL_MODELVIEW); + GL11.glPushMatrix(); + ItemCustomizeManager.disableTextureBinding = true; + tileEntitySkullRenderer.renderSkull(p_180543_1_, p_180543_2_, p_180543_3_, p_180543_4_, p_180543_5_, + p_180543_6_, p_180543_7_, p_180543_8_); + ItemCustomizeManager.disableTextureBinding = false; + GL11.glPopMatrix(); + }); + } + } + +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinMinecraft.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinMinecraft.java new file mode 100644 index 00000000..96e6600e --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinMinecraft.java @@ -0,0 +1,18 @@ +package io.github.moulberry.notenoughupdates.mixins; + +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import net.minecraft.client.Minecraft; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(Minecraft.class) +public class MixinMinecraft { + + @Inject(method="shutdownMinecraftApplet", at=@At("HEAD")) + public void shutdownMinecraftApplet(CallbackInfo ci) { + NotEnoughUpdates.INSTANCE.saveConfig(); + } + +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinMouseHelper.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinMouseHelper.java new file mode 100644 index 00000000..3d442d58 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinMouseHelper.java @@ -0,0 +1,22 @@ +package io.github.moulberry.notenoughupdates.mixins; + +import io.github.moulberry.notenoughupdates.NEUEventListener; +import net.minecraft.util.MouseHelper; +import org.lwjgl.input.Mouse; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(MouseHelper.class) +public class MixinMouseHelper { + + @Inject(method = { "ungrabMouseCursor" }, at = { @At("HEAD") }, cancellable = true) + public void ungrabMouseCursor(final CallbackInfo ci) { + if (System.currentTimeMillis() - NEUEventListener.lastGuiClosed < 150L) { + ci.cancel(); + Mouse.setGrabbed(false); + } + } + +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinNetHandlerPlayClient.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinNetHandlerPlayClient.java index 7f88b369..a32fa216 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinNetHandlerPlayClient.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinNetHandlerPlayClient.java @@ -6,6 +6,7 @@ import io.github.moulberry.notenoughupdates.util.SBInfo; import net.minecraft.client.network.NetHandlerPlayClient; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.network.Packet; +import net.minecraft.network.play.client.C0EPacketClickWindow; import net.minecraft.network.play.client.C13PacketPlayerAbilities; import net.minecraft.network.play.server.*; import org.lwjgl.opengl.Display; @@ -29,9 +30,25 @@ public class MixinNetHandlerPlayClient { player.setPositionAndRotation(x, y, z, yaw, pitch); } - @Inject(method="handleSetSlot", at=@At("HEAD")) + @Inject(method="handleSetSlot", at=@At("RETURN")) public void handleSetSlot(S2FPacketSetSlot packetIn, CallbackInfo ci) { EnchantingSolvers.processInventoryContents(false); + StorageManager.getInstance().setSlotPacket(packetIn); + } + + @Inject(method="handleOpenWindow", at=@At("RETURN")) + public void handleOpenWindow(S2DPacketOpenWindow packetIn, CallbackInfo ci) { + StorageManager.getInstance().openWindowPacket(packetIn); + } + + @Inject(method="handleCloseWindow", at=@At("RETURN")) + public void handleCloseWindow(S2EPacketCloseWindow packetIn, CallbackInfo ci) { + StorageManager.getInstance().closeWindowPacket(packetIn); + } + + @Inject(method="handleWindowItems", at=@At("RETURN")) + public void handleOpenWindow(S30PacketWindowItems packetIn, CallbackInfo ci) { + StorageManager.getInstance().setItemsPacket(packetIn); } @Inject(method="handleBlockChange", at=@At("HEAD")) @@ -45,13 +62,12 @@ public class MixinNetHandlerPlayClient { FlyFix.onReceiveAbilities(packetIn); } - /*@Inject(method="addToSendQueue", at=@At("HEAD")) + @Inject(method="addToSendQueue", at=@At("HEAD")) public void addToSendQueue(Packet packet, CallbackInfo ci) { - if(packet instanceof C13PacketPlayerAbilities) { - C13PacketPlayerAbilities abilities = (C13PacketPlayerAbilities) packet; - FlyFix.onSendAbilities(abilities); + if(packet instanceof C0EPacketClickWindow) { + StorageManager.getInstance().clientSendWindowClick((C0EPacketClickWindow)packet); } - }*/ + } @Inject(method="handlePlayerListHeaderFooter", at=@At("HEAD")) public void handlePlayerListHeaderFooter(S47PacketPlayerListHeaderFooter packetIn, CallbackInfo ci) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinRenderGlobal.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinRenderGlobal.java index a11bf052..d992d518 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinRenderGlobal.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinRenderGlobal.java @@ -15,7 +15,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @Mixin(RenderGlobal.class) public class MixinRenderGlobal { - //setupTerrain @ModifyVariable(method="setupTerrain", at=@At(value="STORE"), ordinal = 4) public double setupTerrain_d0(double d3) { Vector3f currentPosition = CustomItemEffects.INSTANCE.getCurrentPosition(); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinRenderItem.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinRenderItem.java index 5fcb6e84..db3f9be3 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinRenderItem.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinRenderItem.java @@ -3,8 +3,9 @@ package io.github.moulberry.notenoughupdates.mixins; import io.github.moulberry.notenoughupdates.NEUEventListener; import io.github.moulberry.notenoughupdates.NEUOverlay; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.core.ChromaColour; +import io.github.moulberry.notenoughupdates.miscfeatures.ItemCustomizeManager; import io.github.moulberry.notenoughupdates.miscfeatures.ItemCooldowns; -import io.github.moulberry.notenoughupdates.miscfeatures.ItemRarityHalo; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.Gui; @@ -13,18 +14,18 @@ import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.WorldRenderer; import net.minecraft.client.renderer.entity.RenderItem; +import net.minecraft.client.renderer.tileentity.TileEntityItemStackRenderer; import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.resources.model.IBakedModel; +import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import org.lwjgl.input.Keyboard; +import org.lwjgl.opengl.GL11; 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; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import java.awt.*; @Mixin({RenderItem.class}) public abstract class MixinRenderItem { @@ -43,6 +44,137 @@ public abstract class MixinRenderItem { Tessellator.getInstance().draw(); } + private static String customEnchGlint = null; + + @Redirect(method="renderItem(Lnet/minecraft/item/ItemStack;Lnet/minecraft/client/resources/model/IBakedModel;)V", + at=@At( + value = "INVOKE", + target = "Lnet/minecraft/item/ItemStack;hasEffect()Z" + ) + ) + public boolean renderItem_hasEffect(ItemStack stack) { + ItemCustomizeManager.ItemData data = ItemCustomizeManager.getDataForItem(stack); + if(data != null) { + customEnchGlint = data.customGlintColour; + if(data.overrideEnchantGlint) { + return data.enchantGlintValue; + } + } else { + customEnchGlint = null; + } + + return stack.hasEffect(); + } + + @Redirect(method="renderItem(Lnet/minecraft/item/ItemStack;Lnet/minecraft/client/resources/model/IBakedModel;)V", + at=@At( + value = "INVOKE", + target = "Lnet/minecraft/client/renderer/tileentity/TileEntityItemStackRenderer;renderByItem(Lnet/minecraft/item/ItemStack;)V" + ) + ) + public void renderItem_renderByItem(TileEntityItemStackRenderer tileEntityItemStackRenderer, ItemStack stack) { + GL11.glPushMatrix(); + tileEntityItemStackRenderer.renderByItem(stack); + GL11.glPopMatrix(); + + ItemCustomizeManager.ItemData data = ItemCustomizeManager.getDataForItem(stack); + if(data != null) { + if(data.overrideEnchantGlint && data.enchantGlintValue) { + ItemCustomizeManager.renderEffectHook(data.customGlintColour, (color) -> { + float red = ((color >> 16) & 0xFF) / 255f; + float green = ((color >> 8) & 0xFF) / 255f; + float blue = (color & 0xFF) / 255f; + float alpha = ((color >> 24) & 0xFF) / 255f; + + GlStateManager.color(red, green, blue, alpha); + + GlStateManager.scale(1/8f, 1/8f, 1/8f); + GlStateManager.matrixMode(GL11.GL_MODELVIEW); + GL11.glPushMatrix(); + ItemCustomizeManager.disableTextureBinding = true; + tileEntityItemStackRenderer.renderByItem(stack); + ItemCustomizeManager.disableTextureBinding = false; + GL11.glPopMatrix(); + + }); + } + } + } + + @Redirect(method="renderQuads", + at=@At( + value = "INVOKE", + target = "Lnet/minecraft/item/Item;getColorFromItemStack(Lnet/minecraft/item/ItemStack;I)I" + ) + ) + public int renderItem_renderByItem(Item item, ItemStack stack, int renderPass) { + if(renderPass == 0) { + ItemCustomizeManager.ItemData data = ItemCustomizeManager.getDataForItem(stack); + if(data != null && data.customLeatherColour != null) { + return ChromaColour.specialToChromaRGB(data.customLeatherColour); + } + } + + return item.getColorFromItemStack(stack, renderPass); + } + + @Inject(method="renderEffect", at=@At("HEAD"), cancellable = true) + public void renderEffect(IBakedModel model, CallbackInfo ci) { + if(ItemCustomizeManager.renderEffectHook(customEnchGlint, (color) -> { + renderModel(model, color); + })) { + ci.cancel(); + } + } + + @Shadow + abstract void renderModel(IBakedModel model, int color); + /*@Redirect(method="renderEffect", + at=@At( + value = "INVOKE", + target = "Lnet/minecraft/client/renderer/entity/RenderItem;renderModel(Lnet/minecraft/client/resources/model/IBakedModel;I)V" + ) + ) + public void renderEffect_renderModel(RenderItem renderItem, IBakedModel model, int colour) { + if(customEnchGlint != null) { + renderModel(model, ChromaColour.specialToChromaRGB(customEnchGlint)); + } else { + renderModel(model, colour); + } + } + + @Redirect(method="renderEffect", + at=@At( + value = "INVOKE", + target = "Lnet/minecraft/client/renderer/texture/TextureManager;bindTexture(Lnet/minecraft/util/ResourceLocation;)V" + ) + ) + public void renderEffect_bindTexture(TextureManager textureManager, ResourceLocation location) { + if(customEnchGlint != null) { + textureManager.bindTexture(GlintManager.getCustomGlintTexture()); + GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR); + GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR); + } else { + textureManager.bindTexture(location); + } + } + + @Redirect(method="renderEffect", + at=@At( + value = "INVOKE", + target = "Lnet/minecraft/client/renderer/GlStateManager;blendFunc(II)V" + ) + ) + public void renderEffect_blendFunc(int src, int dst) { + if(dst != 1) { + GlStateManager.blendFunc(src, dst); + } else if(customEnchGlint != null) { + GlintManager.setCustomBlendFunc(customEnchGlint); + } else { + GlStateManager.blendFunc(GL11.GL_SRC_COLOR, 1); + } + }*/ + @Inject(method="renderItemIntoGUI", at=@At("HEAD")) public void renderItemHead(ItemStack stack, int x, int y, CallbackInfo ci) { if(NotEnoughUpdates.INSTANCE.overlay.searchMode && NEUEventListener.drawingGuiScreen) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinTextureManager.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinTextureManager.java new file mode 100644 index 00000000..d96beabb --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinTextureManager.java @@ -0,0 +1,21 @@ +package io.github.moulberry.notenoughupdates.mixins; + +import io.github.moulberry.notenoughupdates.miscfeatures.ItemCustomizeManager; +import net.minecraft.client.renderer.texture.TextureManager; +import net.minecraft.util.ResourceLocation; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(TextureManager.class) +public class MixinTextureManager { + + @Inject(method="bindTexture", at=@At("HEAD"), cancellable = true) + public void bindTexture(ResourceLocation location, CallbackInfo ci) { + if(ItemCustomizeManager.disableTextureBinding) { + ci.cancel(); + } + } + +} 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 ae011f92..1c1c746f 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java @@ -14,6 +14,7 @@ import io.github.moulberry.notenoughupdates.overlays.*; import io.github.moulberry.notenoughupdates.util.SBInfo; import net.minecraft.client.Minecraft; import net.minecraftforge.client.ClientCommandHandler; +import org.lwjgl.input.Keyboard; import org.lwjgl.util.vector.Vector2f; import java.util.ArrayList; @@ -117,6 +118,14 @@ public class NEUConfig extends Config { ) public InventoryButtons inventoryButtons = new InventoryButtons(); + + @Expose + @Category( + name = "Slot Locking", + desc = "Slot Locking" + ) + public SlotLocking slotLocking = new SlotLocking(); + @Expose @Category( name = "Tooltip Tweaks", @@ -147,6 +156,13 @@ public class NEUConfig extends Config { @Expose @Category( + name = "Storage GUI", + desc = "Storage GUI" + ) + public StorageGUI storageGUI = new StorageGUI(); + + @Expose + @Category( name = "Dungeons", desc = "Dungeons" ) @@ -494,6 +510,22 @@ public class NEUConfig extends Config { public int clickType = 0; } + public static class SlotLocking { + @ConfigOption( + name = "Enable Slot Locking", + desc = "Allows you to lock slots and create slot pairings" + ) + public boolean enableSlotLocking = false; + + @Expose + @ConfigOption( + name = "Slot Lock Key", + desc = "" + ) + @ConfigEditorKeybind(defaultKey = Keyboard.KEY_L) + public int backpackScrollKey = Keyboard.KEY_L; + } + public static class TooltipTweaks { @ConfigOption( name = "Tooltip Price Information", @@ -768,7 +800,6 @@ public class NEUConfig extends Config { @ConfigAccordionId(id = 4) public String ownRodColour = "0:255:0:0:0"; - @Expose @ConfigOption( name = "Other Rod Colour", @@ -777,6 +808,31 @@ public class NEUConfig extends Config { @ConfigEditorColour @ConfigAccordionId(id = 4) public String otherRodColour = "0:255:0:0:0"; + + @ConfigOption( + name = "Minion Crystal Radius Overlay", + desc = "" + ) + @ConfigEditorAccordion(id = 5) + public boolean crystalAccordion = false; + + @Expose + @ConfigOption( + name = "Enable Crystal Overlay", + desc = "Show a block overlay for the effective radius of minion crystals (farming, mining, etc)" + ) + @ConfigEditorBoolean + @ConfigAccordionId(id = 5) + public boolean enableCrystalOverlay = true; + + @Expose + @ConfigOption( + name = "Always Show Crystal Overlay", + desc = "Show the crystal overlay, even when a minion crystal is not being held" + ) + @ConfigEditorBoolean + @ConfigAccordionId(id = 5) + public boolean alwaysShowCrystal = false; } public static class SkillOverlays { @@ -1026,7 +1082,7 @@ public class NEUConfig extends Config { desc = "" ) @ConfigEditorAccordion(id = 0) - public boolean todoAccordion = false; + public boolean todoAccordion = true; @Expose @ConfigOption( @@ -1035,7 +1091,7 @@ public class NEUConfig extends Config { ) @ConfigEditorBoolean @ConfigAccordionId(id = 0) - public boolean todoOverlay = true; + public boolean todoOverlay = false; @Expose @ConfigOption( @@ -1097,6 +1153,169 @@ public class NEUConfig extends Config { public boolean todoIcons = true; } + public static class StorageGUI { + @ConfigOption( + name = "Storage Overlay", + desc = "" + ) + @ConfigEditorAccordion(id = 1) + public boolean storageOverlayAccordion = false; + + @Expose + @ConfigOption( + name = "Enable Storage GUI", + 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) + public boolean enableStorageGUI = false; + + @Expose + @ConfigOption( + name = "Storage Height", + desc = "Change the height of the storage preview section. Increasing this allows more storages to be seen at once" + ) + @ConfigEditorSlider( + minValue = 104, + maxValue = 312, + minStep = 26 + ) + @ConfigAccordionId(id = 1) + public int storageHeight = 208; + + @Expose + @ConfigOption( + name = "Storage Style", + desc = "Change the visual style of the overlay" + ) + @ConfigEditorDropdown( + values = {"Transparent", "Minecraft", "Dark", "Custom"} + ) + @ConfigAccordionId(id = 1) + public int displayStyle = 0; + + @Expose + @ConfigOption( + name = "Enderchest Preview", + desc = "Preview Enderchest pages when hovering over the selector on the left side" + ) + @ConfigEditorBoolean + @ConfigAccordionId(id = 1) + public boolean enderchestPreview = true; + + @Expose + @ConfigOption( + name = "Backpack Preview", + desc = "Preview Backpacks when hovering over the selector on the left side" + ) + @ConfigEditorBoolean + @ConfigAccordionId(id = 1) + public boolean backpackPreview = true; + + @ConfigOption( + name = "Inventory Backpacks", + desc = "" + ) + @ConfigEditorAccordion(id = 0) + public boolean inventorySlotAccordion = false; + + @Expose + @ConfigOption( + name = "Inventory Backpacks", + desc = "Add a \"10th slot\" to your inventory which allows you to quickly access your backpacks" + ) + @ConfigEditorBoolean + @ConfigAccordionId(id = 0) + public boolean showInvBackpack = true; + + @Expose + @ConfigOption( + name = "Backpack Side", + desc = "Set which side of the hotbar the backpack slot shows" + ) + @ConfigEditorDropdown( + values = {"Left", "Right"} + ) + @ConfigAccordionId(id = 0) + public int backpackHotbarSide = 0; + + @Expose + @ConfigOption( + name = "Backpack Peeking", + desc = "When the backpack is selected, show it's contents on your screen" + ) + @ConfigEditorBoolean + @ConfigAccordionId(id = 0) + public boolean showInvBackpackPreview = true; + + @Expose + @ConfigOption( + name = "Backpack Opacity%", + desc = "Change the opacity of the backpack preview background" + ) + @ConfigEditorSlider( + minValue = 0, + maxValue = 100, + minStep = 5 + ) + @ConfigAccordionId(id = 0) + public int backpackOpacity = 50; + + @Expose + @ConfigOption( + name = "Backpack Scroll Key", + desc = "Change the key which needs to be pressed in order to allow backpacks to be scrolled between" + ) + @ConfigEditorKeybind(defaultKey = Keyboard.KEY_LSHIFT) + @ConfigAccordionId(id = 0) + public int backpackScrollKey = Keyboard.KEY_LSHIFT; + + @Expose + @ConfigOption( + name = "Arrow Key Backpacks", + desc = "Use arrow keys [LEFT],[RIGHT] to move between backpacks and [DOWN] to navigate backpack even when the slot is not selected. Keys are customizable below" + ) + @ConfigEditorBoolean + @ConfigAccordionId(id = 0) + public boolean arrowKeyBackpacks = false; + + @ConfigOption( + name = "Arrow Key Backpack Keybinds", + desc = "" + ) + @ConfigEditorAccordion(id = 2) + @ConfigAccordionId(id = 0) + public boolean backpackArrowAccordion = false; + + @Expose + @ConfigOption( + name = "Backpack Left", + desc = "Select the backpack to the left" + ) + @ConfigEditorKeybind(defaultKey = Keyboard.KEY_LEFT) + @ConfigAccordionId(id = 2) + public int arrowLeftKey = Keyboard.KEY_LEFT; + + @Expose + @ConfigOption( + name = "Backpack Right", + desc = "Select the backpack to the right" + ) + @ConfigEditorKeybind(defaultKey = Keyboard.KEY_RIGHT) + @ConfigAccordionId(id = 2) + public int arrowRightKey = Keyboard.KEY_RIGHT; + + @Expose + @ConfigOption( + name = "Backpack Open", + desc = "Open the selected backpack" + ) + @ConfigEditorKeybind(defaultKey = Keyboard.KEY_DOWN) + @ConfigAccordionId(id = 2) + public int arrowDownKey = Keyboard.KEY_DOWN; + } + public static class EnchSolvers { @Expose @ConfigOption( @@ -1106,6 +1325,14 @@ public class NEUConfig extends Config { @ConfigEditorBoolean public boolean enableEnchantingSolvers = true; + /*@Expose + @ConfigOption( + name = "Prevent Misclicks", + desc = "Prevent accidentally failing the Chronomatron and Ultrasequencer experiments" + ) + @ConfigEditorBoolean + public boolean preventMisclicks = true;*/ + @Expose @ConfigOption( name = "Hide Tooltips", @@ -1290,10 +1517,11 @@ public class NEUConfig extends Config { exampleText = {"\u00a73Goblin Slayer: \u00a7626.5%\n\u00a73Lucky Raffle: \u00a7c0.0%", "\u00a73Mithril Powder: \u00a726,243", "\u00a73Forge 1) \u00a79Diamonite\u00a77: \u00a7aReady!", - "\u00a73Forge 2) \u00a77EMPTY\n\u00a73Forge 3) \u00a77EMPTY\n\u00a73Forge 4) \u00a77EMPTY"} + "\u00a73Forge 2) \u00a77EMPTY\n\u00a73Forge 3) \u00a77EMPTY\n\u00a73Forge 4) \u00a77EMPTY", + "\u00a73Pickaxe CD: \u00a7a78s"} ) @ConfigAccordionId(id = 2) - public List<Integer> dwarvenText = new ArrayList<>(Arrays.asList(0, 1, 2, 3)); + public List<Integer> dwarvenText = new ArrayList<>(Arrays.asList(0, 1, 4, 2, 3)); @Expose @ConfigOption( @@ -1334,6 +1562,30 @@ public class NEUConfig extends Config { @ConfigEditorBoolean public boolean titaniumAlert = true; + + @Expose + @ConfigOption( + name = "Dwarven Mines Textures", + desc = "Allows texture packs to retexture blocks in the Dwarven Mines. If you don't have a texturepack that does this, you should leave this off" + ) + @ConfigEditorBoolean + public boolean dwarvenTextures = false; + + /*@Expose + @ConfigOption( + name = "Don't Mine Stone", + desc = "Prevent mining stone blocks in mining areas" + ) + @ConfigEditorBoolean + public boolean dontMineStone = true; + + @Expose + @ConfigOption( + name = "Reveal Mist Creepers", + desc = "Make the creepers in the Dwarven Mines mist visible" + ) + @ConfigEditorBoolean + public boolean revealMistCreepers = true;*/ } public static class NeuAuctionHouse { @@ -1602,7 +1854,7 @@ public class NEUConfig extends Config { arr.add("/warp hub:Warp Hub:eyJ0aW1lc3RhbXAiOjE1NTkyMTU0MTY5MDksInByb2ZpbGVJZCI6IjQxZDNhYmMyZDc0OTQwMGM5MDkwZDU0MzRkMDM4MzFiIiwicHJvZmlsZU5hbWUiOiJNZWdha2xvb24iLCJzaWduYXR1cmVSZXF1aXJlZCI6dHJ1ZSwidGV4dHVyZXMiOnsiU0tJTiI6eyJ1cmwiOiJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlL2Q3Y2M2Njg3NDIzZDA1NzBkNTU2YWM1M2UwNjc2Y2I1NjNiYmRkOTcxN2NkODI2OWJkZWJlZDZmNmQ0ZTdiZjgifX19"); arr.add("/warp dungeon_hub:Dungeon Hub:eyJ0aW1lc3RhbXAiOjE1Nzg0MDk0MTMxNjksInByb2ZpbGVJZCI6IjQxZDNhYmMyZDc0OTQwMGM5MDkwZDU0MzRkMDM4MzFiIiwicHJvZmlsZU5hbWUiOiJNZWdha2xvb24iLCJzaWduYXR1cmVSZXF1aXJlZCI6dHJ1ZSwidGV4dHVyZXMiOnsiU0tJTiI6eyJ1cmwiOiJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlLzliNTY4OTViOTY1OTg5NmFkNjQ3ZjU4NTk5MjM4YWY1MzJkNDZkYjljMWIwMzg5YjhiYmViNzA5OTlkYWIzM2QiLCJtZXRhZGF0YSI6eyJtb2RlbCI6InNsaW0ifX19fQ=="); arr.add("/craft:Crafting Table:CRAFTING_TABLE"); - arr.add("/enderchest:Ender Chest:ENDER_CHEST"); + arr.add("/storage:Storage:CHEST"); arr.add("/wardrobe:Wardrobe:LEATHER_CHESTPLATE"); arr.add("/pets:Pets:BONE"); arr.add("neuah:NEU Auction House:GOLD_BLOCK"); 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 ff4b0180..f1c051dc 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfigEditor.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfigEditor.java @@ -371,14 +371,15 @@ public class NEUConfigEditor extends GuiElement { ConfigProcessor.ProcessedCategory cat = currentConfigEditing.get(getSelectedCategory()); int optionWidthDefault = innerRight-innerLeft-20; GlStateManager.enableDepth(); - Set<Integer> activeAccordions = new HashSet<>(); + HashMap<Integer, Integer> activeAccordions = new HashMap<>(); for(ConfigProcessor.ProcessedOption option : getOptionsInCategory(cat).values()) { int optionWidth = optionWidthDefault; if(option.accordionId >= 0) { - if(!activeAccordions.contains(option.accordionId)) { + if(!activeAccordions.containsKey(option.accordionId)) { continue; } - optionWidth = optionWidthDefault - 2*innerPadding; + int accordionDepth = activeAccordions.get(option.accordionId); + optionWidth = optionWidthDefault - (2*innerPadding)*(accordionDepth+1); } GuiOptionEditor editor = option.editor; @@ -388,7 +389,11 @@ public class NEUConfigEditor extends GuiElement { if(editor instanceof GuiOptionEditorAccordion) { GuiOptionEditorAccordion accordion = (GuiOptionEditorAccordion) editor; if(accordion.getToggled()) { - activeAccordions.add(accordion.getAccordionId()); + int accordionDepth = 0; + if(option.accordionId >= 0) { + accordionDepth = activeAccordions.get(option.accordionId)+1; + } + activeAccordions.put(accordion.getAccordionId(), accordionDepth); } } int optionHeight = editor.getHeight(); @@ -413,14 +418,15 @@ public class NEUConfigEditor extends GuiElement { GlStateManager.translate(0, 0, 10); GlStateManager.enableDepth(); - Set<Integer> activeAccordions = new HashSet<>(); + HashMap<Integer, Integer> activeAccordions = new HashMap<>(); for(ConfigProcessor.ProcessedOption option : getOptionsInCategory(cat).values()) { int optionWidth = optionWidthDefault; if(option.accordionId >= 0) { - if(!activeAccordions.contains(option.accordionId)) { + if(!activeAccordions.containsKey(option.accordionId)) { continue; } - optionWidth = optionWidthDefault - 2*innerPadding; + int accordionDepth = activeAccordions.get(option.accordionId); + optionWidth = optionWidthDefault - (2*innerPadding)*(accordionDepth+1); } GuiOptionEditor editor = option.editor; @@ -430,7 +436,11 @@ public class NEUConfigEditor extends GuiElement { if(editor instanceof GuiOptionEditorAccordion) { GuiOptionEditorAccordion accordion = (GuiOptionEditorAccordion) editor; if(accordion.getToggled()) { - activeAccordions.add(accordion.getAccordionId()); + int accordionDepth = 0; + if(option.accordionId >= 0) { + accordionDepth = activeAccordions.get(option.accordionId)+1; + } + activeAccordions.put(accordion.getAccordionId(), accordionDepth); } } int optionHeight = editor.getHeight(); @@ -561,10 +571,10 @@ public class NEUConfigEditor extends GuiElement { int optionY = -newTarget; if(getSelectedCategory() != null && getCurrentConfigEditing() != null && getCurrentConfigEditing().containsKey(getSelectedCategory())) { ConfigProcessor.ProcessedCategory cat = getCurrentConfigEditing().get(getSelectedCategory()); - Set<Integer> activeAccordions = new HashSet<>(); + HashMap<Integer, Integer> activeAccordions = new HashMap<>(); for(ConfigProcessor.ProcessedOption option : getOptionsInCategory(cat).values()) { if(option.accordionId >= 0) { - if(!activeAccordions.contains(option.accordionId)) { + if(!activeAccordions.containsKey(option.accordionId)) { continue; } } @@ -574,11 +584,15 @@ public class NEUConfigEditor extends GuiElement { continue; } if(editor instanceof GuiOptionEditorAccordion) { - GuiOptionEditorAccordion accordion = (GuiOptionEditorAccordion) editor; - if(accordion.getToggled()) { - activeAccordions.add(accordion.getAccordionId()); - } + 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); + } + } optionY += editor.getHeight() + 5; if(optionY > 0) { @@ -627,14 +641,15 @@ public class NEUConfigEditor extends GuiElement { int optionY = -optionsScroll.getValue(); if(getSelectedCategory() != null && getCurrentConfigEditing() != null && getCurrentConfigEditing().containsKey(getSelectedCategory())) { int optionWidthDefault = innerRight-innerLeft-20; - ConfigProcessor.ProcessedCategory cat = getCurrentConfigEditing().get(getSelectedCategory());Set<Integer> activeAccordions = new HashSet<>(); + ConfigProcessor.ProcessedCategory cat = getCurrentConfigEditing().get(getSelectedCategory());HashMap<Integer, Integer> activeAccordions = new HashMap<>(); for(ConfigProcessor.ProcessedOption option : getOptionsInCategory(cat).values()) { int optionWidth = optionWidthDefault; if(option.accordionId >= 0) { - if(!activeAccordions.contains(option.accordionId)) { + if(!activeAccordions.containsKey(option.accordionId)) { continue; } - optionWidth = optionWidthDefault - 2*innerPadding; + int accordionDepth = activeAccordions.get(option.accordionId); + optionWidth = optionWidthDefault - (2*innerPadding)*(accordionDepth+1); } GuiOptionEditor editor = option.editor; @@ -644,7 +659,11 @@ public class NEUConfigEditor extends GuiElement { if(editor instanceof GuiOptionEditorAccordion) { GuiOptionEditorAccordion accordion = (GuiOptionEditorAccordion) editor; if(accordion.getToggled()) { - activeAccordions.add(accordion.getAccordionId()); + int accordionDepth = 0; + if(option.accordionId >= 0) { + accordionDepth = activeAccordions.get(option.accordionId)+1; + } + activeAccordions.put(accordion.getAccordionId(), accordionDepth); } } if(editor.mouseInputOverlay((innerLeft+innerRight-optionWidth)/2-5, innerTop+5+optionY, optionWidth, mouseX, mouseY)) { @@ -660,26 +679,31 @@ public class NEUConfigEditor extends GuiElement { if(getSelectedCategory() != null && getCurrentConfigEditing() != null && getCurrentConfigEditing().containsKey(getSelectedCategory())) { int optionWidthDefault = innerRight-innerLeft-20; ConfigProcessor.ProcessedCategory cat = getCurrentConfigEditing().get(getSelectedCategory()); - Set<Integer> activeAccordions = new HashSet<>(); + HashMap<Integer, Integer> activeAccordions = new HashMap<>(); for(ConfigProcessor.ProcessedOption option : getOptionsInCategory(cat).values()) { int optionWidth = optionWidthDefault; if(option.accordionId >= 0) { - if(!activeAccordions.contains(option.accordionId)) { - continue; - } - optionWidth = optionWidthDefault - 2*innerPadding; + if(!activeAccordions.containsKey(option.accordionId)) { + continue; } + int accordionDepth = activeAccordions.get(option.accordionId); + optionWidth = optionWidthDefault - (2*innerPadding)*(accordionDepth+1); + } GuiOptionEditor editor = option.editor; if(editor == null) { continue; } if(editor instanceof GuiOptionEditorAccordion) { - GuiOptionEditorAccordion accordion = (GuiOptionEditorAccordion) editor; - if(accordion.getToggled()) { - activeAccordions.add(accordion.getAccordionId()); + 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); } + } if(editor.mouseInput((innerLeft+innerRight-optionWidth)/2-5, innerTop+5+optionY, optionWidth, mouseX, mouseY)) { return true; } @@ -713,10 +737,10 @@ public class NEUConfigEditor extends GuiElement { if(getSelectedCategory() != null && getCurrentConfigEditing() != null && getCurrentConfigEditing().containsKey(getSelectedCategory())) { ConfigProcessor.ProcessedCategory cat = getCurrentConfigEditing().get(getSelectedCategory()); - Set<Integer> activeAccordions = new HashSet<>(); + HashMap<Integer, Integer> activeAccordions = new HashMap<>(); for(ConfigProcessor.ProcessedOption option : getOptionsInCategory(cat).values()) { if(option.accordionId >= 0) { - if(!activeAccordions.contains(option.accordionId)) { + if(!activeAccordions.containsKey(option.accordionId)) { continue; } } @@ -728,7 +752,11 @@ public class NEUConfigEditor extends GuiElement { if(editor instanceof GuiOptionEditorAccordion) { GuiOptionEditorAccordion accordion = (GuiOptionEditorAccordion) editor; if(accordion.getToggled()) { - activeAccordions.add(accordion.getAccordionId()); + int accordionDepth = 0; + if(option.accordionId >= 0) { + accordionDepth = activeAccordions.get(option.accordionId)+1; + } + activeAccordions.put(accordion.getAccordionId(), accordionDepth); } } if(editor.keyboardInput()) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/overlays/AuctionSearchOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/overlays/AuctionSearchOverlay.java index 81c2b342..00a91219 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/overlays/AuctionSearchOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/overlays/AuctionSearchOverlay.java @@ -5,7 +5,6 @@ import com.google.gson.JsonObject; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.core.GuiElementTextField; import io.github.moulberry.notenoughupdates.core.GuiScreenElementWrapper; -import io.github.moulberry.notenoughupdates.mixins.GuiEditSignAccessor; import io.github.moulberry.notenoughupdates.options.NEUConfigEditor; import io.github.moulberry.notenoughupdates.util.Constants; import io.github.moulberry.notenoughupdates.util.SBInfo; @@ -19,10 +18,8 @@ import net.minecraft.item.ItemStack; import net.minecraft.network.play.client.C0DPacketCloseWindow; import net.minecraft.tileentity.TileEntitySign; import net.minecraft.util.ChatComponentText; -import net.minecraft.util.EnumChatFormatting; import net.minecraft.util.ResourceLocation; import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.text.WordUtils; import org.lwjgl.input.Keyboard; import org.lwjgl.input.Mouse; import org.lwjgl.opengl.GL11; @@ -84,7 +81,7 @@ public class AuctionSearchOverlay { if(lastContainer == null) return false; if(!lastContainer.equals("Auctions Browser") && !lastContainer.startsWith("Auctions: ")) return false; - TileEntitySign tes = ((GuiEditSignAccessor)Minecraft.getMinecraft().currentScreen).getTileSign(); + TileEntitySign tes = ((GuiEditSign)Minecraft.getMinecraft().currentScreen).tileSign; if(tes == null) return false; if(tes.getPos().getY() != 0) return false; @@ -207,7 +204,7 @@ public class AuctionSearchOverlay { } - TileEntitySign tes = ((GuiEditSignAccessor)Minecraft.getMinecraft().currentScreen).getTileSign(); + TileEntitySign tes = ((GuiEditSign)Minecraft.getMinecraft().currentScreen).tileSign; String search = searchString.trim(); if(searchStringExtra != null && !searchStringExtra.isEmpty()) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/overlays/MiningOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/overlays/MiningOverlay.java index dc0ec8f4..a486c773 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/overlays/MiningOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/overlays/MiningOverlay.java @@ -8,6 +8,7 @@ import io.github.moulberry.notenoughupdates.core.config.Position; import io.github.moulberry.notenoughupdates.core.util.StringUtils; import io.github.moulberry.notenoughupdates.core.util.lerp.LerpUtils; import io.github.moulberry.notenoughupdates.cosmetics.CapeManager; +import io.github.moulberry.notenoughupdates.miscfeatures.ItemCooldowns; import io.github.moulberry.notenoughupdates.util.SBInfo; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; @@ -40,7 +41,7 @@ public class MiningOverlay extends TextOverlay { public static Map<String, Float> commissionProgress = new LinkedHashMap<>(); @Override - public void update() { + public void updateFrequent() { if(Minecraft.getMinecraft().currentScreen instanceof GuiChest) { GuiChest chest = (GuiChest) Minecraft.getMinecraft().currentScreen; ContainerChest container = (ContainerChest) chest.inventorySlots; @@ -55,12 +56,6 @@ public class MiningOverlay extends TextOverlay { String name = null; int numberValue = -1; for(String line : lore) { - if(line.startsWith("\u00a77\u00a79")) { - String textAfter = line.substring(4); - if(!textAfter.contains("\u00a7") && !textAfter.equals("Rewards") && !textAfter.equals("Progress")) { - name = textAfter; - } - } if(name != null) { String clean = Utils.cleanColour(line).trim(); if(clean.isEmpty()) { @@ -74,6 +69,12 @@ public class MiningOverlay extends TextOverlay { } } } + if(line.startsWith("\u00a77\u00a79")) { + String textAfter = line.substring(4); + if(!textAfter.contains("\u00a7") && !textAfter.equals("Rewards") && !textAfter.equals("Progress")) { + name = textAfter; + } + } } if(name != null && numberValue > 0) { commissionMaxes.put(name, numberValue); @@ -82,7 +83,10 @@ public class MiningOverlay extends TextOverlay { } } } + } + @Override + public void update() { overlayStrings = null; /*if(Minecraft.getMinecraft().currentScreen instanceof GuiChest) { @@ -250,6 +254,13 @@ public class MiningOverlay extends TextOverlay { overlayStrings.addAll(forgeStrings); }*/ + String pickaxeCooldown; + if(ItemCooldowns.pickaxeUseCooldownMillisRemaining <= 0) { + pickaxeCooldown = DARK_AQUA+"Pickaxe CD: \u00a7aReady"; + } else { + pickaxeCooldown = DARK_AQUA+"Pickaxe CD: \u00a7a" + (ItemCooldowns.pickaxeUseCooldownMillisRemaining/1000) + "s"; + } + for(int index : NotEnoughUpdates.INSTANCE.config.mining.dwarvenText) { switch(index) { case 0: @@ -260,6 +271,8 @@ public class MiningOverlay extends TextOverlay { overlayStrings.addAll(forgeStrings); break; case 3: overlayStrings.addAll(forgeStringsEmpty); break; + case 4: + overlayStrings.add(pickaxeCooldown); break; } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/overlays/RancherBootOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/overlays/RancherBootOverlay.java index 8e1742cd..736f1488 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/overlays/RancherBootOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/overlays/RancherBootOverlay.java @@ -1,10 +1,7 @@ package io.github.moulberry.notenoughupdates.overlays; -import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.core.GuiElementTextField; import io.github.moulberry.notenoughupdates.core.util.GuiElementSlider; -import io.github.moulberry.notenoughupdates.mixins.GuiEditSignAccessor; -import io.github.moulberry.notenoughupdates.util.SBInfo; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Gui; @@ -35,7 +32,7 @@ public class RancherBootOverlay { if(!(Minecraft.getMinecraft().currentScreen instanceof GuiEditSign)) return false; - TileEntitySign tes = ((GuiEditSignAccessor)Minecraft.getMinecraft().currentScreen).getTileSign(); + TileEntitySign tes = ((GuiEditSign)Minecraft.getMinecraft().currentScreen).tileSign; if(tes == null) return false; if(tes.getPos().getY() != 0) return false; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/overlays/TimersOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/overlays/TimersOverlay.java index d4132f76..0b6d1740 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/overlays/TimersOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/overlays/TimersOverlay.java @@ -162,6 +162,11 @@ public class TimersOverlay extends TextOverlay { @Override public void update() { + if(true) { + overlayStrings = null; + return; + } + long currentTime = System.currentTimeMillis(); NEUConfig.HiddenProfileSpecific hidden = NotEnoughUpdates.INSTANCE.config.getProfileSpecific(); |