diff options
Diffstat (limited to 'src/main/java/io')
31 files changed, 2557 insertions, 632 deletions
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/ItemPriceInformation.java b/src/main/java/io/github/moulberry/notenoughupdates/ItemPriceInformation.java index 58efa371..ff618f10 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/ItemPriceInformation.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/ItemPriceInformation.java @@ -3,6 +3,7 @@ package io.github.moulberry.notenoughupdates; import com.google.gson.JsonObject; import io.github.moulberry.notenoughupdates.auction.APIManager; import io.github.moulberry.notenoughupdates.util.Constants; +import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.EnumChatFormatting; @@ -15,6 +16,10 @@ import java.util.Locale; public class ItemPriceInformation { public static boolean addToTooltip(List<String> tooltip, String internalname, ItemStack stack) { + return addToTooltip(tooltip, internalname, stack, true); + } + + public static boolean addToTooltip(List<String> tooltip, String internalname, ItemStack stack, boolean useStackSize) { JsonObject auctionInfo = NotEnoughUpdates.INSTANCE.manager.auctionManager.getItemAuctionInfo(internalname); JsonObject bazaarInfo = NotEnoughUpdates.INSTANCE.manager.auctionManager.getBazaarInfo(internalname); float lowestBinAvg = NotEnoughUpdates.INSTANCE.manager.auctionManager.getItemAvgBin(internalname); @@ -35,7 +40,7 @@ public class ItemPriceInformation { boolean shiftPressed = Keyboard.isKeyDown(Keyboard.KEY_LSHIFT); int stackMultiplier = 1; - int shiftStackMultiplier = 64; + int shiftStackMultiplier = useStackSize && stack.stackSize > 1 ? stack.stackSize : 64; if(shiftPressed) { stackMultiplier = shiftStackMultiplier; } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUEventListener.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUEventListener.java index 838f0b0a..8219c903 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NEUEventListener.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUEventListener.java @@ -1,5 +1,6 @@ package io.github.moulberry.notenoughupdates; +import com.google.common.collect.Lists; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; @@ -16,6 +17,8 @@ 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; import io.github.moulberry.notenoughupdates.util.*; @@ -27,6 +30,7 @@ import net.minecraft.client.gui.ScaledResolution; import net.minecraft.client.gui.inventory.GuiChest; import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.client.gui.inventory.GuiEditSign; +import net.minecraft.client.gui.inventory.GuiInventory; import net.minecraft.client.network.NetworkPlayerInfo; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.entity.player.EntityPlayer; @@ -41,6 +45,7 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.nbt.NBTUtil; import net.minecraft.util.*; +import net.minecraftforge.client.ClientCommandHandler; import net.minecraftforge.client.event.*; import net.minecraftforge.event.entity.player.EntityInteractEvent; import net.minecraftforge.event.entity.player.ItemTooltipEvent; @@ -204,7 +209,6 @@ public class NEUEventListener { CrystalOverlay.tick(); DwarvenMinesTextures.tick(); FairySouls.tick(); - MiningStuff.tick(); XPInformation.getInstance().tick(); ProfileApiSyncer.getInstance().tick(); DamageCommas.tick(); @@ -734,6 +738,8 @@ public class NEUEventListener { } } + public static boolean drawingGuiScreen = false; + /** * Sets hoverInv and focusInv variables, representing whether the NEUOverlay should render behind the inventory when * (hoverInv == true) and whether mouse/kbd inputs shouldn't be sent to NEUOverlay (focusInv == true). @@ -756,10 +762,10 @@ public class NEUEventListener { if(event.gui instanceof GuiContainer) { try { - int xSize = (int) Utils.getField(GuiContainer.class, event.gui, "xSize", "field_146999_f"); - int ySize = (int) Utils.getField(GuiContainer.class, event.gui, "ySize", "field_147000_g"); - int guiLeft = (int) Utils.getField(GuiContainer.class, event.gui, "guiLeft", "field_147003_i"); - int guiTop = (int) Utils.getField(GuiContainer.class, event.gui, "guiTop", "field_147009_r"); + int xSize = ((GuiContainerAccessor)event.gui).getXSize(); + int ySize = ((GuiContainerAccessor)event.gui).getYSize(); + int guiLeft = ((GuiContainerAccessor)event.gui).getGuiLeft(); + int guiTop = ((GuiContainerAccessor)event.gui).getGuiTop(); hoverInv = event.getMouseX() > guiLeft && event.getMouseX() < guiLeft + xSize && event.getMouseY() > guiTop && event.getMouseY() < guiTop + ySize; @@ -797,10 +803,16 @@ public class NEUEventListener { } } } + + drawingGuiScreen = true; } + private boolean doInventoryButtons = false; + @SubscribeEvent public void onGuiScreenDrawPre(GuiScreenEvent.DrawScreenEvent.Pre event) { + doInventoryButtons = false; + if(AuctionSearchOverlay.shouldReplace()) { AuctionSearchOverlay.render(); event.setCanceled(true); @@ -839,6 +851,49 @@ public class NEUEventListener { } } } + + if(CalendarOverlay.isEnabled() || event.isCanceled()) return; + if(NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard() && shouldRenderOverlay(event.gui) + && event.gui instanceof GuiContainer) { + doInventoryButtons = true; + + int zOffset = 50; + + 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(); + + for(NEUConfig.InventoryButton button : NotEnoughUpdates.INSTANCE.config.hidden.inventoryButtons) { + if(!button.isActive()) continue; + if(button.playerInvOnly && !(event.gui instanceof GuiInventory)) continue; + + int x = guiLeft+button.x; + int y = guiTop+button.y; + if(button.anchorRight) { + x += xSize; + } + if(button.anchorBottom) { + y += ySize; + } + + GlStateManager.color(1, 1, 1, 1f); + + GlStateManager.enableDepth(); + GlStateManager.enableAlpha(); + Minecraft.getMinecraft().getTextureManager().bindTexture(EDITOR); + Utils.drawTexturedRect(x, y, 18, 18, + button.backgroundIndex*18/256f, (button.backgroundIndex*18+18)/256f, + 18/256f, 36/256f, GL11.GL_NEAREST); + + if(button.icon != null && !button.icon.trim().isEmpty()) { + GuiInvButtonEditor.renderIcon(button.icon, x+1, y+1); + } + } + GlStateManager.translate(0, 0, -zOffset); + } } private static boolean shouldRenderOverlay(Gui gui) { @@ -854,6 +909,11 @@ public class NEUEventListener { return validGui; } + private static final ResourceLocation EDITOR = new ResourceLocation("notenoughupdates:invbuttons/editor.png"); + private NEUConfig.InventoryButton buttonHovered = null; + private long buttonHoveredMillis = 0; + public static boolean disableCraftingText = false; + /** * Will draw the NEUOverlay over the inventory if focusInv == false. (z-translation of 300 is so that NEUOverlay * will draw over Items in the inventory (which render at a z value of about 250)) @@ -861,6 +921,9 @@ public class NEUEventListener { */ @SubscribeEvent public void onGuiScreenDrawPost(GuiScreenEvent.DrawScreenEvent.Post event) { + drawingGuiScreen = false; + disableCraftingText = false; + if(!(TradeWindow.tradeWindowActive() || event.gui instanceof CustomAHGui || neu.manager.auctionManager.customAH.isRenderOverAuctionView())) { if(shouldRenderOverlay(event.gui) && neu.isOnSkyblock()) { @@ -870,7 +933,6 @@ public class NEUEventListener { neu.overlay.render(hoverInv && focusInv); GL11.glTranslatef(0, 0, -300); } - neu.overlay.renderOverlay(); GlStateManager.popMatrix(); } } @@ -881,6 +943,56 @@ public class NEUEventListener { AccessoryBagOverlay.renderOverlay(); } } + + boolean hoveringButton = false; + 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(); + + for(NEUConfig.InventoryButton button : NotEnoughUpdates.INSTANCE.config.hidden.inventoryButtons) { + if(!button.isActive()) continue; + if(button.playerInvOnly && !(event.gui instanceof GuiInventory)) continue; + + int x = guiLeft+button.x; + int y = guiTop+button.y; + if(button.anchorRight) { + x += xSize; + } + if(button.anchorBottom) { + y += ySize; + } + + if(x-guiLeft >= 85 && x-guiLeft <= 115 && y-guiTop >= 4 && y-guiTop <= 25) { + disableCraftingText = true; + } + + if(event.mouseX >= x && event.mouseX <= x+18 && + event.mouseY >= y && event.mouseY <= y+18) { + hoveringButton = true; + long currentTime = System.currentTimeMillis(); + + if(buttonHovered != button) { + buttonHoveredMillis = currentTime; + buttonHovered = button; + } + + if(currentTime - buttonHoveredMillis > 600) { + String command = button.command.trim(); + if(!command.startsWith("/")) { + command = "/" + command; + } + + Utils.drawHoveringText(Lists.newArrayList("\u00a77"+command), event.mouseX, event.mouseY, + event.gui.width, event.gui.height, -1, Minecraft.getMinecraft().fontRendererObj); + } + } + } + } + if(!hoveringButton) buttonHovered = null; } private void renderDungeonChestOverlay(GuiScreen gui) { @@ -888,10 +1000,10 @@ public class NEUEventListener { if(gui instanceof GuiChest && neu.config.dungeons.profitDisplayLoc != 2) { try { - int xSize = (int) Utils.getField(GuiContainer.class, gui, "xSize", "field_146999_f"); - int ySize = (int) Utils.getField(GuiContainer.class, gui, "ySize", "field_147000_g"); - int guiLeft = (int) Utils.getField(GuiContainer.class, gui, "guiLeft", "field_147003_i"); - int guiTop = (int) Utils.getField(GuiContainer.class, gui, "guiTop", "field_147009_r"); + int xSize = ((GuiContainerAccessor)gui).getXSize(); + int ySize = ((GuiContainerAccessor)gui).getYSize(); + int guiLeft = ((GuiContainerAccessor)gui).getGuiLeft(); + int guiTop = ((GuiContainerAccessor)gui).getGuiTop(); GuiChest eventGui = (GuiChest) gui; ContainerChest cc = (ContainerChest) eventGui.inventorySlots; @@ -1083,7 +1195,7 @@ public class NEUEventListener { * Will also cancel the event if if NEUOverlay#mouseInput returns true. * @param event */ - @SubscribeEvent + @SubscribeEvent(priority = EventPriority.LOW) public void onGuiScreenMouse(GuiScreenEvent.MouseInputEvent.Pre event) { if(!event.isCanceled()) { Utils.scrollTooltip(Mouse.getEventDWheel()); @@ -1121,6 +1233,53 @@ public class NEUEventListener { } } } + if(event.isCanceled()) return; + 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; + + for(NEUConfig.InventoryButton button : NotEnoughUpdates.INSTANCE.config.hidden.inventoryButtons) { + if(!button.isActive()) continue; + if(button.playerInvOnly && !(event.gui instanceof GuiInventory)) continue; + + int x = guiLeft+button.x; + int y = guiTop+button.y; + if(button.anchorRight) { + x += xSize; + } + if(button.anchorBottom) { + y += ySize; + } + + if(mouseX >= x && mouseX <= x+18 && mouseY >= y && mouseY <= y+18) { + if(Minecraft.getMinecraft().thePlayer.inventory.getItemStack() == null) { + int clickType = NotEnoughUpdates.INSTANCE.config.inventoryButtons.clickType; + if((clickType == 0 && Mouse.getEventButtonState()) || (clickType == 1 && !Mouse.getEventButtonState())) { + String command = button.command.trim(); + if(!command.startsWith("/")) { + command = "/" + command; + } + if(ClientCommandHandler.instance.executeCommand(Minecraft.getMinecraft().thePlayer, command) == 0) { + NotEnoughUpdates.INSTANCE.sendChatMessage(command); + } + } + } else { + event.setCanceled(true); + } + return; + } + } + } } ScheduledExecutorService ses = Executors.newScheduledThreadPool(1); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java index 061d6774..4f392ae8 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java @@ -17,6 +17,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.*; import net.minecraft.network.play.client.C0DPacketCloseWindow; import net.minecraft.util.ResourceLocation; +import org.apache.commons.io.FileUtils; import org.lwjgl.input.Keyboard; import org.lwjgl.opengl.Display; @@ -26,6 +27,8 @@ import java.net.URL; import java.net.URLConnection; import java.nio.charset.StandardCharsets; import java.util.*; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; @@ -57,10 +60,10 @@ public class NEUManager { private String currentProfileBackup = ""; public final HypixelApi hypixelApi = new HypixelApi(); - private ResourceLocation wkZip = new ResourceLocation("notenoughupdates:wkhtmltox.zip"); private Map<String, ItemStack> itemstackCache = new HashMap<>(); - //private static final String AUCTIONS_PRICE_URL = "https://moulberry.github.io/files/auc_avg_jsons/average_3day.json.gz"; + private ExecutorService repoLoaderES = Executors.newSingleThreadExecutor(); + private static final String GIT_COMMITS_URL = "https://api.github.com/repos/Moulberry/NotEnoughUpdates-REPO/commits/master"; private HashMap<String, Set<String>> usagesMap = new HashMap<>(); @@ -88,15 +91,6 @@ public class NEUManager { if(itemRenameJson == null) { itemRenameJson = new JsonObject(); } - - File wkShell = new File(configLocation, "wkhtmltox/bin/wkhtmltoimage"); - if(!wkShell.exists()) { - try { - InputStream is = Minecraft.getMinecraft().getResourceManager().getResource(wkZip).getInputStream(); - unzip(is, configLocation); - } catch (IOException e) { - } - } } public void setCurrentProfile(String currentProfile) { @@ -163,7 +157,7 @@ public class NEUManager { }*/ - Thread thread = new Thread(() -> { + repoLoaderES.submit(() -> { JDialog dialog = null; try { if(NotEnoughUpdates.INSTANCE.config.hidden.autoupdate) { @@ -211,12 +205,23 @@ public class NEUManager { } catch (IOException e) { return; } + + URL url = new URL(dlUrl); URLConnection urlConnection = url.openConnection(); urlConnection.setConnectTimeout(15000); - urlConnection.setReadTimeout(20000); - try (BufferedInputStream inStream = new BufferedInputStream(urlConnection.getInputStream()); - FileOutputStream fileOutputStream = new FileOutputStream(itemsZip)) { + urlConnection.setReadTimeout(30000); + + try(InputStream is = urlConnection.getInputStream()) { + FileUtils.copyInputStreamToFile(is, itemsZip); + } catch (IOException e) { + dialog.dispose(); + e.printStackTrace(); + System.err.println("Failed to download NEU Repo! Please report this issue to the mod creator"); + return; + } + /*try (BufferedInputStream inStream = new BufferedInputStream(urlConnection.getInputStream()); + FileOutputStream fileOutputStream = new FileOutputStream(itemsZip)) { byte dataBuffer[] = new byte[1024]; int bytesRead; while ((bytesRead = inStream.read(dataBuffer, 0, 1024)) != -1) { @@ -225,7 +230,7 @@ public class NEUManager { } catch (IOException e) { dialog.dispose(); return; - } + }*/ pane.setMessage("Unzipping NEU Master Archive."); dialog.pack(); @@ -242,6 +247,8 @@ public class NEUManager { } catch (IOException e) { } } + + Constants.reload(); } } catch(Exception e) { e.printStackTrace(); @@ -249,31 +256,40 @@ public class NEUManager { if(dialog != null) dialog.dispose(); } + System.err.println("First load"); + File items = new File(repoLocation, "items"); if(items.exists()) { File[] itemFiles = new File(repoLocation, "items").listFiles(); if(itemFiles != null) { for(File f : itemFiles) { String internalname = f.getName().substring(0, f.getName().length()-5); - if(!getItemInformation().keySet().contains(internalname)) { - loadItem(internalname); + synchronized(itemMap) { + if(!itemMap.keySet().contains(internalname)) { + loadItem(internalname); + } } } } } }); + System.err.println("Second load"); + File items = new File(repoLocation, "items"); if(items.exists()) { File[] itemFiles = new File(repoLocation, "items").listFiles(); if(itemFiles != null) { for(File f : itemFiles) { String internalname = f.getName().substring(0, f.getName().length()-5); - loadItem(internalname); + synchronized(itemMap) { + if(!itemMap.keySet().contains(internalname)) { + loadItem(internalname); + } + } } } } - thread.start(); } /** @@ -301,56 +317,69 @@ public class NEUManager { itemMap.put(internalName, json); if(json.has("recipe")) { - JsonObject recipe = json.get("recipe").getAsJsonObject(); - - String[] x = {"1","2","3"}; - String[] y = {"A","B","C"}; - for(int i=0; i<9; i++) { - String name = y[i/3]+x[i%3]; - String itemS = recipe.get(name).getAsString(); - if(itemS != null && itemS.split(":").length == 2) { - itemS = itemS.split(":")[0]; - } + synchronized(usagesMap) { + JsonObject recipe = json.get("recipe").getAsJsonObject(); + + String[] x = {"1","2","3"}; + String[] y = {"A","B","C"}; + for(int i=0; i<9; i++) { + String name = y[i/3]+x[i%3]; + String itemS = recipe.get(name).getAsString(); + if(itemS != null && itemS.split(":").length == 2) { + itemS = itemS.split(":")[0]; + } - if(!usagesMap.containsKey(itemS)) { - usagesMap.put(itemS, new HashSet<>()); + if(!usagesMap.containsKey(itemS)) { + usagesMap.put(itemS, new HashSet<>()); + } + usagesMap.get(itemS).add(internalName); } - usagesMap.get(itemS).add(internalName); } } if(json.has("displayname")) { - int wordIndex=0; - for(String str : json.get("displayname").getAsString().split(" ")) { - str = clean(str); - if(!titleWordMap.containsKey(str)) { - titleWordMap.put(str, new HashMap<>()); - } - if(!titleWordMap.get(str).containsKey(internalName)) { - titleWordMap.get(str).put(internalName, new ArrayList<>()); + synchronized(titleWordMap) { + int wordIndex=0; + for(String str : json.get("displayname").getAsString().split(" ")) { + str = clean(str); + if(!titleWordMap.containsKey(str)) { + titleWordMap.put(str, new HashMap<>()); + } + if(!titleWordMap.get(str).containsKey(internalName)) { + titleWordMap.get(str).put(internalName, new ArrayList<>()); + } + titleWordMap.get(str).get(internalName).add(wordIndex); + wordIndex++; } - titleWordMap.get(str).get(internalName).add(wordIndex); - wordIndex++; } } if(json.has("lore")) { - int wordIndex=0; - for(JsonElement element : json.get("lore").getAsJsonArray()) { - for(String str : element.getAsString().split(" ")) { - str = clean(str); - if(!loreWordMap.containsKey(str)) { - loreWordMap.put(str, new HashMap<>()); - } - if(!loreWordMap.get(str).containsKey(internalName)) { - loreWordMap.get(str).put(internalName, new ArrayList<>()); + synchronized(loreWordMap) { + int wordIndex=0; + for(JsonElement element : json.get("lore").getAsJsonArray()) { + for(String str : element.getAsString().split(" ")) { + str = clean(str); + if(!loreWordMap.containsKey(str)) { + loreWordMap.put(str, new HashMap<>()); + } + if(!loreWordMap.get(str).containsKey(internalName)) { + loreWordMap.get(str).put(internalName, new ArrayList<>()); + } + loreWordMap.get(str).get(internalName).add(wordIndex); + wordIndex++; } - loreWordMap.get(str).get(internalName).add(wordIndex); - wordIndex++; } } } } catch(Exception e) { + synchronized(loreWordMap) { + System.out.println("loreWordMap is : " + loreWordMap); + } + synchronized(titleWordMap) { + System.out.println("titleWordMap is : " + titleWordMap); + } + System.out.println("internalName is : " + internalName); e.printStackTrace(); } } @@ -1037,7 +1066,7 @@ public class NEUManager { /** * Modified from https://www.journaldev.com/960/java-unzip-file-example */ - private static void unzip(InputStream src, File dest) { + public static void unzip(InputStream src, File dest) { //buffer for read and write data to file byte[] buffer = new byte[1024]; try { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java index 689a98f1..d11d21fa 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java @@ -64,6 +64,8 @@ import static io.github.moulberry.notenoughupdates.util.GuiTextures.*; public class NEUOverlay extends Gui { private static final ResourceLocation SUPERGEHEIMNISVERMOGEN = new ResourceLocation("notenoughupdates:supersecretassets/bald.png"); + private static final ResourceLocation SEARCH_BAR = new ResourceLocation("notenoughupdates:search_bar.png"); + private static final ResourceLocation SEARCH_BAR_GOLD = new ResourceLocation("notenoughupdates:search_bar_gold.png"); private NEUManager manager; @@ -116,12 +118,15 @@ public class NEUOverlay extends Gui { private LerpingInteger itemPaneTabOffset = new LerpingInteger(20, 50); private LerpingFloat infoPaneOffsetFactor = new LerpingFloat(0); - private boolean searchMode = false; + public boolean searchMode = false; private long millisLastLeftClick = 0; private long millisLastMouseMove = 0; private int lastMouseX = 0; private int lastMouseY = 0; + public static final int overlayColourDark = new Color(0, 0, 0, 120).getRGB(); + public static final int overlayColourLight = new Color(255, 255, 255, 120).getRGB(); + boolean mouseDown = false; private boolean redrawItems = false; @@ -199,14 +204,51 @@ public class NEUOverlay extends Gui { FontRenderer fr = Minecraft.getMinecraft().fontRendererObj; int paddingUnscaled = getPaddingUnscaled(); - //Search bar background - drawRect((int)x, (int)y, - (int)x + getWidth(), (int)y + getHeight(), - searchMode ? Color.YELLOW.getRGB() : Color.WHITE.getRGB()); + GlStateManager.color(1, 1, 1, 1); + if(searchMode) { + Minecraft.getMinecraft().getTextureManager().bindTexture(SEARCH_BAR_GOLD); + } else { + Minecraft.getMinecraft().getTextureManager().bindTexture(SEARCH_BAR); + } + + int w = getWidth(); + int h = getHeight(); + + for(int yIndex=0; yIndex<=2; yIndex++) { + for(int xIndex=0; xIndex<=2; xIndex++) { + float uMin = 0; + float uMax = 4/20f; + int partX = (int)x; + int partW = 4; + if(xIndex == 1) { + partX += 4; + uMin = 4/20f; + uMax = 16/20f; + partW = w-8; + } else if(xIndex == 2) { + partX += w-4; + uMin = 16/20f; + uMax = 20/20f; + } - drawRect((int)x + paddingUnscaled, (int)y + paddingUnscaled, - (int)x - paddingUnscaled + getWidth(), (int)y - paddingUnscaled + getHeight(), - Color.BLACK.getRGB()); + float vMin = 0; + float vMax = 4/20f; + int partY = (int)y; + int partH = 4; + if(yIndex == 1) { + partY += 4; + vMin = 4/20f; + vMax = 16/20f; + partH = h-8; + } else if(yIndex == 2) { + partY += h-4; + vMin = 16/20f; + vMax = 20/20f; + } + + Utils.drawTexturedRect(partX, partY, partW, partH, uMin, uMax, vMin, vMax, GL11.GL_NEAREST); + } + } //Search bar text fr.drawString(textField.getText(), (int)x + 5, @@ -791,6 +833,10 @@ public class NEUOverlay extends Gui { return paddingUnscaled; } + public GuiTextField getTextField() { + return textField; + } + /** * Returns searchBarXSize, scaled by 0.8 if gui scale == AUTO. */ @@ -1521,52 +1567,6 @@ public class NEUOverlay extends Gui { GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); } - /** - * Renders black squares over the inventory to indicate items that do not match a specific search. (When searchMode - * is enabled) - */ - public void renderOverlay() { - int width = Utils.peekGuiScale().getScaledWidth(); - int height = Utils.peekGuiScale().getScaledHeight(); - int mouseX = Mouse.getX() * width / Minecraft.getMinecraft().displayWidth; - int mouseY = height - Mouse.getY() * height / Minecraft.getMinecraft().displayHeight - 1; - - if(searchMode && textField.getText().length() > 0) { - if(Minecraft.getMinecraft().currentScreen instanceof GuiContainer) { - GuiContainer inv = (GuiContainer) Minecraft.getMinecraft().currentScreen; - int guiLeftI = (int)Utils.getField(GuiContainer.class, inv, "guiLeft", "field_147003_i"); - int guiTopI = (int)Utils.getField(GuiContainer.class, inv, "guiTop", "field_147009_r"); - - GL11.glTranslatef(0, 0, 260); - int overlay = new Color(0, 0, 0, 100).getRGB(); - for(Slot slot : inv.inventorySlots.inventorySlots) { - boolean matches = false; - for(String search : textField.getText().split("\\|")) { - matches |= slot.getStack() != null && manager.doesStackMatchSearch(slot.getStack(), search.trim()); - } - if(!matches) { - drawRect(guiLeftI+slot.xDisplayPosition, guiTopI+slot.yDisplayPosition, - guiLeftI+slot.xDisplayPosition+16, guiTopI+slot.yDisplayPosition+16, - overlay); - } - } - if(Utils.getSlotUnderMouse(inv) != null) { - ItemStack stack = Utils.getSlotUnderMouse(inv).getStack(); - //Minecraft.getMinecraft().currentScreen.renderToolTip(stack, mouseX, mouseY); - Class<?>[] params = new Class[]{ItemStack.class, int.class, int.class}; - Method renderToolTip = Utils.getMethod(GuiScreen.class, params, "renderToolTip", "func_146285_a"); - if(renderToolTip != null) { - renderToolTip.setAccessible(true); - try { - renderToolTip.invoke(Minecraft.getMinecraft().currentScreen, stack, mouseX, mouseY); - } catch(Exception e) {} - } - } - GL11.glTranslatef(0, 0, -260); - } - } - } - Shader blurShaderHorz = null; Framebuffer blurOutputHorz = null; Shader blurShaderVert = null; @@ -1729,13 +1729,15 @@ public class NEUOverlay extends Gui { //Atomic reference used so that below lambda doesn't complain about non-effectively-final variable AtomicReference<JsonObject> tooltipToDisplay = new AtomicReference<>(null); if(itemPaneOffsetFactor.getValue() < 1) { - BackgroundBlur.renderBlurredBackground(NotEnoughUpdates.INSTANCE.config.itemlist.bgBlurFactor, - width, height, - leftSide+getBoxPadding()-5, getBoxPadding()-5, - paneWidth-getBoxPadding()*2+10, height-getBoxPadding()*2+10, true); - Gui.drawRect(leftSide+getBoxPadding()-5, getBoxPadding()-5, - leftSide+getBoxPadding()-5+paneWidth-getBoxPadding()*2+10, - getBoxPadding()-5+height-getBoxPadding()*2+10, 0xc8101010); + if(NotEnoughUpdates.INSTANCE.config.itemlist.bgBlurFactor > 0.5) { + BackgroundBlur.renderBlurredBackground(NotEnoughUpdates.INSTANCE.config.itemlist.bgBlurFactor, + width, height, + leftSide+getBoxPadding()-5, getBoxPadding()-5, + paneWidth-getBoxPadding()*2+10, height-getBoxPadding()*2+10, true); + Gui.drawRect(leftSide+getBoxPadding()-5, getBoxPadding()-5, + leftSide+getBoxPadding()-5+paneWidth-getBoxPadding()*2+10, + getBoxPadding()-5+height-getBoxPadding()*2+10, 0xc8101010); + } drawRect(leftSide+getBoxPadding()-5, getBoxPadding()-5, leftSide+paneWidth-getBoxPadding()+5, height-getBoxPadding()+5, bg.getRGB()); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java index 59c821b0..2da79f84 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java @@ -18,10 +18,7 @@ import io.github.moulberry.notenoughupdates.gamemodes.GuiGamemodes; import io.github.moulberry.notenoughupdates.gamemodes.SBGamemodes; import io.github.moulberry.notenoughupdates.infopanes.CollectionLogInfoPane; import io.github.moulberry.notenoughupdates.miscfeatures.*; -import io.github.moulberry.notenoughupdates.miscgui.CalendarOverlay; -import io.github.moulberry.notenoughupdates.miscgui.GuiEnchantColour; -import io.github.moulberry.notenoughupdates.miscgui.HelpGUI; -import io.github.moulberry.notenoughupdates.miscgui.NEUOverlayPlacements; +import io.github.moulberry.notenoughupdates.miscgui.*; import io.github.moulberry.notenoughupdates.options.NEUConfig; import io.github.moulberry.notenoughupdates.options.NEUConfigEditor; import io.github.moulberry.notenoughupdates.overlays.FuelBar; @@ -35,6 +32,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.EntityPlayerSP; import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.client.gui.inventory.GuiInventory; @@ -123,6 +121,32 @@ public class NotEnoughUpdates { } }); + SimpleCommand nullzeeSphereCommand = new SimpleCommand("neuzeesphere", new SimpleCommand.ProcessCommandRunnable() { + public void processCommand(ICommandSender sender, String[] args) { + if(args.length != 1) { + sender.addChatMessage(new ChatComponentText(EnumChatFormatting.RED+"Usage: /neuzeesphere [on/off] or /neuzeesphere (radius) or /neuzeesphere setCenter")); + return; + } + if(args[0].equalsIgnoreCase("on")) { + NullzeeSphere.enabled = true; + } else if(args[0].equalsIgnoreCase("off")) { + NullzeeSphere.enabled = false; + } else if(args[0].equalsIgnoreCase("setCenter")) { + EntityPlayerSP p = ((EntityPlayerSP)sender); + NullzeeSphere.centerPos = new BlockPos(p.posX, p.posY, p.posZ); + NullzeeSphere.overlayVBO = null; + } else { + try { + float radius = Float.parseFloat(args[0]); + NullzeeSphere.size = radius; + NullzeeSphere.overlayVBO = null; + } catch(Exception e) { + sender.addChatMessage(new ChatComponentText(EnumChatFormatting.RED+"Can't parse radius: " + args[0])); + } + } + } + }); + SimpleCommand itemRenameCommand = new SimpleCommand("neurename", new SimpleCommand.ProcessCommandRunnable() { public void processCommand(ICommandSender sender, String[] args) { if(args.length == 0) { @@ -215,6 +239,12 @@ public class NotEnoughUpdates { } }); + SimpleCommand buttonsCommand = new SimpleCommand("neubuttons", new SimpleCommand.ProcessCommandRunnable() { + public void processCommand(ICommandSender sender, String[] args) { + openGui = new GuiInvButtonEditor(); + } + }); + SimpleCommand enchantColourCommand = new SimpleCommand("neuec", new SimpleCommand.ProcessCommandRunnable() { public void processCommand(ICommandSender sender, String[] args) { openGui = new GuiEnchantColour(); @@ -250,6 +280,13 @@ public class NotEnoughUpdates { } } Constants.reload(); + + configFile = new File(neuDir, "configNew.json"); + if(configFile.exists()) { + try(BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(configFile), StandardCharsets.UTF_8))) { + config = gson.fromJson(reader, NEUConfig.class); + } catch(Exception e) { } + } } }); @@ -690,7 +727,14 @@ public class NotEnoughUpdates { Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED+devFailStrings[devFailIndex++])); return; } - if(args.length == 1 && args[0].equalsIgnoreCase("dev")) NotEnoughUpdates.INSTANCE.config.hidden.dev = true; + if(args.length == 1 && args[0].equalsIgnoreCase("dev")) { + NotEnoughUpdates.INSTANCE.config.hidden.dev = true; + return; + } + if(args.length == 1 && args[0].equalsIgnoreCase("saveconfig")) { + saveConfig(); + return; + } Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.GREEN+"Executing dubious code")); /*Minecraft.getMinecraft().thePlayer.rotationYaw = 0; Minecraft.getMinecraft().thePlayer.rotationPitch = 0; @@ -991,15 +1035,18 @@ public class NotEnoughUpdates { MinecraftForge.EVENT_BUS.register(XPInformation.getInstance()); MinecraftForge.EVENT_BUS.register(OverlayManager.petInfoOverlay); MinecraftForge.EVENT_BUS.register(OverlayManager.timersOverlay); + MinecraftForge.EVENT_BUS.register(new NullzeeSphere()); if(Minecraft.getMinecraft().getResourceManager() instanceof IReloadableResourceManager) { ((IReloadableResourceManager)Minecraft.getMinecraft().getResourceManager()).registerReloadListener(CustomSkulls.getInstance()); } ClientCommandHandler.instance.registerCommand(collectionLogCommand); + ClientCommandHandler.instance.registerCommand(nullzeeSphereCommand); ClientCommandHandler.instance.registerCommand(cosmeticsCommand); ClientCommandHandler.instance.registerCommand(linksCommand); ClientCommandHandler.instance.registerCommand(gamemodesCommand); + ClientCommandHandler.instance.registerCommand(buttonsCommand); ClientCommandHandler.instance.registerCommand(resetRepoCommand); ClientCommandHandler.instance.registerCommand(reloadRepoCommand); ClientCommandHandler.instance.registerCommand(itemRenameCommand); 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 b2f947d6..111803e8 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/GuiElementTextField.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/GuiElementTextField.java @@ -2,6 +2,7 @@ package io.github.moulberry.notenoughupdates.core; import io.github.moulberry.notenoughupdates.core.util.StringUtils; import io.github.moulberry.notenoughupdates.core.util.render.TextRenderUtils; +import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Gui; import net.minecraft.client.gui.GuiScreen; @@ -462,14 +463,21 @@ public class GuiElementTextField { String selectedText = textField.getSelectedText(); if(!selectedText.isEmpty()) { + System.out.println("Start"); int leftIndex = Math.min(textField.getCursorPosition()+prependText.length(), textField.getSelectionEnd()+prependText.length()); int rightIndex = Math.max(textField.getCursorPosition()+prependText.length(), textField.getSelectionEnd()+prependText.length()); float texX = 0; int texY = 0; boolean sectionSignPrev = false; + boolean ignoreNext = false; boolean bold = false; for(int i=0; i<textNoColor.length(); i++) { + if(ignoreNext) { + ignoreNext = false; + continue; + } + char c = textNoColor.charAt(i); if(sectionSignPrev) { if(c != 'k' && c != 'K' @@ -478,9 +486,13 @@ public class GuiElementTextField { && c != 'o' && c != 'O') { bold = c == 'l' || c == 'L'; } + sectionSignPrev = false; + if(i < prependText.length()) continue; + } + if(c == '\u00B6') { + sectionSignPrev = true; + if(i < prependText.length()) continue; } - sectionSignPrev = false; - if(c == '\u00B6') sectionSignPrev = true; if(c == '\n') { if(i >= leftIndex && i < rightIndex) { @@ -497,6 +509,7 @@ public class GuiElementTextField { //String c2 = bold ? EnumChatFormatting.BOLD.toString() : "" + c; + System.out.println("Adding len for char:"+c+":"+Integer.toHexString(c)); int len = Minecraft.getMinecraft().fontRendererObj.getStringWidth(String.valueOf(c)); if(bold) len++; if(i >= leftIndex && i < rightIndex) { 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 963b91c3..21f6baaf 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/CapeManager.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/CapeManager.java @@ -48,8 +48,11 @@ public class CapeManager { public JsonObject lastJsonSync = null; private String[] capes = new String[]{"patreon1", "patreon2", "fade", "contrib", "nullzee", - "gravy", "space", "mcworld", "lava", "packshq", "mbstaff", "thebakery", "negative", "void", "ironmoon", "krusty", "furf", "soldier", "dsm" }; - public Boolean[] specialCapes = new Boolean[]{ true, true, false, true, true, true, false, false, false, true, true, true, false, false, true, false, true, true, true }; + "gravy", "space", "mcworld", "lava", "packshq", "mbstaff", "thebakery", "negative", + "void", "ironmoon", "krusty", "furf", "soldier", "dsm", "zera", "tunnel", "alexxoffi", "parallax", "jakethybro", "planets" }; + 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 }; public static CapeManager getInstance() { return INSTANCE; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/CapeNode.java b/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/CapeNode.java index b01365d3..06bc6db4 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/CapeNode.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/CapeNode.java @@ -31,6 +31,10 @@ public class CapeNode { public Vector3f sideNormal = null; public boolean fixed = false; + public static final int DRAW_MASK_FRONT = 0b1; + public static final int DRAW_MASK_BACK = 0b10; + public static final int DRAW_MASK_SIDES = 0b100; + public HashMap<NEUCape.Offset, CapeNode> neighbors = new HashMap<>(); public float texU = 0; @@ -279,6 +283,10 @@ public class CapeNode { } public void renderNode() { + renderNode(DRAW_MASK_FRONT | DRAW_MASK_BACK | DRAW_MASK_SIDES); + } + + public void renderNode(int mask) { CapeNode nodeLeft = getNeighbor(new NEUCape.Offset(NEUCape.Direction.LEFT, 1)); CapeNode nodeUp = getNeighbor(new NEUCape.Offset(NEUCape.Direction.UP, 1)); CapeNode nodeDown = getNeighbor(new NEUCape.Offset(NEUCape.Direction.DOWN, 1)); @@ -290,36 +298,42 @@ public class CapeNode { if(nodeDown != null && nodeRight != null && nodeDownRight != null) { //Back - worldrenderer.begin(GL11.GL_TRIANGLE_STRIP, DefaultVertexFormats.POSITION_TEX_NORMAL); - for(CapeNode node : new CapeNode[]{this, nodeDown, nodeRight, nodeDownRight}) { - Vector3f nodeNorm = node.normal(); - worldrenderer.pos(node.renderPosition.x, node.renderPosition.y, node.renderPosition.z) - .tex(1-node.texU, node.texV) - .normal(-nodeNorm.x, -nodeNorm.y, -nodeNorm.z).endVertex(); + if((mask & DRAW_MASK_BACK) != 0) { + worldrenderer.begin(GL11.GL_TRIANGLE_STRIP, DefaultVertexFormats.POSITION_TEX_NORMAL); + for(CapeNode node : new CapeNode[]{this, nodeDown, nodeRight, nodeDownRight}) { + Vector3f nodeNorm = node.normal(); + worldrenderer.pos(node.renderPosition.x, node.renderPosition.y, node.renderPosition.z) + .tex(1-node.texU, node.texV) + .normal(-nodeNorm.x, -nodeNorm.y, -nodeNorm.z).endVertex(); + } + tessellator.draw(); } - tessellator.draw(); //Front (Offset by normal) - worldrenderer.begin(GL11.GL_TRIANGLE_STRIP, DefaultVertexFormats.POSITION_TEX_NORMAL); - for(CapeNode node : new CapeNode[]{this, nodeDown, nodeRight, nodeDownRight}) { - Vector3f nodeNorm = node.normal(); - worldrenderer.pos(node.renderPosition.x+nodeNorm.x*0.05f, node.renderPosition.y+nodeNorm.y*0.05f, node.renderPosition.z+nodeNorm.z*0.05f) - .tex(node.texU, node.texV) - .normal(nodeNorm.x, nodeNorm.y, nodeNorm.z).endVertex(); + if((mask & DRAW_MASK_FRONT) != 0) { + worldrenderer.begin(GL11.GL_TRIANGLE_STRIP, DefaultVertexFormats.POSITION_TEX_NORMAL); + for(CapeNode node : new CapeNode[]{nodeDownRight, nodeDown, nodeRight, this}) { + Vector3f nodeNorm = node.normal(); + worldrenderer.pos(node.renderPosition.x+nodeNorm.x*0.05f, node.renderPosition.y+nodeNorm.y*0.05f, node.renderPosition.z+nodeNorm.z*0.05f) + .tex(node.texU, node.texV) + .normal(nodeNorm.x, nodeNorm.y, nodeNorm.z).endVertex(); + } + tessellator.draw(); } - tessellator.draw(); } - if(nodeLeft == null || nodeRight == null) { - //Render left/right edge - if(nodeDown != null) { - renderEdge(nodeDown, true); + if((mask & DRAW_MASK_SIDES) != 0) { + if(nodeLeft == null || nodeRight == null) { + //Render left/right edge + if(nodeDown != null) { + renderEdge(nodeDown, true); + } } - } - if(nodeUp == null || nodeDown == null) { - //Render up/down edge - if(nodeRight != null) { - renderEdge(nodeRight, false); + if(nodeUp == null || nodeDown == null) { + //Render up/down edge + if(nodeRight != null) { + renderEdge(nodeRight, false); + } } } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/GuiCosmetics.java b/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/GuiCosmetics.java index d0651075..164dfeb8 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/GuiCosmetics.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/GuiCosmetics.java @@ -269,7 +269,7 @@ public class GuiCosmetics extends GuiScreen { if(mouseY > guiTop+sizeY+5 && mouseY < guiTop+sizeY+25) { if(System.currentTimeMillis() - lastCapeEquip > 20*1000) { CapeManager.INSTANCE.setCape(Minecraft.getMinecraft().thePlayer.getUniqueID().toString().replace("-", ""), - null, true); + wantToEquipCape, true); lastCapeEquip = System.currentTimeMillis(); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/NEUCape.java b/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/NEUCape.java index b2d220c8..163b14dd 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/NEUCape.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/NEUCape.java @@ -1,7 +1,9 @@ package io.github.moulberry.notenoughupdates.cosmetics; import io.github.moulberry.notenoughupdates.core.util.lerp.LerpUtils; +import io.github.moulberry.notenoughupdates.util.ReverseWorldRenderer; import io.github.moulberry.notenoughupdates.util.TexLoc; +import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.block.Block; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.GlStateManager; @@ -9,6 +11,8 @@ import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.WorldRenderer; import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.client.renderer.vertex.VertexFormat; +import net.minecraft.client.renderer.vertex.VertexFormatElement; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; @@ -16,6 +20,7 @@ import net.minecraft.potion.Potion; import net.minecraft.util.BlockPos; import net.minecraft.util.MathHelper; import net.minecraft.util.ResourceLocation; +import net.minecraft.util.Vec3; import net.minecraft.world.gen.NoiseGeneratorSimplex; import net.minecraftforge.client.event.RenderPlayerEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; @@ -27,6 +32,7 @@ import org.lwjgl.opengl.*; import org.lwjgl.util.vector.Vector2f; import org.lwjgl.util.vector.Vector3f; +import java.nio.ByteBuffer; import java.nio.FloatBuffer; import java.nio.IntBuffer; import java.security.Key; @@ -45,7 +51,7 @@ public class NEUCape { private static int ANIM_MODE_PINGPONG = 1; private int animMode = ANIM_MODE_LOOP; - private List<List<CapeNode>> nodes = null; + private CapeNode[] nodes = null; private Random random = new Random(); @@ -60,7 +66,7 @@ public class NEUCape { public static final int HORZ_NODES = 6; public static final int VERT_NODES = 22; - public static float targetDist = 1/20f; + public static float targetDist = 1 / 20f; private EntityPlayer currentPlayer; private boolean keepCurrentPlayer = false; @@ -93,11 +99,15 @@ public class NEUCape { shaderName = "negative"; } else if(capeName.equalsIgnoreCase("void")) { shaderName = "void"; + } else if(capeName.equalsIgnoreCase("tunnel")) { + shaderName = "tunnel"; + } else if(capeName.equalsIgnoreCase("planets")) { + shaderName = "planets"; } else { shaderName = "shiny_cape"; } - ResourceLocation staticCapeTex = new ResourceLocation("notenoughupdates:capes/"+capeName+".png"); + ResourceLocation staticCapeTex = new ResourceLocation("notenoughupdates:capes/" + capeName + ".png"); capeTextures = new ResourceLocation[1]; capeTextures[0] = staticCapeTex; @@ -128,17 +138,17 @@ public class NEUCape { if(CapeManager.getInstance().backgroundFramebuffer != null) { CapeManager.getInstance().backgroundFramebuffer.bindFramebufferTexture(); } - } else if(capeTextures != null && capeTextures.length>0) { + } else if(capeTextures != null && capeTextures.length > 0) { long currentTime = System.currentTimeMillis(); if(currentTime - lastFrameUpdate > 100) { - lastFrameUpdate = currentTime/100*100; + lastFrameUpdate = currentTime / 100 * 100; currentFrame++; if(animMode == ANIM_MODE_PINGPONG) { if(capeTextures.length == 1) { currentFrame = displayFrame = 0; } else { - int frameCount = 2*capeTextures.length-2; + int frameCount = 2 * capeTextures.length - 2; currentFrame %= frameCount; displayFrame = currentFrame; if(currentFrame >= capeTextures.length) { @@ -154,80 +164,72 @@ public class NEUCape { } } - public boolean rlExists(ResourceLocation loc) { - try { - return !Minecraft.getMinecraft().getResourceManager().getAllResources(loc).isEmpty(); - } catch(Exception e) { - return false; - } + private CapeNode getNode(int x, int y) { + return nodes[x + y * HORZ_NODES]; } public void createCapeNodes(EntityPlayer player) { - nodes = new ArrayList<>(); + nodes = new CapeNode[HORZ_NODES * VERT_NODES]; - float pX = (float)player.posX % 7789; - float pY = (float)player.posY; - float pZ = (float)player.posZ % 7789; + float pX = (float) player.posX % 7789; + float pY = (float) player.posY; + float pZ = (float) player.posZ % 7789; - float uMinTop = 48/1024f; - float uMaxTop = 246/1024f; - float uMinBottom = 0/1024f; - float uMaxBottom = 293/1024f; + float uMinTop = 48 / 1024f; + float uMaxTop = 246 / 1024f; + float uMinBottom = 0 / 1024f; + float uMaxBottom = 293 / 1024f; - float vMaxSide = 404/1024f; - float vMaxCenter = 419/1024f; + float vMaxSide = 404 / 1024f; + float vMaxCenter = 419 / 1024f; - for(int i=0; i<VERT_NODES; i++) { - float uMin = uMinTop + (uMinBottom - uMinTop) * i/(float)(VERT_NODES-1); - float uMax = uMaxTop + (uMaxBottom - uMaxTop) * i/(float)(VERT_NODES-1); + for(int i = 0; i < VERT_NODES; i++) { + float uMin = uMinTop + (uMinBottom - uMinTop) * i / (float) (VERT_NODES - 1); + float uMax = uMaxTop + (uMaxBottom - uMaxTop) * i / (float) (VERT_NODES - 1); - List<CapeNode> row = new ArrayList<>(); - for(int j=0; j<HORZ_NODES; j++) { + for(int j = 0; j < HORZ_NODES; j++) { float vMin = 0f; - float centerMult = 1-Math.abs(j-(HORZ_NODES-1)/2f)/((HORZ_NODES-1)/2f);//0-(horzCapeNodes) -> 0-1-0 + float centerMult = 1 - Math.abs(j - (HORZ_NODES - 1) / 2f) / ((HORZ_NODES - 1) / 2f);//0-(horzCapeNodes) -> 0-1-0 float vMax = vMaxSide + (vMaxCenter - vMaxSide) * centerMult; CapeNode node = new CapeNode(pX, pY, pZ);//pX-1, pY+2-i*targetDist, pZ+(j-(horzCapeNodes-1)/2f)*targetDist*2 - node.texU = uMin + (uMax - uMin) * j/(float)(HORZ_NODES-1); - node.texV = vMin + (vMax - vMin) * i/(float)(VERT_NODES-1); + node.texU = uMin + (uMax - uMin) * j / (float) (HORZ_NODES - 1); + node.texV = vMin + (vMax - vMin) * i / (float) (VERT_NODES - 1); - node.horzDistMult = 2f+1f*i/(float)(VERT_NODES-1); + node.horzDistMult = 2f + 1f * i / (float) (VERT_NODES - 1); - if(j == 0 || j == HORZ_NODES-1) { - node.horzSideTexU = 406/1024f * i/(float)(VERT_NODES-1); + if(j == 0 || j == HORZ_NODES - 1) { + node.horzSideTexU = 406 / 1024f * i / (float) (VERT_NODES - 1); if(j == 0) { - node.horzSideTexVTop = 1 - 20/1024f; + node.horzSideTexVTop = 1 - 20 / 1024f; } else { - node.horzSideTexVTop = 1 - 40/1024f; + node.horzSideTexVTop = 1 - 40 / 1024f; } } if(i == 0) { - node.vertSideTexU = 198/1024f * j/(float)(HORZ_NODES-1); - node.vertSideTexVTop = 1 - 60/1024f; - } else if(i == VERT_NODES-1) { - node.vertSideTexU = 300/1024f * j/(float)(HORZ_NODES-1); - node.vertSideTexVTop = 1 - 80/1024f; + node.vertSideTexU = 198 / 1024f * j / (float) (HORZ_NODES - 1); + node.vertSideTexVTop = 1 - 60 / 1024f; + } else if(i == VERT_NODES - 1) { + node.vertSideTexU = 300 / 1024f * j / (float) (HORZ_NODES - 1); + node.vertSideTexVTop = 1 - 80 / 1024f; } - row.add(node); + nodes[j + i * HORZ_NODES] = node; } - - nodes.add(row); } - for(int y=0; y<nodes.size(); y++) { - int xSize = nodes.get(y).size(); - for(int x=0; x<xSize; x++) { - CapeNode node = nodes.get(y).get(x); + for(int y = 0; y < VERT_NODES; y++) { + for(int x = 0; x < HORZ_NODES; x++) { + CapeNode node = nodes[x + y * HORZ_NODES]; for(Direction dir : Direction.values()) { - for(int i=1; i<=2; i++) { + for(int i = 1; i <= 2; i++) { Offset offset = new Offset(dir, i); - int xNeighbor = x+offset.getXOffset(); - int yNeighbor = y+offset.getYOffset(); + int xNeighbor = x + offset.getXOffset(); + int yNeighbor = y + offset.getYOffset(); - if(xNeighbor >= 0 && xNeighbor < nodes.get(y).size() - && yNeighbor >= 0 && yNeighbor < nodes.size()) { - CapeNode neighbor = nodes.get(yNeighbor).get(xNeighbor); + if(xNeighbor >= 0 && xNeighbor < HORZ_NODES + && yNeighbor >= 0 && yNeighbor < VERT_NODES) { + CapeNode neighbor = nodes[xNeighbor + yNeighbor * HORZ_NODES]; node.setNeighbor(offset, neighbor); } } @@ -291,11 +293,11 @@ public class NEUCape { } public int getXOffset() { - return direction.xOff*steps; + return direction.xOff * steps; } public int getYOffset() { - return direction.yOff*steps; + return direction.yOff * steps; } public boolean equals(Object obj) { @@ -308,27 +310,27 @@ public class NEUCape { @Override public int hashCode() { - return 13*direction.ordinal() + 7*steps; + return 13 * direction.ordinal() + 7 * steps; } } private void loadShaderUniforms(ShaderManager shaderManager) { - String shaderId = "capes/"+shaderName+"/"+shaderName; - if(shaderName.equalsIgnoreCase("fade_cape")) { - shaderManager.loadData(shaderId, "millis", (int)(System.currentTimeMillis()-startTime)); + String shaderId = "capes/" + shaderName + "/" + shaderName; + if(shaderName.equalsIgnoreCase("fade_cape") || shaderName.equalsIgnoreCase("planets")) { + shaderManager.loadData(shaderId, "millis", (int) (System.currentTimeMillis() - startTime)); } else if(shaderName.equalsIgnoreCase("space_cape")) { - shaderManager.loadData(shaderId, "millis", (int)(System.currentTimeMillis()-startTime)); - shaderManager.loadData(shaderId, "eventMillis", (int)(System.currentTimeMillis()-eventMillis)); + shaderManager.loadData(shaderId, "millis", (int) (System.currentTimeMillis() - startTime)); + shaderManager.loadData(shaderId, "eventMillis", (int) (System.currentTimeMillis() - eventMillis)); shaderManager.loadData(shaderId, "eventRand", eventRandom); } else if(shaderName.equalsIgnoreCase("mcworld_cape")) { shaderManager.loadData(shaderId, "millis", (int) (System.currentTimeMillis() - startTime)); } else if(shaderName.equalsIgnoreCase("lava_cape")) { shaderManager.loadData(shaderId, "millis", (int) (System.currentTimeMillis() - startTime)); - } else if(shaderName.equalsIgnoreCase("lightning_cape")) { + } else if(shaderName.equalsIgnoreCase("tunnel")) { shaderManager.loadData(shaderId, "millis", (int) (System.currentTimeMillis() - startTime)); } else if(shaderName.equalsIgnoreCase("biscuit_cape") || shaderName.equalsIgnoreCase("shiny_cape")) { shaderManager.loadData(shaderId, "millis", (int) (System.currentTimeMillis() - startTime)); - shaderManager.loadData(shaderId, "eventMillis", (int)(System.currentTimeMillis()-eventMillis)); + shaderManager.loadData(shaderId, "eventMillis", (int) (System.currentTimeMillis() - eventMillis)); } else if(shaderName.equalsIgnoreCase("negative")) { shaderManager.loadData(shaderId, "screensize", new Vector2f( Minecraft.getMinecraft().displayWidth, @@ -344,6 +346,7 @@ public class NEUCape { } long lastRender = 0; + public void onRenderPlayer(RenderPlayerEvent.Post e) { EntityPlayer player = e.entityPlayer; @@ -378,21 +381,23 @@ public class NEUCape { GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST); } - GL11.glTranslatef(-(float)viewerX, -(float)viewerY, -(float)viewerZ); + GL11.glTranslatef(-(float) viewerX, -(float) viewerY, -(float) viewerZ); ShaderManager shaderManager = ShaderManager.getInstance(); - shaderManager.loadShader("capes/"+shaderName+"/"+shaderName); + shaderManager.loadShader("capes/" + shaderName + "/" + shaderName); loadShaderUniforms(shaderManager); renderCape(player, e.partialRenderTick); - GL11.glTranslatef((float)viewerX, (float)viewerY, (float)viewerZ); + GL11.glTranslatef((float) viewerX, (float) viewerY, (float) viewerZ); GL20.glUseProgram(0); GlStateManager.enableCull(); GlStateManager.enableTexture2D(); GlStateManager.disableBlend(); + GlStateManager.enableDepth(); + GlStateManager.enableLighting(); GlStateManager.popMatrix(); lastRender = System.currentTimeMillis(); @@ -412,9 +417,9 @@ public class NEUCape { ensureCapeNodesCreated(player); - for(int y=0; y<nodes.size(); y++) { - for(int x=0; x<nodes.get(y).size(); x++) { - CapeNode node = nodes.get(y).get(x); + for(int y = 0; y < VERT_NODES; y++) { + for(int x = 0; x < HORZ_NODES; x++) { + CapeNode node = nodes[x + y * HORZ_NODES]; node.lastPosition.x = node.position.x; node.lastPosition.y = node.position.y; node.lastPosition.z = node.position.z; @@ -429,9 +434,11 @@ public class NEUCape { private static double interpolateRotation(float a, float b, float amount) { double f; - for (f = b - a; f < -180.0F; f += 360.0F) {;} + for(f = b - a; f < -180.0F; f += 360.0F) { + ; + } - while (f >= 180.0F) { + while(f >= 180.0F) { f -= 360.0F; } @@ -475,22 +482,21 @@ public class NEUCape { double vertOffset2 = vertOffset + (player.isSneaking() ? -0.22f : 0) + (player.getCurrentArmor(2) != null ? 0.06f : 0); double shoulderWidth2 = shoulderWidth + (player.getCurrentArmor(2) != null ? 0.08f : 0); - float xOff = (float)(Math.cos(angle)*shoulderLength); - float zOff = (float)(Math.sin(angle)*shoulderLength); + float xOff = (float) (Math.cos(angle) * shoulderLength); + float zOff = (float) (Math.sin(angle) * shoulderLength); float totalDX = 0; float totalDY = 0; float totalDZ = 0; int totalMovements = 0; - int xSize = nodes.get(0).size(); - for(int i=0; i<xSize; i++) { - float mult = 1 - 2f*i/(xSize-1); //1 -> -1 - float widthMult = 1.25f-(1.414f*i/(xSize-1) - 0.707f)*(1.414f*i/(xSize-1) - 0.707f); - CapeNode node = nodes.get(0).get(i); - float x = (float)pX+(float)(xOff*mult-widthMult*Math.cos(angle+Math.PI/2)*shoulderWidth2); - float y = (float)pY+(float)(vertOffset2); - float z = (float)pZ+(float)(zOff*mult-widthMult*Math.sin(angle+Math.PI/2)*shoulderWidth2); + for(int i = 0; i < HORZ_NODES; i++) { + float mult = 1 - 2f * i / (HORZ_NODES - 1); //1 -> -1 + float widthMult = 1.25f - (1.414f * i / (HORZ_NODES - 1) - 0.707f) * (1.414f * i / (HORZ_NODES - 1) - 0.707f); + CapeNode node = nodes[i]; + float x = (float) pX + (float) (xOff * mult - widthMult * Math.cos(angle + Math.PI / 2) * shoulderWidth2); + float y = (float) pY + (float) (vertOffset2); + float z = (float) pZ + (float) (zOff * mult - widthMult * Math.sin(angle + Math.PI / 2) * shoulderWidth2); totalDX += x - node.position.x; totalDY += y - node.position.y; totalDZ += z - node.position.z; @@ -501,9 +507,9 @@ public class NEUCape { node.fixed = true; } - float avgDX = totalDX/totalMovements; - float avgDY = totalDY/totalMovements; - float avgDZ = totalDZ/totalMovements; + float avgDX = totalDX / totalMovements; + float avgDY = totalDY / totalMovements; + float avgDZ = totalDZ / totalMovements; return new Vector3f(avgDX, avgDY, avgDZ); } @@ -517,17 +523,16 @@ public class NEUCape { double vertOffset2 = vertOffset + (player.isSneaking() ? -0.22f : 0) + (player.getCurrentArmor(2) != null ? 0.06f : 0); double shoulderWidth2 = shoulderWidth + (player.getCurrentArmor(2) != null ? 0.08f : 0); - float xOff = (float)(Math.cos(angle)*shoulderLength); - float zOff = (float)(Math.sin(angle)*shoulderLength); - - int xSize = nodes.get(0).size(); - for(int i=0; i<xSize; i++) { - float mult = 1 - 2f*i/(xSize-1); //1 -> -1 - float widthMult = 1.25f-(1.414f*i/(xSize-1) - 0.707f)*(1.414f*i/(xSize-1) - 0.707f); - CapeNode node = nodes.get(0).get(i); - node.renderPosition.x = (float)pX+(float)(xOff*mult-widthMult*Math.cos(angle+Math.PI/2)*shoulderWidth2); - node.renderPosition.y = (float)pY+(float)(vertOffset2); - node.renderPosition.z = (float)pZ+(float)(zOff*mult-widthMult*Math.sin(angle+Math.PI/2)*shoulderWidth2); + float xOff = (float) (Math.cos(angle) * shoulderLength); + float zOff = (float) (Math.sin(angle) * shoulderLength); + + for(int i = 0; i < HORZ_NODES; i++) { + float mult = 1 - 2f * i / (HORZ_NODES - 1); //1 -> -1 + float widthMult = 1.25f - (1.414f * i / (HORZ_NODES - 1) - 0.707f) * (1.414f * i / (HORZ_NODES - 1) - 0.707f); + CapeNode node = nodes[i]; + node.renderPosition.x = (float) pX + (float) (xOff * mult - widthMult * Math.cos(angle + Math.PI / 2) * shoulderWidth2); + node.renderPosition.y = (float) pY + (float) (vertOffset2); + node.renderPosition.z = (float) pZ + (float) (zOff * mult - widthMult * Math.sin(angle + Math.PI / 2) * shoulderWidth2); node.fixed = true; } } @@ -536,57 +541,58 @@ public class NEUCape { private double oldPlayerAngle; private int crouchTicks = 0; long startTime = 0; + private void updateCape(EntityPlayer player) { Vector3f capeTranslation = updateFixedCapeNodes(player); if(shaderName.equals("space_cape")) { long currentTime = System.currentTimeMillis(); - if(currentTime-startTime > eventMillis-startTime+eventLength) { + if(currentTime - startTime > eventMillis - startTime + eventLength) { eventMillis = currentTime; - eventLength = random.nextFloat()*2000+4000; + eventLength = random.nextFloat() * 2000 + 4000; eventRandom = random.nextFloat(); } } else if(shaderName.equals("biscuit_cape") || shaderName.equals("shiny_cape")) { long currentTime = System.currentTimeMillis(); - if(currentTime-startTime > eventMillis-startTime+eventLength) { + if(currentTime - startTime > eventMillis - startTime + eventLength) { eventMillis = currentTime; - eventLength = random.nextFloat()*3000+3000; + eventLength = random.nextFloat() * 3000 + 3000; } } double playerAngle = getPlayerRenderAngle(player, 0); double deltaAngle = playerAngle - oldPlayerAngle; if(deltaAngle > Math.PI) { - deltaAngle = 2*Math.PI - deltaAngle; + deltaAngle = 2 * Math.PI - deltaAngle; } if(deltaAngle < -Math.PI) { - deltaAngle = 2*Math.PI + deltaAngle; + deltaAngle = 2 * Math.PI + deltaAngle; } deltaAngleAccum *= 0.5f; deltaAngleAccum += deltaAngle; - float dX = (float)Math.cos(playerAngle+Math.PI/2f); - float dZ = (float)Math.sin(playerAngle+Math.PI/2f); + float dX = (float) Math.cos(playerAngle + Math.PI / 2f); + float dZ = (float) Math.sin(playerAngle + Math.PI / 2f); - float factor = (float)(deltaAngleAccum*deltaAngleAccum); + float factor = (float) (deltaAngleAccum * deltaAngleAccum); float capeTransLength = capeTranslation.length(); float capeTranslationFactor = 0f; if(capeTransLength > 0.5f) { - capeTranslationFactor = (capeTransLength-0.5f)/capeTransLength; + capeTranslationFactor = (capeTransLength - 0.5f) / capeTransLength; } Vector3f lookDir = new Vector3f(dX, 0, dZ); Vector3f lookDirNorm = lookDir.normalise(null); float dot = Vector3f.dot(capeTranslation, lookDirNorm); if(dot < 0) { //Moving backwards - for(int y=0; y<nodes.size(); y++) { - for(int x=0; x<nodes.get(y).size(); x++) { - CapeNode node = nodes.get(y).get(x); + for(int y = 0; y < VERT_NODES; y++) { + for(int x = 0; x < HORZ_NODES; x++) { + CapeNode node = nodes[x + y * HORZ_NODES]; if(!node.fixed) { - node.position.x += lookDirNorm.x*dot; - node.position.y += lookDirNorm.y*dot; - node.position.z += lookDirNorm.z*dot; + node.position.x += lookDirNorm.x * dot; + node.position.y += lookDirNorm.y * dot; + node.position.z += lookDirNorm.z * dot; } } } @@ -595,21 +601,21 @@ public class NEUCape { } if(factor > 0) { - for(int y=0; y<nodes.size(); y++) { - for(int x=0; x<nodes.get(y).size(); x++) { - nodes.get(y).get(x).applyForce(-dX*factor, 0, -dZ*factor); + for(int y = 0; y < VERT_NODES; y++) { + for(int x = 0; x < HORZ_NODES; x++) { + nodes[x + y * HORZ_NODES].applyForce(-dX * factor, 0, -dZ * factor); } } } if(capeTranslationFactor > 0f) { - float capeDX = capeTranslation.x*capeTranslationFactor; - float capeDY = capeTranslation.y*capeTranslationFactor; - float capeDZ = capeTranslation.z*capeTranslationFactor; + float capeDX = capeTranslation.x * capeTranslationFactor; + float capeDY = capeTranslation.y * capeTranslationFactor; + float capeDZ = capeTranslation.z * capeTranslationFactor; - for(int y=0; y<nodes.size(); y++) { - for(int x=0; x<nodes.get(y).size(); x++) { - CapeNode node = nodes.get(y).get(x); + for(int y = 0; y < VERT_NODES; y++) { + for(int x = 0; x < HORZ_NODES; x++) { + CapeNode node = nodes[x + y * HORZ_NODES]; if(!node.fixed) { node.position.x += capeDX; node.position.y += capeDY; @@ -620,15 +626,15 @@ public class NEUCape { } //Wind - float currTime = (System.currentTimeMillis()-startTime)/1000f; - float windRandom = Math.abs((float)(0.5f*Math.sin(0.22f*currTime)+Math.sin(0.44f*currTime)*Math.sin(0.47f*currTime))); - double windDir = playerAngle+Math.PI/4f*Math.sin(0.2f*currTime); - - float windDX = (float)Math.cos(windDir+Math.PI/2f); - float windDZ = (float)Math.sin(windDir+Math.PI/2f); - for(int y=0; y<nodes.size(); y++) { - for(int x=0; x<nodes.get(y).size(); x++) { - nodes.get(y).get(x).applyForce(-windDX*windRandom*0.01f, 0, -windDZ*windRandom*0.01f); + float currTime = (System.currentTimeMillis() - startTime) / 1000f; + float windRandom = Math.abs((float) (0.5f * Math.sin(0.22f * currTime) + Math.sin(0.44f * currTime) * Math.sin(0.47f * currTime))); + double windDir = playerAngle + Math.PI / 4f * Math.sin(0.2f * currTime); + + float windDX = (float) Math.cos(windDir + Math.PI / 2f); + float windDZ = (float) Math.sin(windDir + Math.PI / 2f); + for(int y = 0; y < VERT_NODES; y++) { + for(int x = 0; x < HORZ_NODES; x++) { + nodes[x + y * HORZ_NODES].applyForce(-windDX * windRandom * 0.01f, 0, -windDZ * windRandom * 0.01f); } } @@ -638,9 +644,9 @@ public class NEUCape { if(crouchTicks < 5) { mult = 2f; } - for(int y=0; y<8; y++) { - for(int x=0; x<nodes.get(y).size(); x++) { - nodes.get(y).get(x).applyForce(-dX*mult, 0, -dZ*mult); + for(int y = 0; y < 8; y++) { + for(int x = 0; x < HORZ_NODES; x++) { + nodes[x + y * HORZ_NODES].applyForce(-dX * mult, 0, -dZ * mult); } } } else { @@ -648,13 +654,13 @@ public class NEUCape { } Vector3f avgPosition = avgFixedPosition(); - for(int y=0; y<nodes.size(); y++) { - for(int x=0; x<nodes.get(y).size(); x++) { - CapeNode node = nodes.get(y).get(x); + for(int y = 0; y < VERT_NODES; y++) { + for(int x = 0; x < HORZ_NODES; x++) { + CapeNode node = nodes[x + y * HORZ_NODES]; Vector3f delta = Vector3f.sub(node.position, avgPosition, null); - if(delta.lengthSquared() > 5*5) { + if(delta.lengthSquared() > 5 * 5) { Vector3f norm = delta.normalise(null); node.position = Vector3f.add(avgPosition, norm, null); } @@ -663,32 +669,33 @@ public class NEUCape { oldPlayerAngle = playerAngle; - for(int y=0; y<nodes.size(); y++) { - for(int x=0; x<nodes.get(y).size(); x++) { - nodes.get(y).get(x).update(); + for(int y = 0; y < VERT_NODES; y++) { + for(int x = 0; x < HORZ_NODES; x++) { + nodes[x + y * HORZ_NODES].update(); } } int updates = player == Minecraft.getMinecraft().thePlayer ? 50 : 50; - for(int i=0; i<updates; i++) { - for(int y=0; y<nodes.size(); y++) { - for(int x=0; x<nodes.get(y).size(); x++) { - nodes.get(y).get(x).resolveAll(2+1f*y/nodes.size(), false); + for(int i = 0; i < updates; i++) { + for(int y = 0; y < VERT_NODES; y++) { + for(int x = 0; x < HORZ_NODES; x++) { + nodes[x + y * HORZ_NODES].resolveAll(2 + 1f * y / VERT_NODES, false); } } } } private int ssbo = -1; + private void generateSSBO() { ssbo = GL15.glGenBuffers(); loadSBBO(); } private void loadSBBO() { - FloatBuffer buff = BufferUtils.createFloatBuffer(CapeNode.FLOAT_NUM*HORZ_NODES*VERT_NODES); - for(int y=0; y<VERT_NODES; y++) { - for(int x=0; x<HORZ_NODES; x++) { - nodes.get(y).get(x).loadIntoBuffer(buff); + FloatBuffer buff = BufferUtils.createFloatBuffer(CapeNode.FLOAT_NUM * HORZ_NODES * VERT_NODES); + for(int y = 0; y < VERT_NODES; y++) { + for(int x = 0; x < HORZ_NODES; x++) { + nodes[x + y * HORZ_NODES].loadIntoBuffer(buff); } } buff.flip(); @@ -714,32 +721,64 @@ public class NEUCape { GL20.glUseProgram(program); - for(int i=0; i<30; i++) { + for(int i = 0; i < 30; i++) { GL43.glDispatchCompute(VERT_NODES, 1, 1); GL42.glMemoryBarrier(GL43.GL_SHADER_STORAGE_BARRIER_BIT); } GL20.glUseProgram(0); - FloatBuffer buff = BufferUtils.createFloatBuffer(CapeNode.FLOAT_NUM*HORZ_NODES*VERT_NODES); + FloatBuffer buff = BufferUtils.createFloatBuffer(CapeNode.FLOAT_NUM * HORZ_NODES * VERT_NODES); GL15.glBindBuffer(GL43.GL_SHADER_STORAGE_BUFFER, ssbo); GL15.glGetBufferSubData(GL43.GL_SHADER_STORAGE_BUFFER, 0, buff); GL15.glBindBuffer(GL43.GL_SHADER_STORAGE_BUFFER, 0); - for(int y=0; y<VERT_NODES; y++) { - for(int x=0; x<HORZ_NODES; x++) { - nodes.get(y).get(x).readFromBuffer(buff); + for(int y = 0; y < VERT_NODES; y++) { + for(int x = 0; x < HORZ_NODES; x++) { + nodes[x + y * HORZ_NODES].readFromBuffer(buff); + } + } + } + + private Vector3f avgRenderPosition() { + Vector3f accum = new Vector3f(); + int num = 0; + for(int y = 0; y < VERT_NODES; y++) { + for(int x = 0; x < HORZ_NODES; x++) { + CapeNode node = nodes[x + y * HORZ_NODES]; + Vector3f.add(accum, node.renderPosition, accum); + num++; + } + } + if(num != 0) { + accum.scale(1f / num); + } + return accum; + } + + private Vector3f avgNormal() { + Vector3f accum = new Vector3f(); + int num = 0; + for(int y = 0; y < VERT_NODES; y++) { + for(int x = 0; x < HORZ_NODES; x++) { + CapeNode node = nodes[x + y * HORZ_NODES]; + Vector3f.add(accum, node.normal(), accum); + num++; } } + if(num != 0) { + accum.scale(1f / num); + } + return accum; } private Vector3f avgFixedRenderPosition() { Vector3f accum = new Vector3f(); int numFixed = 0; - for(int y=0; y<nodes.size(); y++) { - for(int x=0; x<nodes.get(y).size(); x++) { - CapeNode node = nodes.get(y).get(x); + for(int y = 0; y < VERT_NODES; y++) { + for(int x = 0; x < HORZ_NODES; x++) { + CapeNode node = nodes[x + y * HORZ_NODES]; if(node.fixed) { Vector3f.add(accum, node.renderPosition, accum); numFixed++; @@ -747,7 +786,7 @@ public class NEUCape { } } if(numFixed != 0) { - accum.scale(1f/numFixed); + accum.scale(1f / numFixed); } return accum; } @@ -755,9 +794,9 @@ public class NEUCape { private Vector3f avgFixedPosition() { Vector3f accum = new Vector3f(); int numFixed = 0; - for(int y=0; y<nodes.size(); y++) { - for(int x=0; x<nodes.get(y).size(); x++) { - CapeNode node = nodes.get(y).get(x); + for(int y = 0; y < VERT_NODES; y++) { + for(int x = 0; x < HORZ_NODES; x++) { + CapeNode node = nodes[x + y * HORZ_NODES]; if(node.fixed) { Vector3f.add(accum, node.position, accum); numFixed++; @@ -765,11 +804,429 @@ public class NEUCape { } } if(numFixed != 0) { - accum.scale(1f/numFixed); + accum.scale(1f / numFixed); } return accum; } + private void renderBackAndDoFrontStencil() { + for(int y = 0; y < VERT_NODES; y++) { + for(int x = 0; x < HORZ_NODES; x++) { + nodes[x + y * HORZ_NODES].renderNode(CapeNode.DRAW_MASK_BACK | CapeNode.DRAW_MASK_SIDES); + } + } + + if(!Minecraft.getMinecraft().getFramebuffer().isStencilEnabled()) + Minecraft.getMinecraft().getFramebuffer().enableStencil(); + + GL11.glEnable(GL11.GL_STENCIL_TEST); + GL11.glStencilFunc(GL11.GL_ALWAYS, 1, 0xFF); + GL11.glStencilOp(GL11.GL_ZERO, GL11.GL_ZERO, GL11.GL_REPLACE); + GL11.glStencilMask(0xFF); + GL11.glClear(GL11.GL_STENCIL_BUFFER_BIT); + GlStateManager.enableDepth(); + + GL11.glColorMask(false, false, false, false); + for(int y = 0; y < VERT_NODES; y++) { + for(int x = 0; x < HORZ_NODES; x++) { + nodes[x + y * HORZ_NODES].renderNode(CapeNode.DRAW_MASK_FRONT); + } + } + GL11.glColorMask(true, true, true, true); + + // Only pass stencil test if equal to 1 + GL11.glStencilMask(0x00); + GL11.glStencilFunc(GL11.GL_EQUAL, 1, 0xFF); + } + + private Vector3f getPoint(Vector3f point, Vector3f... vectors) { + Vector3f res = new Vector3f(point); + for(Vector3f vec : vectors) Vector3f.add(res, vec, res); + return res; + } + + private static void renderVBO(WorldRenderer worldRenderer) { + if(worldRenderer != null && worldRenderer.getVertexCount() > 0) { + VertexFormat vertexformat = worldRenderer.getVertexFormat(); + int stride = vertexformat.getNextOffset(); + ByteBuffer bytebuffer = worldRenderer.getByteBuffer(); + List<VertexFormatElement> list = vertexformat.getElements(); + + for(int index = 0; index < list.size(); index++) { + VertexFormatElement vertexformatelement = list.get(index); + vertexformatelement.getUsage().preDraw(vertexformat, index, stride, bytebuffer); + } + + GL11.glDrawArrays(worldRenderer.getDrawMode(), 0, worldRenderer.getVertexCount()); + + for(int index = 0; index < list.size(); index++) { + VertexFormatElement vertexformatelement = list.get(index); + vertexformatelement.getUsage().postDraw(vertexformat, index, stride, bytebuffer); + } + } + } + + private static WorldRenderer sphereVBO = null; + + private void renderNodes() { + if(capeName.equalsIgnoreCase("planets")) { + renderBackAndDoFrontStencil(); + + Vector3f pointNorm = avgNormal(); + Vector3f capeAvgPos = avgRenderPosition(); + + pointNorm.scale(0.5f / pointNorm.length()); + pointNorm.scale(1 - pointNorm.y / 1.3f); + Vector3f point = Vector3f.sub(capeAvgPos, pointNorm, null); + + if(sphereVBO == null || Keyboard.isKeyDown(Keyboard.KEY_K)) { + if(sphereVBO != null) sphereVBO.reset(); + + int arcSegments = 24; + int rotationSegments = 24; + double arcAngleDelta = Math.PI / (arcSegments - 1); + + float xScale = 0.95f; + + double diameterUnitArcLen = 0; + + double arcAngle = 0; + for(int i = 0; i < arcSegments; i++) { + diameterUnitArcLen += Math.sin(arcAngle); + arcAngle += arcAngleDelta; + } + double arcLength = 2f / diameterUnitArcLen; + + List<List<Vector3f>> arcs = new ArrayList<>(); + for(int angleI = 0; angleI < rotationSegments; angleI++) { + double angle = Math.PI * 2 * angleI / rotationSegments; + + List<Vector3f> arc = new ArrayList<>(); + + Vector3f arcPos = new Vector3f(0, 0, -1); + + arc.add(arcPos); + + arcAngle = 0; + for(int segmentI = 0; segmentI < arcSegments; segmentI++) { + + double deltaZ = Math.sin(arcAngle) * arcLength; + double deltaY = Math.cos(arcAngle) * Math.cos(angle) * arcLength; + double deltaX = Math.cos(arcAngle) * Math.sin(angle) * arcLength * xScale; + + arcPos = new Vector3f(arcPos); + arcPos.z += deltaZ; + arcPos.y += deltaY; + arcPos.x += deltaX; + arcPos.normalise(); + arc.add(arcPos); + + arcAngle += arcAngleDelta; + } + + arcs.add(arc); + } + + sphereVBO = new WorldRenderer(8 * 4 * rotationSegments * arcSegments); + sphereVBO.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_NORMAL); + + double maxXYRad = 0; + for(int angleI = 0; angleI < rotationSegments; angleI++) { + for(int segmentI = 0; segmentI <= arcSegments; segmentI++) { + List<Vector3f> thisArc = arcs.get(angleI); + Vector3f point1 = thisArc.get(segmentI); + double rad = Math.sqrt(point1.x * point1.x + point1.y * point1.y); + maxXYRad = Math.max(maxXYRad, rad); + } + } + + for(int angleI = 0; angleI < rotationSegments; angleI++) { + + int nextAngleI = angleI + 1; + if(angleI == rotationSegments - 1) { + nextAngleI = 0; + } + + float v = 0.5f * (angleI) / (rotationSegments); + float v2 = 0.5f * (angleI + 1) / (rotationSegments); + //if(v2 == 0) v2 = 0.5f; + + List<Vector3f> thisArc = arcs.get(angleI); + List<Vector3f> nextArc = arcs.get(nextAngleI); + + for(int segmentI = 1; segmentI <= arcSegments; segmentI++) { + Vector3f point1 = thisArc.get(segmentI); + Vector3f point2 = thisArc.get(segmentI - 1); + Vector3f point3 = nextArc.get(segmentI - 1); + Vector3f point4 = nextArc.get(segmentI); + + double u1 = 0.5f * segmentI / arcSegments; + double u2 = 0.5f * (segmentI - 1) / arcSegments; + + sphereVBO.pos(point4.x, point4.y, point4.z) + .tex(u1, v2).normal(-point4.x, -point4.y, -point4.z).endVertex(); + sphereVBO.pos(point3.x, point3.y, point3.z) + .tex(u2, v2).normal(-point3.x, -point3.y, -point3.z).endVertex(); + sphereVBO.pos(point2.x, point2.y, point2.z) + .tex(u2, v).normal(-point2.x, -point2.y, -point2.z).endVertex(); + sphereVBO.pos(point1.x, point1.y, point1.z) + .tex(u1, v).normal(-point1.x, -point1.y, -point1.z).endVertex(); + } + } + } + + String shaderId = "capes/" + shaderName + "/" + shaderName; + double mercuryAngle = Math.PI * 2 * ((System.currentTimeMillis() - startTime) / 10000f % 1); + double mercuryX = Math.sin(mercuryAngle) * 0.3; + double mercuryZ = Math.cos(mercuryAngle) * 0.3; + + double earthAngle = Math.PI * 2 * ((System.currentTimeMillis() - startTime) / 30000f % 1); + double earthSlant = Math.PI * 0.1; + double earthX = Math.sin(earthAngle) * Math.cos(earthSlant) * 0.6; + double earthY = Math.sin(earthAngle) * Math.sin(earthSlant) * 0.6; + double earthZ = Math.cos(earthAngle) * Math.cos(earthSlant) * 0.6; + + float sunDist = Vector3f.sub(point, capeAvgPos, null).lengthSquared(); + float mercuryDist = Vector3f.sub(new Vector3f(point.x + (float) mercuryX, point.y, point.z + (float) mercuryZ), + capeAvgPos, null).lengthSquared(); + float earthDist = Vector3f.sub(new Vector3f(point.x + (float) earthX, point.y + (float) earthY, point.z + (float) earthZ), + capeAvgPos, null).lengthSquared(); + + double jupiterAngle = Math.PI * 2 * ((System.currentTimeMillis() - startTime) / 200000f % 1); + double jupiterSlant = Math.PI * -0.08; + double jupiterX = Math.sin(jupiterAngle) * Math.cos(jupiterSlant) * 1.5; + double jupiterY = Math.sin(jupiterAngle) * Math.sin(jupiterSlant) * 1.5; + double jupiterZ = Math.cos(jupiterAngle) * Math.cos(jupiterSlant) * 1.5; + float jupiterDist = Vector3f.sub(new Vector3f(point.x + (float) jupiterX, point.y + (float) jupiterY, point.z + (float) jupiterZ), + capeAvgPos, null).lengthSquared(); + + double neptuneX = -Math.sin(earthAngle) * Math.cos(earthSlant); + double neptuneY = -Math.sin(earthAngle) * Math.sin(earthSlant); + double neptuneZ = -Math.cos(earthAngle) * Math.cos(earthSlant); + + float neptuneDist = Vector3f.sub(new Vector3f(point.x + (float) neptuneX, point.y + (float) neptuneY, point.z + (float) neptuneZ), + capeAvgPos, null).lengthSquared(); + + TreeMap<Float, Integer> orbitals = new TreeMap<>(); + orbitals.put(sunDist, 0); + orbitals.put(earthDist, 1); + orbitals.put(mercuryDist, 2); + + double delta = Minecraft.getMinecraft().getRenderViewEntity().getRotationYawHead() % 360; + while(delta < 0) delta += 360; + + double jupDelta = (delta + Math.toDegrees(jupiterAngle)) % 360; + while(jupDelta < 0) jupDelta += 360; + if(jupDelta > 250 || jupDelta < 110) orbitals.put(jupiterDist, 3); + + double nepDelta = (delta + Math.toDegrees(-earthAngle)) % 360; + while(nepDelta < 0) nepDelta += 360; + if(nepDelta > 250 || nepDelta < 110) orbitals.put(neptuneDist, 4); + + GlStateManager.disableDepth(); + GlStateManager.enableCull(); + + for(int planetId : orbitals.descendingMap().values()) { + GlStateManager.pushMatrix(); + switch(planetId) { + case 0: { + GlStateManager.translate(point.x, point.y, point.z); + GlStateManager.scale(0.2f, 0.2f, 0.2f); + break; + } + case 1: { + Vector3f sunVec = new Vector3f((float) earthX, (float) earthY, (float) earthZ); + ShaderManager.getInstance().loadData(shaderId, "sunVec", sunVec); + GlStateManager.translate(point.x + earthX, point.y + earthY, point.z + earthZ); + GlStateManager.scale(0.1f, 0.1f, 0.1f); + break; + } + case 2: { + Vector3f sunVec = new Vector3f((float) mercuryX, 0, (float) mercuryZ); + ShaderManager.getInstance().loadData(shaderId, "sunVec", sunVec); + GlStateManager.translate(point.x + mercuryX, point.y, point.z + mercuryZ); + GlStateManager.scale(0.05f, 0.05f, 0.05f); + break; + } + case 3: { + Vector3f sunVec = new Vector3f((float) jupiterX, (float) jupiterY, (float) jupiterZ); + ShaderManager.getInstance().loadData(shaderId, "sunVec", sunVec); + GlStateManager.translate(point.x + jupiterX, point.y + jupiterY, point.z + jupiterZ); + GlStateManager.scale(0.3f, 0.3f, 0.3f); + break; + } + case 4: { + Vector3f sunVec = new Vector3f((float) neptuneX, (float) neptuneY, (float) neptuneZ); + ShaderManager.getInstance().loadData(shaderId, "sunVec", sunVec); + GlStateManager.translate(point.x + neptuneX, point.y + neptuneY, point.z + neptuneZ); + GlStateManager.scale(0.15f, 0.15f, 0.15f); + break; + } + } + ShaderManager.getInstance().loadData(shaderId, "planetType", planetId); + renderVBO(sphereVBO); + GlStateManager.popMatrix(); + } + + + GlStateManager.disableCull(); + GlStateManager.enableDepth(); + + GL11.glDisable(GL11.GL_STENCIL_TEST); + } else if(capeName.equalsIgnoreCase("parallax")) { + renderBackAndDoFrontStencil(); + + Vector3f pointNorm = avgNormal(); + pointNorm.scale(-0.2f / pointNorm.length()); + Vector3f negPointNorm = new Vector3f(pointNorm); + negPointNorm.scale(-1); + //pointNorm.scale(1 - pointNorm.y/1.3f); + Vector3f point = Vector3f.add(avgRenderPosition(), pointNorm, null); + Vector3f fixedPoint = Vector3f.add(avgFixedRenderPosition(), pointNorm, null); + + Vector3f up = Vector3f.sub(fixedPoint, point, null); + float halfUp = up.length(); + + Vector3f down = new Vector3f(up); + down.scale(-1); + + Vector3f left = Vector3f.cross(up, pointNorm, null); + left.scale(halfUp * 522f / 341f / left.length()); + Vector3f right = new Vector3f(left); + right.scale(-1); + + Vector3f point1 = getPoint(point, left); + Vector3f point2 = getPoint(point, left, down, down); + Vector3f point3 = getPoint(point, right, down, down); + Vector3f point4 = getPoint(point, right); + + Vector3f point2Edge = getPoint(point2, negPointNorm, negPointNorm); + Vector3f point3Edge = getPoint(point3, negPointNorm, negPointNorm); + + GlStateManager.disableDepth(); + GlStateManager.disableCull(); + + GlStateManager.color(1, 1, 1, 1); + + Tessellator tessellator = Tessellator.getInstance(); + WorldRenderer worldrenderer = tessellator.getWorldRenderer(); + worldrenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); + + worldrenderer.pos(point1.x, point1.y, point1.z) + .tex(0, 943 / 1024f).endVertex(); + worldrenderer.pos(point2.x, point2.y, point2.z) + .tex(280 / 1024f, 943 / 1024f).endVertex(); + worldrenderer.pos(point3.x, point3.y, point3.z) + .tex(280 / 1024f, 421 / 1024f).endVertex(); + worldrenderer.pos(point4.x, point4.y, point4.z) + .tex(0, 421 / 1024f).endVertex(); + + tessellator.draw(); + + worldrenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); + + worldrenderer.pos(point2.x, point2.y, point2.z) + .tex(280 / 1024f, 943 / 1024f).endVertex(); + worldrenderer.pos(point2Edge.x, point2Edge.y, point2Edge.z) + .tex(341 / 1024f, 943 / 1024f).endVertex(); + worldrenderer.pos(point3Edge.x, point3Edge.y, point3Edge.z) + .tex(341 / 1024f, 421 / 1024f).endVertex(); + worldrenderer.pos(point3.x, point3.y, point3.z) + .tex(280 / 1024f, 421 / 1024f).endVertex(); + + tessellator.draw(); + + + GlStateManager.disableCull(); + GlStateManager.enableDepth(); + + GL11.glDisable(GL11.GL_STENCIL_TEST); + } else if(capeName.equalsIgnoreCase("tunnel")) { + renderBackAndDoFrontStencil(); + + Vector3f pointNorm = avgNormal(); + + pointNorm.scale(0.7f / pointNorm.length()); + pointNorm.scale(1 - pointNorm.y / 1.3f); + Vector3f point = Vector3f.sub(avgRenderPosition(), pointNorm, null); + + List<CapeNode> edgeNodes = new ArrayList<>(); + List<Vector2f> edgeCoords = new ArrayList<>(); + + //Left edge + for(int y = 0; y < VERT_NODES; y++) { + edgeNodes.add(nodes[y * HORZ_NODES]); + edgeCoords.add(new Vector2f(0, (float) y / (VERT_NODES - 1))); + } + edgeNodes.add(null); + edgeCoords.add(null); + //Bottom edge + int bottomIndex = VERT_NODES - 1; + int botSize = HORZ_NODES; + for(int x = 0; x < botSize; x++) { + edgeNodes.add(getNode(x, bottomIndex)); + edgeCoords.add(new Vector2f((float) x / (botSize - 1), 1)); + } + edgeNodes.add(null); + edgeCoords.add(null); + //Right edge + for(int y = VERT_NODES - 1; y >= 0; y--) { + edgeNodes.add(getNode(HORZ_NODES - 1, y)); + edgeCoords.add(new Vector2f(1, (float) y / VERT_NODES)); + } + edgeNodes.add(null); + edgeCoords.add(null); + //Top edge + int topSize = HORZ_NODES; + for(int x = topSize - 1; x >= 0; x--) { + edgeNodes.add(getNode(x, 0)); + edgeCoords.add(new Vector2f((float) x / (topSize - 1), 0)); + } + + GlStateManager.disableDepth(); + GlStateManager.enableCull(); + CapeNode last = null; + for(int i = 0; i < edgeNodes.size(); i++) { + CapeNode node = edgeNodes.get(i); + if(last != null && node != null) { + Vector2f lastCoord = edgeCoords.get(i - 1); + Vector2f coord = edgeCoords.get(i); + + Tessellator tessellator = Tessellator.getInstance(); + WorldRenderer worldrenderer = tessellator.getWorldRenderer(); + worldrenderer.begin(GL11.GL_TRIANGLES, DefaultVertexFormats.POSITION_TEX_NORMAL); + + Vector3f lastNodeNorm = last.normal(); + worldrenderer.pos(last.renderPosition.x + lastNodeNorm.x * 0.05f, last.renderPosition.y + lastNodeNorm.y * 0.05f, last.renderPosition.z + lastNodeNorm.z * 0.05f) + .tex(lastCoord.x * 300f / 1024f, lastCoord.y * 420f / 1024f) + .normal(-lastNodeNorm.x, -lastNodeNorm.y, -lastNodeNorm.z).endVertex(); + + Vector3f nodeNorm = node.normal(); + worldrenderer.pos(node.renderPosition.x + nodeNorm.x * 0.05f, node.renderPosition.y + nodeNorm.y * 0.05f, node.renderPosition.z + nodeNorm.z * 0.05f) + .tex(coord.x * 300f / 1024f, coord.y * 420f / 1024f) + .normal(-nodeNorm.x, -nodeNorm.y, -nodeNorm.z).endVertex(); + + worldrenderer.pos(point.x, point.y, point.z) + .tex(150f / 1024f, 210f / 1024f) + .normal(-pointNorm.x, -pointNorm.y, -pointNorm.z).endVertex(); + + tessellator.draw(); + } + last = node; + } + GlStateManager.disableCull(); + GlStateManager.enableDepth(); + + GL11.glDisable(GL11.GL_STENCIL_TEST); + } else { + for(int y = 0; y < VERT_NODES; y++) { + for(int x = 0; x < HORZ_NODES; x++) { + nodes[x + y * HORZ_NODES].renderNode(); + } + } + } + } + private void renderCape(EntityPlayer player, float partialRenderTick) { ensureCapeNodesCreated(player); @@ -781,9 +1238,9 @@ public class NEUCape { if(delta.lengthSquared() > 9) { updateFixedCapeNodes(player); - for(int y=0; y<nodes.size(); y++) { - for(int x=0; x<nodes.get(y).size(); x++) { - CapeNode node = nodes.get(y).get(x); + for(int y = 0; y < VERT_NODES; y++) { + for(int x = 0; x < HORZ_NODES; x++) { + CapeNode node = nodes[x + y * HORZ_NODES]; if(!node.fixed) { Vector3f.add(node.renderPosition, delta, node.renderPosition); node.position.set(node.renderPosition); @@ -794,17 +1251,13 @@ public class NEUCape { } } - for(int y=0; y<nodes.size(); y++) { - for(int x=0; x<nodes.get(y).size(); x++) { - nodes.get(y).get(x).renderNode(); - } - } + renderNodes(); return; } - for(int y=0; y<nodes.size(); y++) { - for(int x=0; x<nodes.get(y).size(); x++) { - CapeNode node = nodes.get(y).get(x); + for(int y = 0; y < VERT_NODES; y++) { + for(int x = 0; x < HORZ_NODES; x++) { + CapeNode node = nodes[x + y * HORZ_NODES]; node.resetNormal(); @@ -821,31 +1274,31 @@ public class NEUCape { if(fps < 50) { length = 2; } else if(fps < 100) { - length = 2 + (int)((fps-50)/50f*3); + length = 2 + (int) ((fps - 50) / 50f * 3); } - if(node.oldRenderPosition[length-1] == null) { + if(node.oldRenderPosition[length - 1] == null) { Arrays.fill(node.oldRenderPosition, Vector3f.sub(newPosition, avgPositionFixed, null)); node.renderPosition = newPosition; } else { Vector3f accum = new Vector3f(); - for(int i=0; i<length; i++) { + for(int i = 0; i < length; i++) { Vector3f.add(accum, node.oldRenderPosition[i], accum); Vector3f.add(accum, avgPositionFixed, accum); } - accum.scale(1/(float)(length)); + accum.scale(1 / (float) (length)); - float blendFactor = 0.5f+0.3f*y/(float)(nodes.size()-1); //0.5/0.5 -> 0.8/0.2 //0-1 + float blendFactor = 0.5f + 0.3f * y / (float) (VERT_NODES - 1); //0.5/0.5 -> 0.8/0.2 //0-1 accum.scale(blendFactor); - newPosition.scale(1-blendFactor); + newPosition.scale(1 - blendFactor); Vector3f.add(accum, newPosition, accum); node.renderPosition = accum; } if(!Minecraft.getMinecraft().isGamePaused()) { - for(int i=node.oldRenderPosition.length-1; i>=0; i--) { + for(int i = node.oldRenderPosition.length - 1; i >= 0; i--) { if(i > 0) { - node.oldRenderPosition[i] = node.oldRenderPosition[i-1]; + node.oldRenderPosition[i] = node.oldRenderPosition[i - 1]; } else { node.oldRenderPosition[i] = Vector3f.sub(node.renderPosition, avgPositionFixed, null); } @@ -853,11 +1306,7 @@ public class NEUCape { } } } - for(int y=0; y<nodes.size(); y++) { - for(int x=0; x<nodes.get(y).size(); x++) { - nodes.get(y).get(x).renderNode(); - } - } + renderNodes(); } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/infopanes/HTMLInfoPane.java b/src/main/java/io/github/moulberry/notenoughupdates/infopanes/HTMLInfoPane.java index 9981e6f9..df7069d4 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/infopanes/HTMLInfoPane.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/infopanes/HTMLInfoPane.java @@ -19,11 +19,15 @@ import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.texture.DynamicTexture; import net.minecraft.util.EnumChatFormatting; import net.minecraft.util.ResourceLocation; +import org.apache.commons.io.FileUtils; +import org.apache.commons.lang3.SystemUtils; import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; import java.io.*; +import java.net.URL; +import java.net.URLConnection; import java.nio.charset.CharsetEncoder; import java.nio.charset.StandardCharsets; import java.util.concurrent.ExecutorService; @@ -43,6 +47,8 @@ public class HTMLInfoPane extends TextInfoPane { private int imageHeight = 0; private int imageWidth = 0; + private static boolean hasAttemptedDownload = false; + /** * Creates a wiki model and sets the configuration to work with hypixel-skyblock wikia. */ @@ -140,6 +146,9 @@ public class HTMLInfoPane extends TextInfoPane { return str.replace(" ", "\\ "); } + private static final ExecutorService wkDownloadES = Executors.newSingleThreadExecutor(); + private static final ExecutorService rendererES = Executors.newCachedThreadPool(); + /** * Uses the wkhtmltoimage command-line tool to generate an image from the HTML code. This * generation is done asynchronously as sometimes it can take up to 10 seconds for more @@ -149,8 +158,68 @@ public class HTMLInfoPane extends TextInfoPane { super(overlay, manager, name, ""); this.title = name; + String osId; + if(SystemUtils.IS_OS_WINDOWS) { + osId = "win"; + } else if(SystemUtils.IS_OS_MAC) { + osId = "mac"; + } else if(SystemUtils.IS_OS_LINUX) { + osId = "linux"; + } else { + text = EnumChatFormatting.RED+"Unsupported operating system."; + return; + } + File cssFile = new File(manager.configLocation, "wikia.css"); - File wkHtmlToImage = new File(manager.configLocation, "wkhtmltox/bin/wkhtmltoimage"); + File wkHtmlToImage = new File(manager.configLocation, "wkhtmltox-"+osId+"/bin/wkhtmltoimage"); + + //Use old binary folder + if(new File(manager.configLocation, "wkhtmltox/bin/wkhtmltoimage").exists() && SystemUtils.IS_OS_WINDOWS) { + wkHtmlToImage = new File(manager.configLocation, "wkhtmltox/bin/wkhtmltoimage"); + } + + Runtime runtime = Runtime.getRuntime(); + String[] chmodCommand = new String[]{ "chmod", "-R", "777", new File(manager.configLocation, "wkhtmltox-"+osId).getAbsolutePath() }; + try { + Process p = runtime.exec(chmodCommand); + p.waitFor(); + } catch(IOException | InterruptedException e) {} + + if(!wkHtmlToImage.exists()) { + if(hasAttemptedDownload) { + text = EnumChatFormatting.RED+"Downloading web renderer failed? Or still downloading? Not sure what to do"; + return; + } else { + hasAttemptedDownload = true; + Utils.recursiveDelete(new File(manager.configLocation, "wkhtmltox-"+osId)); + wkDownloadES.submit(() -> { + try { + File itemsZip = new File(manager.configLocation, "wkhtmltox-"+osId+".zip"); + if(!itemsZip.exists()) { + URL url = new URL("https://moulberry.codes/wkhtmltox/wkhtmltox-"+osId+".zip"); + URLConnection urlConnection = url.openConnection(); + urlConnection.setConnectTimeout(15000); + urlConnection.setReadTimeout(60000); + + FileUtils.copyInputStreamToFile(urlConnection.getInputStream(), itemsZip); + } + + try(InputStream is = new FileInputStream(itemsZip)) { + manager.unzip(is, manager.configLocation); + } + + itemsZip.delete(); + itemsZip.deleteOnExit(); + } catch (IOException e) { + e.printStackTrace(); + } + }); + + text = EnumChatFormatting.YELLOW+"Downloading web renderer... try again soon"; + return; + } + } + File input = new File(manager.configLocation, "tmp/input.html"); String outputFileName = filename.replaceAll("(?i)\\u00A7.", "") .replaceAll("[^a-zA-Z0-9_\\-]", "_"); @@ -179,7 +248,7 @@ public class HTMLInfoPane extends TextInfoPane { } else { html = "<div id=\"mw-content-text\" lang=\"en\" dir=\"ltr\" class=\"mw-content-ltr mw-content-text\">"+html+"</div>"; html = "<div id=\"WikiaArticle\" class=\"WikiaArticle\">"+html+"</div>"; - html = "<link rel=\"stylesheet\" href=\"file:///"+cssFile.getAbsolutePath()+"\">\n"+html; + html = "<link rel=\"stylesheet\" href=\"file:///"+cssFile.getAbsolutePath().replaceAll("^/", "")+"\">\n"+html; try(PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter( new FileOutputStream(input), StandardCharsets.UTF_8)), false)) { @@ -187,16 +256,12 @@ public class HTMLInfoPane extends TextInfoPane { out.println(encodeNonAscii(html)); } catch(IOException e) {} - - ExecutorService ste = Executors.newSingleThreadExecutor(); try { text = EnumChatFormatting.GRAY+"Rendering webpage (" + name + EnumChatFormatting.RESET+ EnumChatFormatting.GRAY+"), please wait..."; - Runtime runtime = Runtime.getRuntime(); - String[] wkCommand = new String[]{ wkHtmlToImage.getAbsolutePath(), "--width", ""+IMAGE_WIDTH*ZOOM_FACTOR, - "--transparent", "--zoom", ""+ZOOM_FACTOR, input.getAbsolutePath(), output.getAbsolutePath()}; + "--transparent", "--allow", manager.configLocation.getAbsolutePath(), "--zoom", ""+ZOOM_FACTOR, input.getAbsolutePath(), output.getAbsolutePath()}; Process p = runtime.exec(wkCommand); /*Process p = runtime.exec(spaceEscape(wkHtmlToImage.getAbsolutePath()) + " --width "+ IMAGE_WIDTH*ZOOM_FACTOR+" --transparent --zoom "+ZOOM_FACTOR + " " + spaceEscape(input.getAbsolutePath()) + @@ -207,7 +272,7 @@ public class HTMLInfoPane extends TextInfoPane { /*Process p2 = runtime.exec("\""+wkHtmlToImage.getAbsolutePath() + "\" --width "+ (IMAGE_WIDTH+EXT_WIDTH)*ZOOM_FACTOR+" --transparent --zoom "+ZOOM_FACTOR+" \"" + input.getAbsolutePath() + "\" \"" + outputExt.getAbsolutePath() + "\"");*/ - ste.submit(() -> { + rendererES.submit(() -> { try { if(p.waitFor(15, TimeUnit.SECONDS)) { //if(p2.waitFor(5, TimeUnit.SECONDS)) { @@ -260,8 +325,6 @@ public class HTMLInfoPane extends TextInfoPane { } catch(IOException e) { e.printStackTrace(); text = EnumChatFormatting.RED+"Failed to exec webpage renderer."; - } finally { - ste.shutdown(); } } } 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 7e073bbd..20915503 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CustomItemEffects.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CustomItemEffects.java @@ -10,6 +10,7 @@ import net.minecraft.block.BlockPackedIce; import net.minecraft.block.material.Material; import net.minecraft.block.state.IBlockState; import net.minecraft.client.Minecraft; +import net.minecraft.client.audio.PositionedSoundRecord; import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.client.gui.ScaledResolution; import net.minecraft.client.renderer.*; @@ -408,6 +409,9 @@ public class CustomItemEffects { cropBlocksZapper.add(Blocks.melon_stem); cropBlocksZapper.add(Blocks.cactus); cropBlocksZapper.add(Blocks.reeds); + cropBlocksZapper.add(Blocks.nether_wart); + cropBlocksZapper.add(Blocks.tallgrass); + cropBlocksZapper.add(Blocks.double_plant); otherBannedBlocksZapper.add(Blocks.farmland); } @@ -436,6 +440,7 @@ public class CustomItemEffects { zapperDirty = false; zapperBlocks.clear(); + LinkedList<BlockPos> returnablePositions = new LinkedList<>(); BlockPos pos = event.target.getBlockPos(); 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 eed1ec60..26e87ae9 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/EnchantingSolvers.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/EnchantingSolvers.java @@ -311,8 +311,7 @@ public class EnchantingSolvers { if(chronomatronReplayIndex < chronomatronOrder.size()) { String chronomatronCurrent = chronomatronOrder.get(chronomatronReplayIndex); - if(!NotEnoughUpdates.INSTANCE.config.enchantingSolvers.preventMisclicks || - chronomatronCurrent.equals(displayName)) { + if(true) { chronomatronReplayIndex++; Minecraft.getMinecraft().playerController.windowClick(windowId, slotId, 2, mode, Minecraft.getMinecraft().thePlayer); @@ -334,9 +333,7 @@ public class EnchantingSolvers { return true; } long currentTime = System.currentTimeMillis(); - if(currentTime - millisLastClick > 150 && - (!NotEnoughUpdates.INSTANCE.config.enchantingSolvers.preventMisclicks || - current.containerIndex == slotId)) { + if(currentTime - millisLastClick > 150) { ultrasequencerReplayIndex++; Minecraft.getMinecraft().playerController.windowClick(windowId, slotId, 2, mode, Minecraft.getMinecraft().thePlayer); @@ -354,7 +351,9 @@ public class EnchantingSolvers { return false; } - public static void processInventoryContents() { + public static void processInventoryContents(boolean fromTick) { + if(currentSolver != SolverType.CHRONOMATRON && !fromTick) return; + if(!NotEnoughUpdates.INSTANCE.config.enchantingSolvers.enableEnchantingSolvers) { return; } @@ -536,7 +535,7 @@ public class EnchantingSolvers { return; } - processInventoryContents(); + processInventoryContents(true); } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/MiningStuff.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/MiningStuff.java index d01a173f..6f706b5c 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/MiningStuff.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/MiningStuff.java @@ -104,26 +104,6 @@ public class MiningStuff { } } - public static void tick() { - if(SBInfo.getInstance().getLocation() == null) return; - if(!SBInfo.getInstance().getLocation().equals("mining_3")) return; - if(Minecraft.getMinecraft().theWorld == null) return; - - for(Entity entity : Minecraft.getMinecraft().theWorld.loadedEntityList) { - if(entity instanceof EntityCreeper) { - EntityCreeper creeper = (EntityCreeper) entity; - if(creeper.isInvisible() && creeper.getPowered()) { - - BlockPos below = creeper.getPosition().down(); - IBlockState state = Minecraft.getMinecraft().theWorld.getBlockState(below); - if(state != null && state.getBlock() == Blocks.stained_glass) { - creeper.setInvisible(!NotEnoughUpdates.INSTANCE.config.mining.revealMistCreepers); - } - } - } - } - } - @SubscribeEvent public void renderWorldLast(RenderWorldLastEvent event) { if(overlayLoc == null) return; @@ -186,19 +166,4 @@ public class MiningStuff { } } - public static boolean blockClicked(BlockPos loc) { - if(loc.equals(overlayLoc)) { - overlayLoc = null; - } - IBlockState state = Minecraft.getMinecraft().theWorld.getBlockState(loc); - if(NotEnoughUpdates.INSTANCE.config.mining.dontMineStone && - state != null && SBInfo.getInstance().getLocation() != null && - SBInfo.getInstance().getLocation().startsWith("mining_") && - (state.getBlock() == Blocks.stone && state.getValue(BlockStone.VARIANT) == BlockStone.EnumType.STONE || - state.getBlock() == Blocks.cobblestone)) { - return true; - } - return false; - } - } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/NullzeeSphere.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/NullzeeSphere.java new file mode 100644 index 00000000..7e297c58 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/NullzeeSphere.java @@ -0,0 +1,234 @@ +package io.github.moulberry.notenoughupdates.miscfeatures; + +import io.github.moulberry.notenoughupdates.util.ReverseWorldRenderer; +import io.github.moulberry.notenoughupdates.util.SpecialColour; +import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.EntityPlayerSP; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.client.renderer.vertex.VertexFormat; +import net.minecraft.client.renderer.vertex.VertexFormatElement; +import net.minecraft.entity.Entity; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.BlockPos; +import net.minecraftforge.client.event.RenderWorldLastEvent; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.gameevent.TickEvent; +import org.lwjgl.opengl.GL11; + +import java.awt.*; +import java.nio.ByteBuffer; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class NullzeeSphere { + + public static boolean enabled = false; + public static float size = 20; + public static BlockPos centerPos = new BlockPos(0, 0, 0); + + public static ReverseWorldRenderer overlayVBO = null; + + public ReverseWorldRenderer getOverlayVBO() { + if(overlayVBO != null) return overlayVBO; + + EntityPlayerSP p = Minecraft.getMinecraft().thePlayer; + if(p == null) return null; + + //per vertex = 6 + //per size = 4 + //per block = 8 + //total per block = 196 + + Set<BlockPos> circleOffsets = getCircleOffsets(size); + + ReverseWorldRenderer worldRenderer = new ReverseWorldRenderer(196*circleOffsets.size()); + worldRenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR); + + String col = SpecialColour.special(0, 180, 0xffff9900); + for(BlockPos offset : circleOffsets) { + BlockPos overlayPos = new BlockPos(offset.getX(), offset.getY(), offset.getZ()); + + AxisAlignedBB bb = new AxisAlignedBB( + overlayPos.getX(), + overlayPos.getY(), + overlayPos.getZ(), + overlayPos.getX()+1, + overlayPos.getY()+1, + overlayPos.getZ()+1 + ).expand(0.001f, 0.001f, 0.001f); + uploadFilledBoundingBox(bb, 1f, col, worldRenderer); + } + + overlayVBO = worldRenderer; + return overlayVBO; + } + + public Set<BlockPos> getCircleOffsets(float radius) { + Set<BlockPos> circleOffsets = new HashSet<>(); + + int radiusI = (int)Math.ceil(radius)+1; + for(int x=-radiusI; x<=radiusI; x++) { + for(int y=-radiusI; y<=radiusI; y++) { + for(int z=-radiusI; z<=radiusI; z++) { + float distSq = x*x + y*y + z*z; + if(distSq >= (radius-0.5)*(radius-0.5) && distSq <= (radius+0.5)*(radius+0.5)) { + circleOffsets.add(new BlockPos(x, y, z)); + } + } + } + } + + return circleOffsets; + } + + long lastUpdate = 0; + + private static double posLastUpdateX; + private static double posLastUpdateY; + private static double posLastUpdateZ; + + @SubscribeEvent + public void onTick(TickEvent.ClientTickEvent event) { + if(!enabled) return; + + EntityPlayerSP p = Minecraft.getMinecraft().thePlayer; + if(p == null) return; + + if(event.phase == TickEvent.Phase.START) { + double dX = p.posX - posLastUpdateX; + double dY = p.posY - posLastUpdateY; + double dZ = p.posZ - posLastUpdateZ; + + if(dX*dX + dY*dY + dZ*dZ < 1) { + return; + } + + posLastUpdateX = p.posX; + posLastUpdateY = p.posY; + posLastUpdateZ = p.posZ; + + long currentTime = System.currentTimeMillis(); + if(currentTime - lastUpdate < 250) { + return; + } + lastUpdate = currentTime; + + ReverseWorldRenderer worldRenderer = getOverlayVBO(); + if(worldRenderer != null) { + worldRenderer.setTranslation(0, 0,0 ); + worldRenderer.sortVertexData( + (float)p.posX-centerPos.getX(), + (float)p.posY-centerPos.getY(), + (float)p.posZ-centerPos.getZ()); + + } + } + } + + @SubscribeEvent + public void onRenderLast(RenderWorldLastEvent event) { + if(!enabled) return; + + Entity viewer = Minecraft.getMinecraft().getRenderViewEntity(); + double viewerX = viewer.lastTickPosX + (viewer.posX - viewer.lastTickPosX) * event.partialTicks; + double viewerY = viewer.lastTickPosY + (viewer.posY - viewer.lastTickPosY) * event.partialTicks; + double viewerZ = viewer.lastTickPosZ + (viewer.posZ - viewer.lastTickPosZ) * event.partialTicks; + + GlStateManager.enableBlend(); + GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0); + GlStateManager.disableTexture2D(); + + GlStateManager.translate(-viewerX, -viewerY, -viewerZ); + + GL11.glPolygonOffset(5, 5); + ReverseWorldRenderer worldRenderer = getOverlayVBO(); + if(worldRenderer != null && worldRenderer.getVertexCount() > 0) { + GlStateManager.translate(centerPos.getX(), centerPos.getY(), centerPos.getZ()); + + VertexFormat vertexformat = worldRenderer.getVertexFormat(); + int stride = vertexformat.getNextOffset(); + ByteBuffer bytebuffer = worldRenderer.getByteBuffer(); + List<VertexFormatElement> list = vertexformat.getElements(); + + for (int index = 0; index < list.size(); index++) { + VertexFormatElement vertexformatelement = list.get(index); + vertexformatelement.getUsage().preDraw(vertexformat, index, stride, bytebuffer); + } + + GL11.glDrawArrays(worldRenderer.getDrawMode(), 0, worldRenderer.getVertexCount()); + + for (int index = 0; index < list.size(); index++) { + VertexFormatElement vertexformatelement = list.get(index); + vertexformatelement.getUsage().postDraw(vertexformat, index, stride, bytebuffer); + } + + GlStateManager.translate(-centerPos.getX(), -centerPos.getY(), -centerPos.getZ()); + } + GL11.glPolygonOffset(0, 0); + + GlStateManager.translate(viewerX, viewerY, viewerZ); + + GlStateManager.enableTexture2D(); + } + + public static void uploadFilledBoundingBox(AxisAlignedBB p_181561_0_, float alpha, String special, ReverseWorldRenderer worldrenderer) { + Color c = new Color(SpecialColour.specialToChromaRGB(special), true); + + //vertical + worldrenderer.pos(p_181561_0_.minX, p_181561_0_.minY, p_181561_0_.minZ) + .color(c.getRed()/255f, c.getGreen()/255f, c.getBlue()/255f, c.getAlpha()/255f*alpha).endVertex(); + worldrenderer.pos(p_181561_0_.maxX, p_181561_0_.minY, p_181561_0_.minZ) + .color(c.getRed()/255f, c.getGreen()/255f, c.getBlue()/255f, c.getAlpha()/255f*alpha).endVertex(); + worldrenderer.pos(p_181561_0_.maxX, p_181561_0_.minY, p_181561_0_.maxZ) + .color(c.getRed()/255f, c.getGreen()/255f, c.getBlue()/255f, c.getAlpha()/255f*alpha).endVertex(); + worldrenderer.pos(p_181561_0_.minX, p_181561_0_.minY, p_181561_0_.maxZ) + .color(c.getRed()/255f, c.getGreen()/255f, c.getBlue()/255f, c.getAlpha()/255f*alpha).endVertex(); + worldrenderer.pos(p_181561_0_.minX, p_181561_0_.maxY, p_181561_0_.maxZ) + .color(c.getRed()/255f, c.getGreen()/255f, c.getBlue()/255f, c.getAlpha()/255f*alpha).endVertex(); + worldrenderer.pos(p_181561_0_.maxX, p_181561_0_.maxY, p_181561_0_.maxZ) + .color(c.getRed()/255f, c.getGreen()/255f, c.getBlue()/255f, c.getAlpha()/255f*alpha).endVertex(); + worldrenderer.pos(p_181561_0_.maxX, p_181561_0_.maxY, p_181561_0_.minZ) + .color(c.getRed()/255f, c.getGreen()/255f, c.getBlue()/255f, c.getAlpha()/255f*alpha).endVertex(); + worldrenderer.pos(p_181561_0_.minX, p_181561_0_.maxY, p_181561_0_.minZ) + .color(c.getRed()/255f, c.getGreen()/255f, c.getBlue()/255f, c.getAlpha()/255f*alpha).endVertex(); + + //x + worldrenderer.pos(p_181561_0_.minX, p_181561_0_.minY, p_181561_0_.maxZ) + .color(c.getRed()/255f*0.8f, c.getGreen()/255f*0.8f, c.getBlue()/255f*0.8f, c.getAlpha()/255f*alpha).endVertex(); + worldrenderer.pos(p_181561_0_.minX, p_181561_0_.maxY, p_181561_0_.maxZ) + .color(c.getRed()/255f*0.8f, c.getGreen()/255f*0.8f, c.getBlue()/255f*0.8f, c.getAlpha()/255f*alpha).endVertex(); + worldrenderer.pos(p_181561_0_.minX, p_181561_0_.maxY, p_181561_0_.minZ) + .color(c.getRed()/255f*0.8f, c.getGreen()/255f*0.8f, c.getBlue()/255f*0.8f, c.getAlpha()/255f*alpha).endVertex(); + worldrenderer.pos(p_181561_0_.minX, p_181561_0_.minY, p_181561_0_.minZ) + .color(c.getRed()/255f*0.8f, c.getGreen()/255f*0.8f, c.getBlue()/255f*0.8f, c.getAlpha()/255f*alpha).endVertex(); + worldrenderer.pos(p_181561_0_.maxX, p_181561_0_.minY, p_181561_0_.minZ) + .color(c.getRed()/255f*0.8f, c.getGreen()/255f*0.8f, c.getBlue()/255f*0.8f, c.getAlpha()/255f*alpha).endVertex(); + worldrenderer.pos(p_181561_0_.maxX, p_181561_0_.maxY, p_181561_0_.minZ) + .color(c.getRed()/255f*0.8f, c.getGreen()/255f*0.8f, c.getBlue()/255f*0.8f, c.getAlpha()/255f*alpha).endVertex(); + worldrenderer.pos(p_181561_0_.maxX, p_181561_0_.maxY, p_181561_0_.maxZ) + .color(c.getRed()/255f*0.8f, c.getGreen()/255f*0.8f, c.getBlue()/255f*0.8f, c.getAlpha()/255f*alpha).endVertex(); + worldrenderer.pos(p_181561_0_.maxX, p_181561_0_.minY, p_181561_0_.maxZ) + .color(c.getRed()/255f*0.8f, c.getGreen()/255f*0.8f, c.getBlue()/255f*0.8f, c.getAlpha()/255f*alpha).endVertex(); + + //z + worldrenderer.pos(p_181561_0_.minX, p_181561_0_.maxY, p_181561_0_.minZ) + .color(c.getRed()/255f*0.9f, c.getGreen()/255f*0.9f, c.getBlue()/255f*0.9f, c.getAlpha()/255f*alpha).endVertex(); + worldrenderer.pos(p_181561_0_.maxX, p_181561_0_.maxY, p_181561_0_.minZ) + .color(c.getRed()/255f*0.9f, c.getGreen()/255f*0.9f, c.getBlue()/255f*0.9f, c.getAlpha()/255f*alpha).endVertex(); + worldrenderer.pos(p_181561_0_.maxX, p_181561_0_.minY, p_181561_0_.minZ) + .color(c.getRed()/255f*0.9f, c.getGreen()/255f*0.9f, c.getBlue()/255f*0.9f, c.getAlpha()/255f*alpha).endVertex(); + worldrenderer.pos(p_181561_0_.minX, p_181561_0_.minY, p_181561_0_.minZ) + .color(c.getRed()/255f*0.9f, c.getGreen()/255f*0.9f, c.getBlue()/255f*0.9f, c.getAlpha()/255f*alpha).endVertex(); + worldrenderer.pos(p_181561_0_.minX, p_181561_0_.minY, p_181561_0_.maxZ) + .color(c.getRed()/255f*0.9f, c.getGreen()/255f*0.9f, c.getBlue()/255f*0.9f, c.getAlpha()/255f*alpha).endVertex(); + worldrenderer.pos(p_181561_0_.maxX, p_181561_0_.minY, p_181561_0_.maxZ) + .color(c.getRed()/255f*0.9f, c.getGreen()/255f*0.9f, c.getBlue()/255f*0.9f, c.getAlpha()/255f*alpha).endVertex(); + worldrenderer.pos(p_181561_0_.maxX, p_181561_0_.maxY, p_181561_0_.maxZ) + .color(c.getRed()/255f*0.9f, c.getGreen()/255f*0.9f, c.getBlue()/255f*0.9f, c.getAlpha()/255f*alpha).endVertex(); + worldrenderer.pos(p_181561_0_.minX, p_181561_0_.maxY, p_181561_0_.maxZ) + .color(c.getRed()/255f*0.9f, c.getGreen()/255f*0.9f, c.getBlue()/255f*0.9f, c.getAlpha()/255f*alpha).endVertex(); + } + +} 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 09ae3071..f759ba7d 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/PetInfoOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/PetInfoOverlay.java @@ -48,7 +48,7 @@ public class PetInfoOverlay extends TextOverlay { private static final Pattern XP_BOOST_PATTERN = Pattern.compile("PET_ITEM_(COMBAT|FISHING|MINING|FORAGING|ALL|FARMING)_(SKILL|SKILLS)_BOOST_(COMMON|UNCOMMON|RARE|EPIC)"); private static final Pattern PET_CONTAINER_PAGE = Pattern.compile("\\((\\d)/(\\d)\\) Pets"); 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 Pattern XP_LINE_PATTERN = Pattern.compile("-------------------- (\\d+(?:,\\d+)*(?:\\.\\d+)?)/(\\d+(?:\\.\\d+)?[B|M|k]?)"); public PetInfoOverlay(Position position, Supplier<List<String>> dummyStrings, Supplier<TextOverlayStyle> styleSupplier) { super(position, dummyStrings, styleSupplier); @@ -95,6 +95,7 @@ public class PetInfoOverlay extends TextOverlay { 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<>(); @@ -103,23 +104,40 @@ public class PetInfoOverlay extends TextOverlay { public static float beastMultiplier = 0; public static boolean setActivePet = false; - private long lastUpdate = 0; - private float levelXpLast = 0; + private static long lastUpdate = 0; + private static float levelXpLast = 0; - private LinkedList<Float> xpGainQueue = new LinkedList<>(); - private float xpGainHourLast = -1; - private float xpGainHour = -1; + private static LinkedList<Float> xpGainQueue = new LinkedList<>(); + private static float xpGainHourLast = -1; + private static float xpGainHour = -1; + + private static float xpGainHourSecondPet = -1; private int xpAddTimer = 0; public static void clearPet() { selectedPet = -1; + selectedPet2 = -1; + } + + public static void setCurrentPet(int index) { + selectedPet2 = selectedPet; + xpGainHourSecondPet = xpGainHour; + xpGainHourLast = xpGainHour; + xpGainQueue.clear(); + selectedPet = index; } public static Pet getCurrentPet() { return petMap.get(selectedPet); } + public static Pet getCurrentPet2() { + if(!NotEnoughUpdates.INSTANCE.config.petOverlay.dualPets) return null; + if(selectedPet == selectedPet2) return null; + return petMap.get(selectedPet2); + } + public float getLevelPercent() { DecimalFormat df = new DecimalFormat("#.#", DecimalFormatSymbols.getInstance(Locale.ENGLISH)); Pet pet = getCurrentPet(); @@ -306,57 +324,59 @@ public class PetInfoOverlay extends TextOverlay { return interp; } - @Override - public void updateFrequent() { - Pet currentPet = getCurrentPet(); - if(!NotEnoughUpdates.INSTANCE.config.petOverlay.enablePetInfo || currentPet == null) { - overlayStrings = null; + private List<String> createStringsForPet(Pet currentPet, boolean secondPet) { + float levelXp = currentPet.petLevel.levelXp; + if(!secondPet) levelXp = interp(currentPet.petLevel.levelXp, levelXpLast); + if(levelXp < 0) levelXp = 0; + + String petName = EnumChatFormatting.GREEN + "[Lvl " + (int) currentPet.petLevel.level + "] " + currentPet.rarity.chatFormatting + + WordUtils.capitalizeFully(currentPet.petType.replace("_", " ")); + + String lvlStringShort = EnumChatFormatting.AQUA + "" + roundFloat(levelXp) + "/" + + roundFloat(currentPet.petLevel.currentLevelRequirement) + + EnumChatFormatting.YELLOW + " (" + getLevelPercent() + "%)"; + + String lvlString = EnumChatFormatting.AQUA + "" + Utils.shortNumberFormat(levelXp, 0) + "/" + + Utils.shortNumberFormat(currentPet.petLevel.currentLevelRequirement, 0) + + EnumChatFormatting.YELLOW + " (" + getLevelPercent() + "%)"; + + float xpGain; + if(!secondPet) { + xpGain = interp(xpGainHour, xpGainHourLast); } else { - float levelXp = interp(currentPet.petLevel.levelXp, levelXpLast); - if(levelXp < 0) levelXp = 0; - - String petName = EnumChatFormatting.GREEN + "[Lvl " + (int) currentPet.petLevel.level + "] " + currentPet.rarity.chatFormatting + - WordUtils.capitalizeFully(currentPet.petType.replace("_", " ")); - - String lvlStringShort = EnumChatFormatting.AQUA + "" + roundFloat(levelXp) + "/" + - roundFloat(currentPet.petLevel.currentLevelRequirement) - + EnumChatFormatting.YELLOW + " (" + getLevelPercent() + "%)"; - - String lvlString = EnumChatFormatting.AQUA + "" + Utils.shortNumberFormat(levelXp, 0) + "/" + - Utils.shortNumberFormat(currentPet.petLevel.currentLevelRequirement, 0) - + EnumChatFormatting.YELLOW + " (" + getLevelPercent() + "%)"; - - float xpGain = interp(xpGainHour, xpGainHourLast); - if(xpGain < 0) xpGain = 0; - String xpGainString = EnumChatFormatting.AQUA + "XP/h: " + - EnumChatFormatting.YELLOW + roundFloat(xpGain); - if(xpGain > 0 && xpGainHour == xpGainHourLast) xpGainString += EnumChatFormatting.RED + " (PAUSED)"; - - String totalXpString = EnumChatFormatting.AQUA + "Total XP: " + EnumChatFormatting.YELLOW + roundFloat(currentPet.petLevel.totalXp); - - String petItemStr = EnumChatFormatting.AQUA+ "Held Item: " + EnumChatFormatting.RED + "None"; - if(currentPet.petItem != null) { - JsonObject json = NotEnoughUpdates.INSTANCE.manager.getItemInformation().get(currentPet.petItem); - if(json != null) { - String name = NotEnoughUpdates.INSTANCE.manager.jsonToStack(json).getDisplayName(); - petItemStr = EnumChatFormatting.AQUA + "Held Item: " + name; - } + xpGain = xpGainHourSecondPet; + } + if(xpGain < 0) xpGain = 0; + String xpGainString = EnumChatFormatting.AQUA + "XP/h: " + + EnumChatFormatting.YELLOW + roundFloat(xpGain); + if(xpGain > 0 && xpGainHour == xpGainHourLast) xpGainString += EnumChatFormatting.RED + " (PAUSED)"; + + String totalXpString = EnumChatFormatting.AQUA + "Total XP: " + EnumChatFormatting.YELLOW + roundFloat(currentPet.petLevel.totalXp); + + String petItemStr = EnumChatFormatting.AQUA+ "Held Item: " + EnumChatFormatting.RED + "None"; + if(currentPet.petItem != null) { + JsonObject json = NotEnoughUpdates.INSTANCE.manager.getItemInformation().get(currentPet.petItem); + if(json != null) { + String name = NotEnoughUpdates.INSTANCE.manager.jsonToStack(json).getDisplayName(); + petItemStr = EnumChatFormatting.AQUA + "Held Item: " + name; } + } - String etaStr = null; - String etaMaxStr = null; - if(currentPet.petLevel.level < 100) { - float remaining = currentPet.petLevel.currentLevelRequirement - currentPet.petLevel.levelXp; - if(remaining > 0) { - if(xpGain < 1000) { - etaStr = EnumChatFormatting.AQUA+"Until L"+(int)(currentPet.petLevel.level+1)+": " + - EnumChatFormatting.YELLOW+"N/A"; - } else { - etaStr = EnumChatFormatting.AQUA+"Until L"+(int)(currentPet.petLevel.level+1)+": " + - EnumChatFormatting.YELLOW + Utils.prettyTime((long)(remaining)*1000*60*60/(long)xpGain); - } + String etaStr = null; + String etaMaxStr = null; + if(currentPet.petLevel.level < 100) { + float remaining = currentPet.petLevel.currentLevelRequirement - currentPet.petLevel.levelXp; + if(remaining > 0) { + if(xpGain < 1000) { + etaStr = EnumChatFormatting.AQUA+"Until L"+(int)(currentPet.petLevel.level+1)+": " + + EnumChatFormatting.YELLOW+"N/A"; + } else { + etaStr = EnumChatFormatting.AQUA+"Until L"+(int)(currentPet.petLevel.level+1)+": " + + EnumChatFormatting.YELLOW + Utils.prettyTime((long)(remaining)*1000*60*60/(long)xpGain); } + } + if(currentPet.petLevel.level < 99 || !NotEnoughUpdates.INSTANCE.config.petOverlay.petOverlayText.contains(6)) { float remainingMax = currentPet.petLevel.maxXP - currentPet.petLevel.totalXp; if(remaining > 0) { if(xpGain < 1000) { @@ -368,28 +388,48 @@ public class PetInfoOverlay extends TextOverlay { } } } + } + + List<String> strings = new ArrayList<>(); + + for(int index : NotEnoughUpdates.INSTANCE.config.petOverlay.petOverlayText) { + switch(index) { + case 0: + strings.add(petName); break; + case 1: + strings.add(lvlStringShort); break; + case 2: + strings.add(lvlString); break; + case 3: + strings.add(xpGainString); break; + case 4: + strings.add(totalXpString); break; + case 5: + strings.add(petItemStr); break; + case 6: + if(etaStr != null) strings.add(etaStr); break; + case 7: + if(etaMaxStr != null) strings.add(etaMaxStr); break; + } + } + return strings; + } + + @Override + public void updateFrequent() { + Pet currentPet = getCurrentPet(); + if(!NotEnoughUpdates.INSTANCE.config.petOverlay.enablePetInfo || currentPet == null) { + overlayStrings = null; + } else { overlayStrings = new ArrayList<>(); - for(int index : NotEnoughUpdates.INSTANCE.config.petOverlay.petOverlayText) { - switch(index) { - case 0: - overlayStrings.add(petName); break; - case 1: - overlayStrings.add(lvlStringShort); break; - case 2: - overlayStrings.add(lvlString); break; - case 3: - overlayStrings.add(xpGainString); break; - case 4: - overlayStrings.add(totalXpString); break; - case 5: - overlayStrings.add(petItemStr); break; - case 6: - if(etaStr != null) overlayStrings.add(etaStr); break; - case 7: - if(etaMaxStr != null) overlayStrings.add(etaMaxStr); break; - } + overlayStrings.addAll(createStringsForPet(currentPet, false)); + + Pet currentPet2 = getCurrentPet2(); + if(currentPet2 != null) { + overlayStrings.add(""); + overlayStrings.addAll(createStringsForPet(currentPet2, true)); } } @@ -403,18 +443,8 @@ public class PetInfoOverlay extends TextOverlay { NEUConfig config = NotEnoughUpdates.INSTANCE.config; int updateTime = 60000; - if((config.itemOverlays.enableMonkeyCheck) && !config.petOverlay.enablePetInfo) - updateTime = 300000; if(NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) { - /*if(petList.isEmpty()) { - ProfileViewer.Profile profile = NotEnoughUpdates.profileViewer.getProfileRaw(Minecraft.getMinecraft().thePlayer - .getUniqueID().toString().replace("-", "")); - if(profile != null) { - getAndSetPet(profile); - } - }*/ - ProfileApiSyncer.getInstance().requestResync("petinfo", updateTime, () -> { }, PetInfoOverlay::getAndSetPet); } @@ -429,6 +459,32 @@ public class PetInfoOverlay extends TextOverlay { } } + private static GuiProfileViewer.PetLevel getMaxLevel(JsonArray levels, int offset) { + float xpTotal = 0; + float level = 1; + float currentLevelRequirement = 0; + + for(int i=offset; i<offset+99; i++) { + currentLevelRequirement = levels.get(i).getAsFloat(); + xpTotal += currentLevelRequirement; + level += 1; + } + + if(level <= 0) { + level = 1; + } else if(level > 100) { + level = 100; + } + GuiProfileViewer.PetLevel levelObj = new GuiProfileViewer.PetLevel(); + levelObj.level = level; + levelObj.currentLevelRequirement = currentLevelRequirement; + levelObj.maxXP = xpTotal; + levelObj.levelPercentage = 1; + levelObj.levelXp = currentLevelRequirement-5; + levelObj.totalXp = xpTotal-5; + return levelObj; + } + private static GuiProfileViewer.PetLevel getLevel(JsonArray levels, int offset, float xpThisLevel, int xpMaxThisLevel) { float xpTotal = 0; float level = 1; @@ -498,7 +554,6 @@ public class PetInfoOverlay extends TextOverlay { .replace(" ", "_").toUpperCase(); } if(petType == null || rarity == null) { - System.out.println("Failed pet : " + name); return null; } @@ -541,7 +596,7 @@ public class PetInfoOverlay extends TextOverlay { } } else if(xpLineMatcher.matches()) { String xpThisLevelS = xpLineMatcher.group(1); - String xpMaxThisLevelS = xpLineMatcher.group(2); + String xpMaxThisLevelS = xpLineMatcher.group(2).toLowerCase(); try { float xpThisLevel = Float.parseFloat(xpThisLevelS.replace(",", "")); @@ -561,6 +616,8 @@ public class PetInfoOverlay extends TextOverlay { level = getLevel(Constants.PETS.get("pet_levels").getAsJsonArray(), rarity.petOffset, xpThisLevel, xpMaxThisLevel); } catch(NumberFormatException ignored) {} + } else if(line.equals("\u00a7b\u00a7lMAX LEVEL")) { + level = getMaxLevel(Constants.PETS.get("pet_levels").getAsJsonArray(), rarity.petOffset); } } @@ -583,9 +640,6 @@ public class PetInfoOverlay extends TextOverlay { @SubscribeEvent public void onTick(TickEvent.ClientTickEvent event) { - if(Keyboard.isKeyDown(Keyboard.KEY_K)) { - System.out.println("Current:"+selectedPet+":"+getCurrentPet()); - } if(Minecraft.getMinecraft().currentScreen instanceof GuiChest) { GuiChest chest = (GuiChest) Minecraft.getMinecraft().currentScreen; ContainerChest container = (ContainerChest) chest.inventorySlots; @@ -667,7 +721,7 @@ public class PetInfoOverlay extends TextOverlay { } } if(!foundDespawn && selectedPet == petIndex) { - selectedPet = -1; + clearPet(); } } } @@ -744,6 +798,24 @@ public class PetInfoOverlay extends TextOverlay { Utils.drawItemStack(stack, 0, 0); GlStateManager.popMatrix(); } + + Pet currentPet2 = getCurrentPet2(); + if(currentPet2 != null) { + JsonObject petItem2 = NotEnoughUpdates.INSTANCE.manager.getItemInformation().get(currentPet2.petType + ";" + currentPet2.rarity.petId); + if(petItem2 != null) { + Vector2f position = getPosition(overlayWidth, overlayHeight); + int x = (int)position.x; + int y = (int)position.y + NotEnoughUpdates.INSTANCE.config.petOverlay.petOverlayText.size()*10+10; + + ItemStack stack = NotEnoughUpdates.INSTANCE.manager.jsonToStack(petItem2); + GlStateManager.enableDepth(); + GlStateManager.pushMatrix(); + GlStateManager.translate(x-2, y-2, 0); + GlStateManager.scale(2, 2, 1); + Utils.drawItemStack(stack, 0, 0); + GlStateManager.popMatrix(); + } + } } public static float getBoostMultiplier(String boostName) { @@ -807,14 +879,13 @@ public class PetInfoOverlay extends TextOverlay { System.out.println("removing"); System.out.println("new:"+newSelected+":OLD:"+selectedPet); if(newSelected == selectedPet) { - System.out.println("setting to -1"); - selectedPet = -1; + clearPet(); } else if(selectedPet > newSelected) { System.out.println("decrementing"); selectedPet--; } } else { - selectedPet = newSelected; + setCurrentPet(newSelected); String[] lore = NotEnoughUpdates.INSTANCE.manager.getLoreFromNBT(stack.getTagCompound()); Pet pet = getPetFromStack(stack.getDisplayName(), lore); @@ -831,6 +902,8 @@ public class PetInfoOverlay extends TextOverlay { } public static float getXpGain(Pet pet, float xp, String xpType) { + if(pet.petLevel.level >= 100) return 0; + if(validXpTypes == null) validXpTypes = Lists.newArrayList("mining","foraging","enchanting","farming","combat","fishing","alchemy"); if(!validXpTypes.contains(xpType.toLowerCase())) return 0; @@ -1021,10 +1094,10 @@ public class PetInfoOverlay extends TextOverlay { .replaceAll("[^\\w ]", "").trim() .replace(" ", "_").toUpperCase(); - selectedPet = getClosestPetIndex(pet, rarity.petId, "", lastLevelHovered); + setCurrentPet(getClosestPetIndex(pet, rarity.petId, "", lastLevelHovered)); if(selectedPet == -1) { Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED+"[NEU] Can't find pet \u00a7" + petStringMatch + - EnumChatFormatting.RED + " try visiting all pages of /pets.")); + EnumChatFormatting.RED + " try revisiting all pages of /pets.")); } } else if(chatMessage.toLowerCase().startsWith("you despawned your")) { clearPet(); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/CalendarOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/CalendarOverlay.java index 4a343f9e..3305cd13 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/CalendarOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/CalendarOverlay.java @@ -5,6 +5,7 @@ import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonPrimitive; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.core.BackgroundBlur; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; import net.minecraft.client.audio.PositionedSoundRecord; @@ -787,7 +788,6 @@ public class CalendarOverlay { @SubscribeEvent public void onGuiScreenDrawTimer(GuiScreenEvent.BackgroundDrawnEvent event) { - blurBackground(); if(!drawTimerForeground) { drawTimer(); } @@ -903,7 +903,7 @@ public class CalendarOverlay { GlStateManager.disableLighting(); GlStateManager.disableColorMaterial(); - renderBlurredBackground(width, height, guiLeft+3, guiTop+3, xSize-6, ySize-6); + renderBlurredBackground(10, width, height, guiLeft+3, guiTop+3, xSize-6, ySize-6); Minecraft.getMinecraft().getTextureManager().bindTexture(DISPLAYBAR); Utils.drawTexturedRect(guiLeft, guiTop, xSize, 20, GL11.GL_NEAREST); @@ -985,6 +985,13 @@ public class CalendarOverlay { GlStateManager.popMatrix(); } + private void renderBlurredBackground(float blurStrength, int screenWidth, int screenHeight, + int x, int y, int blurWidth, int blurHeight) { + BackgroundBlur.renderBlurredBackground(blurStrength, screenWidth, screenHeight, x, y, blurWidth, blurHeight); + Gui.drawRect(x, y, x+blurWidth, y+blurHeight, 0xc8101010); + GlStateManager.color(1, 1, 1, 1); + } + @SubscribeEvent public void onGuiDraw(GuiScreenEvent.DrawScreenEvent.Pre event) { if(!(Minecraft.getMinecraft().currentScreen instanceof GuiChest)) { @@ -1021,10 +1028,10 @@ public class CalendarOverlay { Utils.drawGradientRect(0, 0, width, height, -1072689136, -804253680); - renderBlurredBackground(width, height, guiLeft+3, guiTop+3, 162, 14); - renderBlurredBackground(width, height, guiLeft+3, guiTop+26, 14, 141); - renderBlurredBackground(width, height, guiLeft+151, guiTop+26, 14, 141); - renderBlurredBackground(width, height, guiLeft+26, guiTop+26, 116, 141); + renderBlurredBackground(10, width, height, guiLeft+3, guiTop+3, 162, 14); + renderBlurredBackground(10, width, height, guiLeft+3, guiTop+26, 14, 141); + renderBlurredBackground(10, width, height, guiLeft+151, guiTop+26, 14, 141); + renderBlurredBackground(10, width, height, guiLeft+26, guiTop+26, 116, 141); Minecraft.getMinecraft().getTextureManager().bindTexture(BACKGROUND); Utils.drawTexturedRect(guiLeft, guiTop, xSize, ySize, GL11.GL_NEAREST); @@ -1381,82 +1388,4 @@ public class CalendarOverlay { return projMatrix; } - private double lastBgBlurFactor = -1; - private void blurBackground() { - if(!OpenGlHelper.isFramebufferEnabled()) return; - - int width = Minecraft.getMinecraft().displayWidth; - int height = Minecraft.getMinecraft().displayHeight; - - if(blurOutputHorz == null) { - blurOutputHorz = new Framebuffer(width, height, false); - blurOutputHorz.setFramebufferFilter(GL11.GL_NEAREST); - } - if(blurOutputVert == null) { - blurOutputVert = new Framebuffer(width, height, false); - blurOutputVert.setFramebufferFilter(GL11.GL_NEAREST); - } - if(blurOutputHorz.framebufferWidth != width || blurOutputHorz.framebufferHeight != height) { - blurOutputHorz.createBindFramebuffer(width, height); - blurShaderHorz.setProjectionMatrix(createProjectionMatrix(width, height)); - Minecraft.getMinecraft().getFramebuffer().bindFramebuffer(false); - } - if(blurOutputVert.framebufferWidth != width || blurOutputVert.framebufferHeight != height) { - blurOutputVert.createBindFramebuffer(width, height); - blurShaderVert.setProjectionMatrix(createProjectionMatrix(width, height)); - Minecraft.getMinecraft().getFramebuffer().bindFramebuffer(false); - } - - if(blurShaderHorz == null) { - try { - blurShaderHorz = new Shader(Minecraft.getMinecraft().getResourceManager(), "blur", - Minecraft.getMinecraft().getFramebuffer(), blurOutputHorz); - blurShaderHorz.getShaderManager().getShaderUniform("BlurDir").set(1, 0); - blurShaderHorz.setProjectionMatrix(createProjectionMatrix(width, height)); - } catch(Exception e) { } - } - if(blurShaderVert == null) { - try { - blurShaderVert = new Shader(Minecraft.getMinecraft().getResourceManager(), "blur", - blurOutputHorz, blurOutputVert); - blurShaderVert.getShaderManager().getShaderUniform("BlurDir").set(0, 1); - blurShaderVert.setProjectionMatrix(createProjectionMatrix(width, height)); - } catch(Exception e) { } - } - if(blurShaderHorz != null && blurShaderVert != null) { - if(15 != lastBgBlurFactor) { - blurShaderHorz.getShaderManager().getShaderUniform("Radius").set((float)15); - blurShaderVert.getShaderManager().getShaderUniform("Radius").set((float)15); - lastBgBlurFactor = 15; - } - GL11.glPushMatrix(); - blurShaderHorz.loadShader(0); - blurShaderVert.loadShader(0); - GlStateManager.enableDepth(); - GL11.glPopMatrix(); - - Minecraft.getMinecraft().getFramebuffer().bindFramebuffer(false); - } - } - - /** - * Renders a subsection of the blurred framebuffer on to the corresponding section of the screen. - * Essentially, this method will "blur" the background inside the bounds specified by [x->x+blurWidth, y->y+blurHeight] - */ - public void renderBlurredBackground(int width, int height, int x, int y, int blurWidth, int blurHeight) { - if(!OpenGlHelper.isFramebufferEnabled()) return; - - float uMin = x/(float)width; - float uMax = (x+blurWidth)/(float)width; - float vMin = (height-y)/(float)height; - float vMax = (height-y-blurHeight)/(float)height; - - GlStateManager.depthMask(false); - blurOutputVert.bindFramebufferTexture(); - GlStateManager.color(1f, 1f, 1f, 1f); - Utils.drawTexturedRect(x, y, blurWidth, blurHeight, uMin, uMax, vMin, vMax); - blurOutputVert.unbindFramebufferTexture(); - GlStateManager.depthMask(true); - } - } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiInvButtonEditor.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiInvButtonEditor.java new file mode 100644 index 00000000..1260dbd2 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiInvButtonEditor.java @@ -0,0 +1,677 @@ +package io.github.moulberry.notenoughupdates.miscgui; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.annotations.Expose; +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.core.GlScissorStack; +import io.github.moulberry.notenoughupdates.core.GuiElementTextField; +import io.github.moulberry.notenoughupdates.core.util.lerp.LerpingInteger; +import io.github.moulberry.notenoughupdates.options.NEUConfig; +import io.github.moulberry.notenoughupdates.util.TexLoc; +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.init.Items; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.util.ResourceLocation; +import org.lwjgl.input.Keyboard; +import org.lwjgl.input.Mouse; +import org.lwjgl.opengl.GL11; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.util.*; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.atomic.AtomicInteger; + +public class GuiInvButtonEditor extends GuiScreen { + + private static final ResourceLocation INVENTORY = new ResourceLocation("minecraft:textures/gui/container/inventory.png"); + private static final ResourceLocation EDITOR = new ResourceLocation("notenoughupdates:invbuttons/editor.png"); + private static final ResourceLocation EXTRA_ICONS_JSON = new ResourceLocation("notenoughupdates:invbuttons/extraicons.json"); + private static final ResourceLocation PRESETS_JSON = new ResourceLocation("notenoughupdates:invbuttons/presets.json"); + + private int xSize = 176; + private int ySize = 166; + + private int guiLeft; + private int guiTop; + + private static final int BACKGROUND_TYPES = 5; + private static final int ICON_TYPES = 3; + private int iconTypeIndex = 0; + + private int editorXSize = 150; + private int editorYSize = 204; + private int editorLeft; + private int editorTop; + + private GuiElementTextField commandTextField = new GuiElementTextField("", editorXSize-14, 16, GuiElementTextField.SCALE_TEXT); + private GuiElementTextField iconTextField = new GuiElementTextField("", editorXSize-14, 16, GuiElementTextField.SCALE_TEXT); + + private static final HashSet<String> prioritisedIcons = new HashSet<>(); + static { + prioritisedIcons.add("WORKBENCH"); + prioritisedIcons.add("LEATHER_CHESTPLATE"); + prioritisedIcons.add("CHEST"); + prioritisedIcons.add("BONE"); + prioritisedIcons.add("ENDER_CHEST"); + prioritisedIcons.add("GOLD_BARDING"); + prioritisedIcons.add("COMPASS"); + prioritisedIcons.add("GOLD_BLOCK"); + prioritisedIcons.add("EMPTY_MAP"); + prioritisedIcons.add("RAW_FISH"); + prioritisedIcons.add("FISHING_ROD"); + prioritisedIcons.add("EMERALD"); + prioritisedIcons.add("IRON_SWORD"); + prioritisedIcons.add("POTION"); + prioritisedIcons.add("NETHER_STAR"); + prioritisedIcons.add("PAINTING"); + prioritisedIcons.add("COMMAND"); + prioritisedIcons.add("BOOK"); + } + + private static HashMap<String, String> extraIcons = null; + + private static final HashMap<String, String> skullIcons = new HashMap<>(); + static { + skullIcons.put("personal bank", "skull:e36e94f6c34a35465fce4a90f2e25976389eb9709a12273574ff70fd4daa6852"); + skullIcons.put("skyblock hub", "skull:d7cc6687423d0570d556ac53e0676cb563bbdd9717cd8269bdebed6f6d4e7bf8"); + skullIcons.put("private island", "skull:c9c8881e42915a9d29bb61a16fb26d059913204d265df5b439b3d792acd56"); + skullIcons.put("castle", "skull:f4559d75464b2e40a518e4de8e6cf3085f0a3ca0b1b7012614c4cd96fed60378"); + skullIcons.put("sirius shack", "skull:7ab83858ebc8ee85c3e54ab13aabfcc1ef2ad446d6a900e471c3f33b78906a5b"); + skullIcons.put("crypts", "skull:25d2f31ba162fe6272e831aed17f53213db6fa1c4cbe4fc827f3963cc98b9"); + skullIcons.put("spiders den", "skull:c754318a3376f470e481dfcd6c83a59aa690ad4b4dd7577fdad1c2ef08d8aee6"); + skullIcons.put("top of the nest", "skull:9d7e3b19ac4f3dee9c5677c135333b9d35a7f568b63d1ef4ada4b068b5a25"); + skullIcons.put("blazing fortress", "skull:c3687e25c632bce8aa61e0d64c24e694c3eea629ea944f4cf30dcfb4fbce071"); + skullIcons.put("blazing fortress magma boss", "skull:38957d5023c937c4c41aa2412d43410bda23cf79a9f6ab36b76fef2d7c429"); + skullIcons.put("the end", "skull:7840b87d52271d2a755dedc82877e0ed3df67dcc42ea479ec146176b02779a5"); + skullIcons.put("the end dragons nest", "skull:a1cd6d2d03f135e7c6b5d6cdae1b3a68743db4eb749faf7341e9fb347aa283b"); + skullIcons.put("the park", "skull:a221f813dacee0fef8c59f76894dbb26415478d9ddfc44c2e708a6d3b7549b"); + skullIcons.put("the park jungle", "skull:79ca3540621c1c79c32bf42438708ff1f5f7d0af9b14a074731107edfeb691c"); + skullIcons.put("the park howling cave", "skull:1832d53997b451635c9cf9004b0f22bb3d99ab5a093942b5b5f6bb4e4de47065"); + skullIcons.put("gold mines", "skull:73bc965d579c3c6039f0a17eb7c2e6faf538c7a5de8e60ec7a719360d0a857a9"); + skullIcons.put("deep caverns", "skull:569a1f114151b4521373f34bc14c2963a5011cdc25a6554c48c708cd96ebfc"); + skullIcons.put("the barn", "skull:4d3a6bd98ac1833c664c4909ff8d2dc62ce887bdcf3cc5b3848651ae5af6b"); + skullIcons.put("mushroom desert", "skull:2116b9d8df346a25edd05f842e7a9345beaf16dca4118abf5a68c75bcaae10"); + skullIcons.put("dungeon hub", "skull:9b56895b9659896ad647f58599238af532d46db9c1b0389b8bbeb70999dab33d"); + skullIcons.put("dwarven mines", "skull:569a1f114151b4521373f34bc14c2963a5011cdc25a6554c48c708cd96ebfc"); + skullIcons.put("hotm heart of the mountain", "skull:86f06eaa3004aeed09b3d5b45d976de584e691c0e9cade133635de93d23b9edb"); + skullIcons.put("bazaar dude", "skull:c232e3820897429157619b0ee099fec0628f602fff12b695de54aef11d923ad7"); + } + + private static LinkedHashMap<String, List<NEUConfig.InventoryButton>> presets = null; + + public GuiInvButtonEditor() { + super(); + reloadExtraIcons(); + reloadPresets(); + Keyboard.enableRepeatEvents(true); + } + + private static void reloadExtraIcons() { + extraIcons = new HashMap<>(); + + try(BufferedReader reader = new BufferedReader(new InputStreamReader( + Minecraft.getMinecraft().getResourceManager().getResource(EXTRA_ICONS_JSON).getInputStream(), StandardCharsets.UTF_8))) { + JsonObject json = NotEnoughUpdates.INSTANCE.manager.gson.fromJson(reader, JsonObject.class); + + for(Map.Entry<String, JsonElement> entry : json.entrySet()) { + if(entry.getValue().isJsonPrimitive()) { + extraIcons.put(entry.getKey(), "extra:"+entry.getValue().getAsString()); + } + } + } catch(Exception e) { + } + } + + private static void reloadPresets() { + presets = new LinkedHashMap<>(); + + try(BufferedReader reader = new BufferedReader(new InputStreamReader( + Minecraft.getMinecraft().getResourceManager().getResource(PRESETS_JSON).getInputStream(), StandardCharsets.UTF_8))) { + JsonObject json = NotEnoughUpdates.INSTANCE.manager.gson.fromJson(reader, JsonObject.class); + + for(Map.Entry<String, JsonElement> entry : json.entrySet()) { + if(entry.getValue().isJsonArray()) { + JsonArray arr = entry.getValue().getAsJsonArray(); + List<NEUConfig.InventoryButton> buttons = new ArrayList<>(); + for(int i=0; i<arr.size(); i++) { + JsonObject o = arr.get(i).getAsJsonObject(); + NEUConfig.InventoryButton button = NotEnoughUpdates.INSTANCE.manager.gson.fromJson(o, NEUConfig.InventoryButton.class); + buttons.add(button); + } + presets.put(entry.getKey(), buttons); + } + } + } catch(Exception e) { + } + } + + private static final Comparator<String> prioritisingComparator = (o1, o2) -> { + boolean c1 = prioritisedIcons.contains(o1); + boolean c2 = prioritisedIcons.contains(o2); + + if(c1 && !c2) return -1; + if(!c1 && c2) return 1; + + return o1.compareTo(o2); + }; + + private final List<String> searchedIcons = new ArrayList<>(); + + private LerpingInteger itemScroll = new LerpingInteger(0, 100); + + private NEUConfig.InventoryButton editingButton = null; + + private static HashMap<String, ItemStack> skullMap = new HashMap<>(); + + public static void renderIcon(String icon, int x, int y) { + if(extraIcons == null) { + reloadExtraIcons(); + } + + if(icon.startsWith("extra:")) { + String name = icon.substring("extra:".length()); + ResourceLocation resourceLocation = new ResourceLocation("notenoughupdates:invbuttons/extraicons/"+name+".png"); + Minecraft.getMinecraft().getTextureManager().bindTexture(resourceLocation); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(x, y, 16, 16, GL11.GL_NEAREST); + } else { + ItemStack stack = getStack(icon); + + float scale = 1; + if(icon.startsWith("skull:")) { + scale = 1.2f; + } + GlStateManager.pushMatrix(); + GlStateManager.translate(x+8, y+8, 0); + GlStateManager.scale(scale, scale, 1); + GlStateManager.translate(-8, -8, 0); + Utils.drawItemStack(stack, 0, 0); + GlStateManager.popMatrix(); + } + } + + public static ItemStack getStack(String icon) { + if(icon.startsWith("extra:")) { + return null; + } else if(icon.startsWith("skull:")) { + String link = icon.substring("skull:".length()); + if(skullMap.containsKey(link)) return skullMap.get(link); + + ItemStack render = new ItemStack(Items.skull, 1, 3); + NBTTagCompound nbt = new NBTTagCompound(); + NBTTagCompound skullOwner = new NBTTagCompound(); + NBTTagCompound properties = new NBTTagCompound(); + NBTTagList textures = new NBTTagList(); + NBTTagCompound textures_0 = new NBTTagCompound(); + + String uuid = UUID.nameUUIDFromBytes(link.getBytes()).toString(); + skullOwner.setString("Id", uuid); + skullOwner.setString("Name", uuid); + + String display = "{\"textures\":{\"SKIN\":{\"url\":\"http://textures.minecraft.net/texture/"+link+"\"}}}"; + String displayB64 = Base64.getEncoder().encodeToString(display.getBytes()); + + textures_0.setString("Value", displayB64); + textures.appendTag(textures_0); + + properties.setTag("textures", textures); + skullOwner.setTag("Properties", properties); + nbt.setTag("SkullOwner", skullOwner); + render.setTagCompound(nbt); + + skullMap.put(link, render); + return render; + } else { + return NotEnoughUpdates.INSTANCE.manager.jsonToStack(NotEnoughUpdates.INSTANCE.manager.getItemInformation().get(icon)); + } + } + + @Override + public void drawScreen(int mouseX, int mouseY, float partialTicks) { + super.drawScreen(mouseX, mouseY, partialTicks); + + super.drawDefaultBackground(); + + guiLeft = width/2 - xSize/2; + guiTop = height/2 - ySize/2; + + GlStateManager.enableDepth(); + + Minecraft.getMinecraft().getTextureManager().bindTexture(INVENTORY); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(guiLeft, guiTop, xSize, ySize, 0, xSize/256f, 0, ySize/256f, GL11.GL_NEAREST); + + for(NEUConfig.InventoryButton button : NotEnoughUpdates.INSTANCE.config.hidden.inventoryButtons) { + int x = guiLeft+button.x; + int y = guiTop+button.y; + if(button.anchorRight) { + x += xSize; + } + if(button.anchorBottom) { + y += ySize; + } + + if(button.isActive()) { + GlStateManager.color(1, 1, 1, 1f); + } else { + GlStateManager.color(1, 1, 1, 0.5f); + } + + Minecraft.getMinecraft().getTextureManager().bindTexture(EDITOR); + Utils.drawTexturedRect(x, y, 18, 18, + button.backgroundIndex*18/256f, (button.backgroundIndex*18+18)/256f, 18/256f, 36/256f, GL11.GL_NEAREST); + + if(button.isActive()) { + if(button.icon != null && !button.icon.trim().isEmpty()) { + GlStateManager.enableDepth(); + + renderIcon(button.icon, x+1, y+1); + } + } else { + fontRendererObj.drawString("+", x+6, y+5, 0xffcccccc); + } + } + + if(presets != null) { + Minecraft.getMinecraft().getTextureManager().bindTexture(EDITOR); + Utils.drawTexturedRect(guiLeft+xSize+22, guiTop, 80, ySize, + editorXSize/256f, (editorXSize+80)/256f, 41/256f, (41+ySize)/256f, GL11.GL_NEAREST); + Utils.drawStringCenteredScaledMaxWidth("\u00a7nPresets", fontRendererObj, guiLeft+xSize+22+40, guiTop+10, false, 70, 0xffa0a0a0); + + int index = 0; + for(String presetName : presets.keySet()) { + Utils.drawStringCenteredScaledMaxWidth(presetName, fontRendererObj, guiLeft+xSize+22+40, guiTop+25+10*(index++), + false, 70, 0xff909090); + } + } + + if(editingButton != null) { + int x = guiLeft+editingButton.x; + int y = guiTop+editingButton.y; + if(editingButton.anchorRight) { + x += xSize; + } + if(editingButton.anchorBottom) { + y += ySize; + } + + GlStateManager.translate(0, 0, 300); + editorLeft = x + 8 - editorXSize/2; + editorTop = y + 18 + 2; + + boolean showArrow = true; + if(editorTop+editorYSize+5 > height) { + editorTop = height-editorYSize-5; + showArrow = false; + } + if(editorLeft < 5) { + editorLeft = 5; + showArrow = false; + } + if(editorLeft+editorXSize+5 > width) { + editorLeft = width-editorXSize-5; + showArrow = false; + } + + Minecraft.getMinecraft().getTextureManager().bindTexture(EDITOR); + GlStateManager.color(1, 1, 1, 1f); + Utils.drawTexturedRect(editorLeft, editorTop, editorXSize, editorYSize, 0, editorXSize/256f, 41/256f, (41+editorYSize)/256f, GL11.GL_NEAREST); + + if(showArrow) Utils.drawTexturedRect(x+8-3, y+18, 10, 5, 0, 6/256f, 36/256f, 41/256f, GL11.GL_NEAREST); + + fontRendererObj.drawString("Command", editorLeft+7, editorTop+7, 0xffa0a0a0, false); + + commandTextField.setSize(editorXSize-14, 16); + commandTextField.setText(commandTextField.getText().replaceAll("^ +", "")); + if(commandTextField.getText().startsWith("/")) { + commandTextField.setPrependText(""); + } else { + commandTextField.setPrependText("\u00a77/\u00a7r"); + } + commandTextField.render(editorLeft+7, editorTop+19); + + fontRendererObj.drawString("Background", editorLeft+7, editorTop+40, 0xffa0a0a0, false); + + for(int i=0; i<BACKGROUND_TYPES; i++) { + if(i == editingButton.backgroundIndex) { + Gui.drawRect(editorLeft+7+20*i-1, editorTop+50-1, editorLeft+7+20*i+19, editorTop+50+19, 0xff0000ff); + } + Minecraft.getMinecraft().getTextureManager().bindTexture(EDITOR); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(editorLeft+7+20*i, editorTop+50, 18, 18, + i*18/256f, (i*18+18)/256f, 0/256f, 18/256f, GL11.GL_NEAREST); + } + + fontRendererObj.drawString("Icon Type", editorLeft+7, editorTop+50+24, 0xffa0a0a0, false); + + Minecraft.getMinecraft().getTextureManager().bindTexture(EDITOR); + GlStateManager.color(1, 1, 1, 1); + float uMin = 18/256f; + float uMax = 36/256f; + float vMin = 0; + float vMax = 18/256f; + + for(int i=0; i<ICON_TYPES; i++) { + boolean flip = iconTypeIndex == i; + + Minecraft.getMinecraft().getTextureManager().bindTexture(EDITOR); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(editorLeft+7+20*i, editorTop+50+34, 18, 18, + flip ? uMax : uMin, flip ? uMin : uMax, flip ? vMax : vMin, flip ? vMin : vMax, GL11.GL_NEAREST); + + ItemStack stack = null; + if(i == 0) { + stack = new ItemStack(Items.diamond_sword); + } else if(i == 1) { + stack = getStack("skull:c9c8881e42915a9d29bb61a16fb26d059913204d265df5b439b3d792acd56"); + } else if(i == 2) { + stack = new ItemStack(Items.lead); + } + if(stack != null) Utils.drawItemStack(stack, editorLeft+8+20*i, editorTop+50+35); + } + + fontRendererObj.drawString("Icon Selector", editorLeft+7, editorTop+50+55, 0xffa0a0a0, false); + + iconTextField.render(editorLeft+7, editorTop+50+65); + + GlStateManager.enableDepth(); + + itemScroll.tick(); + + ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft()); + GlScissorStack.push(0, editorTop+136, width, editorTop+196, scaledResolution); + + synchronized(searchedIcons) { + if(iconTextField.getText().trim().isEmpty() && searchedIcons.isEmpty()) { + searchedIcons.addAll(NotEnoughUpdates.INSTANCE.manager.getItemInformation().keySet()); + searchedIcons.sort(prioritisingComparator); + } + + int max = (searchedIcons.size()-1)/6*20-40; + int scroll = itemScroll.getValue(); + if(scroll > max) scroll = max; + + int scrollBarHeight = (int)Math.ceil(3f*54f/(searchedIcons.size()-18)); + if(scrollBarHeight < 0) scrollBarHeight = 54; + if(scrollBarHeight < 2) scrollBarHeight = 2; + int scrollY = (int)Math.floor(54f*((scroll/20f) / ((searchedIcons.size()-18)/6f))); + if(scrollY+scrollBarHeight > 54) scrollY = 54-scrollBarHeight; + + Gui.drawRect(editorLeft+137, editorTop+139+scrollY, editorLeft+139, editorTop+139+scrollY+scrollBarHeight, 0xff202020); + + int endIndex = searchedIcons.size(); + int startIndex = scroll/20*6; + if(startIndex < 0) startIndex = 0; + if(endIndex > startIndex+24) endIndex = startIndex+24; + + for(int i=startIndex; i<endIndex; i++) { + String iconS = searchedIcons.get(i); + + int iconX = editorLeft+12+((i-startIndex)%6)*20; + int iconY = editorTop+137+((i-startIndex)/6)*20 - (itemScroll.getValue()%20); + + Minecraft.getMinecraft().getTextureManager().bindTexture(EDITOR); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(iconX, iconY, 18, 18, + 18/256f, 36/256f, 0/256f, 18/256f, GL11.GL_NEAREST); + + renderIcon(iconS, iconX+1, iconY+1); + } + } + + GlScissorStack.pop(scaledResolution); + + GlStateManager.translate(0, 0, -300); + } + } + + @Override + public void handleMouseInput() throws IOException { + int scroll = Mouse.getEventDWheel(); + if(scroll != 0) { + scroll = -scroll; + if(scroll > 1) scroll = 8; + if(scroll < -1) scroll = -8; + + int delta = Math.abs(itemScroll.getTarget() - itemScroll.getValue()); + float acc = delta/20+1; + scroll *= acc; + + int max = (searchedIcons.size()-1)/6*20-40; + int newTarget = itemScroll.getTarget() + scroll; + + if(newTarget > max) newTarget = max; + if(newTarget < 0) newTarget = 0; + + itemScroll.setTarget(newTarget); + itemScroll.resetTimer(); + } + + super.handleMouseInput(); + } + + @Override + protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException { + super.mouseClicked(mouseX, mouseY, mouseButton); + + if(editingButton != null) { + if(mouseX >= editorLeft && mouseX <= editorLeft+editorXSize && + mouseY >= editorTop & mouseY <= editorTop + editorYSize) { + if(mouseX >= editorLeft+7 && mouseX <= editorLeft+7+commandTextField.getWidth() && + mouseY >= editorTop+12 && mouseY <= editorTop+12+commandTextField.getHeight()) { + commandTextField.mouseClicked(mouseX, mouseY, mouseButton); + iconTextField.unfocus(); + editingButton.command = commandTextField.getText(); + return; + } + if(mouseX >= editorLeft+7 && mouseX <= editorLeft+7+iconTextField.getWidth() && + mouseY >= editorTop+50+65 && mouseY <= editorTop+50+65+iconTextField.getHeight()) { + iconTextField.mouseClicked(mouseX, mouseY, mouseButton); + + if(mouseButton == 1) { + search(); + } + + commandTextField.unfocus(); + return; + } + if(mouseY >= editorTop+50 && mouseY <= editorTop+50+18) { + for(int i=0; i<BACKGROUND_TYPES; i++) { + if(mouseX >= editorLeft+7+20*i && mouseX <= editorLeft+7+20*i+18) { + editingButton.backgroundIndex = i; + return; + } + } + } + for(int i=0; i<ICON_TYPES; i++) { + if(mouseX >= editorLeft+7+20*i && mouseX <= editorLeft+7+20*i+18 && + mouseY >= editorTop+50+34 && mouseY <= editorTop+50+34+18) { + if(iconTypeIndex != i) { + iconTypeIndex = i; + search(); + } + return; + } + } + if(mouseX > editorLeft+8 && mouseX < editorLeft+editorXSize-16 && mouseY > editorTop+136 && mouseY < editorTop+196) { + synchronized(searchedIcons) { + int max = (searchedIcons.size()-1)/6*20-40; + int scroll = itemScroll.getValue(); + if(scroll > max) scroll = max; + + int endIndex = searchedIcons.size(); + int startIndex = scroll/20*6; + if(startIndex < 0) startIndex = 0; + if(endIndex > startIndex+24) endIndex = startIndex+24; + + for(int i=startIndex; i<endIndex; i++) { + String iconS = searchedIcons.get(i); + + int x = editorLeft+12+((i-startIndex)%6)*20; + int y = editorTop+137+((i-startIndex)/6)*20 - (itemScroll.getValue()%20); + + if(mouseX >= x && mouseX <= x+18 && + mouseY >= y && mouseY <= y+18) { + editingButton.icon = iconS; + return; + } + } + } + } + return; + } + } + + for(NEUConfig.InventoryButton button : NotEnoughUpdates.INSTANCE.config.hidden.inventoryButtons) { + int x = guiLeft+button.x; + int y = guiTop+button.y; + if(button.anchorRight) { + x += xSize; + } + if(button.anchorBottom) { + y += ySize; + } + + if(mouseX >= x && mouseY >= y && + mouseX <= x+18 && mouseY <= y+18) { + if(editingButton == button) { + editingButton = null; + } else { + editingButton = button; + commandTextField.setText(editingButton.command); + } + return; + } + } + + if(editingButton == null) { + int index = 0; + for(List<NEUConfig.InventoryButton> buttons : presets.values()) { + if(mouseX >= guiLeft+xSize+22 && mouseX <= guiLeft+xSize+22+80 && + mouseY >= guiTop+21+10*index && mouseY <= guiTop+21+10*index+10) { + NotEnoughUpdates.INSTANCE.config.hidden.inventoryButtons = buttons; + return; + } + index++; + } + } + + editingButton = null; + } + + @Override + protected void keyTyped(char typedChar, int keyCode) throws IOException { + super.keyTyped(typedChar, keyCode); + + if(editingButton != null && commandTextField.getFocus()) { + commandTextField.keyTyped(typedChar, keyCode); + editingButton.command = commandTextField.getText(); + } else if(editingButton != null && iconTextField.getFocus()) { + String old = iconTextField.getText().trim(); + iconTextField.keyTyped(typedChar, keyCode); + String newText = iconTextField.getText().trim(); + + if(!old.equalsIgnoreCase(newText)) { + search(); + } + } + } + + private ExecutorService searchES = Executors.newSingleThreadExecutor(); + private AtomicInteger searchId = new AtomicInteger(0); + + public void search() { + final int thisSearchId = searchId.incrementAndGet(); + final String searchString = iconTextField.getText(); + + if(iconTypeIndex == 0) { + if(searchString.trim().isEmpty()) { + synchronized(searchedIcons) { + searchedIcons.clear(); + + List<String> unsorted = new ArrayList<>(NotEnoughUpdates.INSTANCE.manager.getItemInformation().keySet()); + unsorted.sort(prioritisingComparator); + searchedIcons.addAll(unsorted); + } + return; + } + + searchES.submit(() -> { + if(thisSearchId != searchId.get()) return; + + List<String> title = new ArrayList<>(NotEnoughUpdates.INSTANCE.manager.search("title:" + searchString.trim())); + + if(thisSearchId != searchId.get()) return; + + if(!searchString.trim().contains(" ")) { + StringBuilder sb = new StringBuilder(); + for(char c : searchString.toCharArray()) { + sb.append(c).append(" "); + } + title.addAll(NotEnoughUpdates.INSTANCE.manager.search("title:" + sb.toString().trim())); + } + + if(thisSearchId != searchId.get()) return; + + List<String> desc = new ArrayList<>(NotEnoughUpdates.INSTANCE.manager.search("desc:" + searchString.trim())); + desc.removeAll(title); + + if(thisSearchId != searchId.get()) return; + + title.sort(prioritisingComparator); + desc.sort(prioritisingComparator); + + if(thisSearchId != searchId.get()) return; + + synchronized(searchedIcons) { + searchedIcons.clear(); + searchedIcons.addAll(title); + searchedIcons.addAll(desc); + } + }); + } else if(iconTypeIndex == 1) { + if(searchString.trim().isEmpty()) { + searchedIcons.clear(); + searchedIcons.addAll(skullIcons.values()); + return; + } + + synchronized(searchedIcons) { + searchedIcons.clear(); + for(Map.Entry<String, String> entry : skullIcons.entrySet()) { + if(NotEnoughUpdates.INSTANCE.manager.searchString(entry.getKey(), searchString)) { + searchedIcons.add(entry.getValue()); + } + } + } + } else if(iconTypeIndex == 2) { + if(searchString.trim().isEmpty()) { + searchedIcons.clear(); + searchedIcons.addAll(extraIcons.values()); + return; + } + + synchronized(searchedIcons) { + searchedIcons.clear(); + for(Map.Entry<String, String> entry : extraIcons.entrySet()) { + if(NotEnoughUpdates.INSTANCE.manager.searchString(entry.getKey(), searchString)) { + searchedIcons.add(entry.getValue()); + } + } + } + } + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/GuiContainerAccessor.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/GuiContainerAccessor.java new file mode 100644 index 00000000..57d4de2a --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/GuiContainerAccessor.java @@ -0,0 +1,22 @@ +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/MixinContainer.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinContainer.java index fb6fba4e..58aeb828 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinContainer.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinContainer.java @@ -17,7 +17,7 @@ public class MixinContainer { @Inject(method = "putStacksInSlots", at=@At("RETURN")) public void putStacksInSlots(ItemStack[] stacks, CallbackInfo ci) { - EnchantingSolvers.processInventoryContents(); + EnchantingSolvers.processInventoryContents(false); } } 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 1281dec4..0c822827 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiContainer.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiContainer.java @@ -1,13 +1,19 @@ package io.github.moulberry.notenoughupdates.mixins; +import io.github.moulberry.notenoughupdates.NEUEventListener; +import io.github.moulberry.notenoughupdates.NEUOverlay; 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.util.Utils; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Gui; import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.gui.GuiTextField; import net.minecraft.client.gui.inventory.GuiChest; import net.minecraft.client.gui.inventory.GuiContainer; +import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.RenderHelper; import net.minecraft.inventory.Container; import net.minecraft.inventory.ContainerChest; @@ -28,6 +34,16 @@ public abstract class MixinGuiContainer extends GuiScreen { public void drawSlot(Slot slot, CallbackInfo ci) { if(slot == null) return; + if(slot.getStack() == null && NotEnoughUpdates.INSTANCE.overlay.searchMode && NEUEventListener.drawingGuiScreen) { + GlStateManager.pushMatrix(); + GlStateManager.translate(0, 0, 100 + Minecraft.getMinecraft().getRenderItem().zLevel); + GlStateManager.depthMask(false); + Gui.drawRect(slot.xDisplayPosition, slot.yDisplayPosition, + slot.xDisplayPosition+16, slot.yDisplayPosition+16, NEUOverlay.overlayColourDark); + GlStateManager.depthMask(true); + GlStateManager.popMatrix(); + } + GuiContainer $this = (GuiContainer)(Object)this; ItemStack stack = slot.getStack(); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiInventory.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiInventory.java new file mode 100644 index 00000000..9a5d739e --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiInventory.java @@ -0,0 +1,22 @@ +package io.github.moulberry.notenoughupdates.mixins; + +import io.github.moulberry.notenoughupdates.NEUEventListener; +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import net.minecraft.client.gui.inventory.GuiInventory; +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(GuiInventory.class) +public class MixinGuiInventory { + + @Inject(method="drawGuiContainerForegroundLayer", at=@At("HEAD"), cancellable = true) + protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY, CallbackInfo ci) { + if(NotEnoughUpdates.INSTANCE.config.inventoryButtons.hideCrafting || + NEUEventListener.disableCraftingText) { + ci.cancel(); + } + } + +} 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 c20ccebe..239dbe93 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinItemStack.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinItemStack.java @@ -28,6 +28,10 @@ public class MixinItemStack { @Inject(method="getDisplayName",at=@At("HEAD"), cancellable=true) public void getDisplayName(CallbackInfoReturnable<String> returnable) { try { + if(stackTagCompound == null || !stackTagCompound.hasKey("ExtraAttributes", 10)) { + return; + } + String customName = NotEnoughUpdates.INSTANCE.manager.itemRenameJson .get(stackTagCompound.getCompoundTag("ExtraAttributes").getString("uuid")).getAsString(); if(customName != null && !customName.equals("")) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinLayerCreeperCharge.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinLayerCreeperCharge.java deleted file mode 100644 index e6c9f048..00000000 --- a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinLayerCreeperCharge.java +++ /dev/null @@ -1,26 +0,0 @@ -package io.github.moulberry.notenoughupdates.mixins; - -import io.github.moulberry.notenoughupdates.miscfeatures.MiningStuff; -import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.client.renderer.entity.layers.LayerCreeperCharge; -import net.minecraft.entity.monster.EntityCreeper; -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.Inject; -import org.spongepowered.asm.mixin.injection.Redirect; - -@Mixin(LayerCreeperCharge.class) -public class MixinLayerCreeperCharge { - - /*@Redirect(method="doRenderLayer", at=@At( - value = "INVOKE", - target = "Lnet/minecraft/client/renderer/GlStateManager;color(FFFF)V")) - public void doRenderLayer_color(float red, float green, float blue, float alpha) { - Vector3f col = MiningStuff.getCreeperColour(); - GlStateManager.color(col.getX(), col.getY(), col.getZ(), alpha); - }*/ - - - -} 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 f20a5557..7f88b369 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinNetHandlerPlayClient.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinNetHandlerPlayClient.java @@ -31,7 +31,7 @@ public class MixinNetHandlerPlayClient { @Inject(method="handleSetSlot", at=@At("HEAD")) public void handleSetSlot(S2FPacketSetSlot packetIn, CallbackInfo ci) { - EnchantingSolvers.processInventoryContents(); + EnchantingSolvers.processInventoryContents(false); } @Inject(method="handleBlockChange", at=@At("HEAD")) @@ -45,13 +45,13 @@ 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); } - } + }*/ @Inject(method="handlePlayerListHeaderFooter", at=@At("HEAD")) public void handlePlayerListHeaderFooter(S47PacketPlayerListHeaderFooter packetIn, CallbackInfo ci) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinPlayerControllerMP.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinPlayerControllerMP.java index 2183e437..308dc779 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinPlayerControllerMP.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinPlayerControllerMP.java @@ -20,10 +20,10 @@ public class MixinPlayerControllerMP { @Inject(method="clickBlock", at=@At("HEAD"), cancellable = true) public void clickBlock(BlockPos loc, EnumFacing face, CallbackInfoReturnable<Boolean> cir) { ItemCooldowns.blockClicked(loc); - if(MiningStuff.blockClicked(loc)) { + /*if(MiningStuff.blockClicked(loc)) { cir.setReturnValue(false); ((PlayerControllerMP)(Object)this).resetBlockRemoving(); - } + }*/ } } 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 afd44fd3..5fcb6e84 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinRenderItem.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinRenderItem.java @@ -1,13 +1,20 @@ 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.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; +import net.minecraft.client.gui.GuiTextField; 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.vertex.DefaultVertexFormats; +import net.minecraft.client.resources.model.IBakedModel; import net.minecraft.item.ItemStack; import org.lwjgl.input.Keyboard; import org.spongepowered.asm.mixin.Mixin; @@ -17,6 +24,8 @@ import org.spongepowered.asm.mixin.injection.Inject; 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 { @@ -34,8 +43,81 @@ public abstract class MixinRenderItem { Tessellator.getInstance().draw(); } + @Inject(method="renderItemIntoGUI", at=@At("HEAD")) + public void renderItemHead(ItemStack stack, int x, int y, CallbackInfo ci) { + if(NotEnoughUpdates.INSTANCE.overlay.searchMode && NEUEventListener.drawingGuiScreen) { + boolean matches = false; + + GuiTextField textField = NotEnoughUpdates.INSTANCE.overlay.getTextField(); + + if(textField.getText().trim().isEmpty()) { + matches = true; + } else if(stack != null) { + for(String search : textField.getText().split("\\|")) { + matches |= NotEnoughUpdates.INSTANCE.manager.doesStackMatchSearch(stack, search.trim()); + } + } + if(matches) { + GlStateManager.pushMatrix(); + GlStateManager.translate(0, 0, 100 + Minecraft.getMinecraft().getRenderItem().zLevel); + GlStateManager.depthMask(false); + Gui.drawRect(x, y, x+16, y+16, NEUOverlay.overlayColourLight); + GlStateManager.depthMask(true); + GlStateManager.popMatrix(); + } + } + } + + @Inject(method="renderItemIntoGUI", at=@At("RETURN")) + public void renderItemReturn(ItemStack stack, int x, int y, CallbackInfo ci) { + if(stack != null && stack.stackSize != 1) return; + if(NotEnoughUpdates.INSTANCE.overlay.searchMode && NEUEventListener.drawingGuiScreen) { + boolean matches = false; + + GuiTextField textField = NotEnoughUpdates.INSTANCE.overlay.getTextField(); + + if(textField.getText().trim().isEmpty()) { + matches = true; + } else if(stack != null) { + for(String search : textField.getText().split("\\|")) { + matches |= NotEnoughUpdates.INSTANCE.manager.doesStackMatchSearch(stack, search.trim()); + } + } + if(!matches) { + GlStateManager.pushMatrix(); + GlStateManager.translate(0, 0, 110 + Minecraft.getMinecraft().getRenderItem().zLevel); + Gui.drawRect(x, y, x+16, y+16, NEUOverlay.overlayColourDark); + GlStateManager.popMatrix(); + } + } + } + @Inject(method="renderItemOverlayIntoGUI", at=@At("RETURN")) public void renderItemOverlayIntoGUI(FontRenderer fr, ItemStack stack, int xPosition, int yPosition, String text, CallbackInfo ci) { + if(stack != null && stack.stackSize != 1) { + if(NotEnoughUpdates.INSTANCE.overlay.searchMode && NEUEventListener.drawingGuiScreen) { + boolean matches = false; + + GuiTextField textField = NotEnoughUpdates.INSTANCE.overlay.getTextField(); + + if(textField.getText().trim().isEmpty()) { + matches = true; + } else { + for(String search : textField.getText().split("\\|")) { + matches |= NotEnoughUpdates.INSTANCE.manager.doesStackMatchSearch(stack, search.trim()); + } + } + if(!matches) { + GlStateManager.pushMatrix(); + GlStateManager.translate(0, 0, 110 + Minecraft.getMinecraft().getRenderItem().zLevel); + GlStateManager.disableDepth(); + Gui.drawRect(xPosition, yPosition, xPosition+16, yPosition+16, NEUOverlay.overlayColourDark); + GlStateManager.enableDepth(); + GlStateManager.popMatrix(); + } + } + } + if(stack == null) return; float damageOverride = ItemCooldowns.getDurabilityOverride(stack); 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 2ff43bd8..ae011f92 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java @@ -8,6 +8,8 @@ import io.github.moulberry.notenoughupdates.core.config.Config; import io.github.moulberry.notenoughupdates.core.config.Position; import io.github.moulberry.notenoughupdates.core.config.annotations.*; import io.github.moulberry.notenoughupdates.core.config.gui.GuiPositionEditor; +import io.github.moulberry.notenoughupdates.miscgui.GuiInvButtonEditor; +import io.github.moulberry.notenoughupdates.miscgui.NEUOverlayPlacements; import io.github.moulberry.notenoughupdates.overlays.*; import io.github.moulberry.notenoughupdates.util.SBInfo; import net.minecraft.client.Minecraft; @@ -70,6 +72,12 @@ public class NEUConfig extends Config { case 5: editOverlay(activeConfigCategory, OverlayManager.timersOverlay, miscOverlays.todoPosition); return; + case 6: + NotEnoughUpdates.INSTANCE.openGui = new NEUOverlayPlacements(); + return; + case 7: + NotEnoughUpdates.INSTANCE.openGui = new GuiInvButtonEditor(); + return; } } @@ -104,6 +112,13 @@ public class NEUConfig extends Config { @Expose @Category( + name = "Inventory Buttons", + desc = "Inventory Buttons" + ) + public InventoryButtons inventoryButtons = new InventoryButtons(); + + @Expose + @Category( name = "Tooltip Tweaks", desc = "Tooltip Tweaks" ) @@ -394,6 +409,14 @@ public class NEUConfig extends Config { public static class Toolbar { @Expose @ConfigOption( + name = "Edit Toolbar Positions", + desc = "Edit the position of the QuickCommands / Search Bar" + ) + @ConfigEditorButton(runnableId = 6, buttonText = "Edit") + public boolean positionButton = true; + + @Expose + @ConfigOption( name = "Show Quick Commands", desc = "Show QuickCommands\u2122 in the NEU toolbar" ) @@ -443,6 +466,34 @@ public class NEUConfig extends Config { public int quickCommandsClickType = 0; } + public static class InventoryButtons { + @Expose + @ConfigOption( + name = "Open Button Editor", + desc = "Open button editor GUI (/neubuttons)" + ) + @ConfigEditorButton(runnableId = 7, buttonText = "Open") + public boolean openEditorButton = true; + + @Expose + @ConfigOption( + name = "Always Hide \"Crafting\" Text", + desc = "Hide crafting text in inventory, even when no button is there" + ) + @ConfigEditorBoolean + public boolean hideCrafting = false; + + @Expose + @ConfigOption( + name = "Button Click Type", + desc = "Change the click type needed to trigger commands" + ) + @ConfigEditorDropdown( + values = {"Mouse Down", "Mouse Up"} + ) + public int clickType = 0; + } + public static class TooltipTweaks { @ConfigOption( name = "Tooltip Price Information", @@ -1035,24 +1086,25 @@ public class NEUConfig extends Config { ) @ConfigAccordionId(id = 0) public int todoStyle = 0; - } - public static class EnchSolvers { @Expose @ConfigOption( - name = "Enable Solvers", - desc = "Turn on solvers for the experimentation table" + name = "Todo Icons", + desc = "Add little item icons next to the lines in the todo overlay" ) @ConfigEditorBoolean - public boolean enableEnchantingSolvers = true; + @ConfigAccordionId(id = 0) + public boolean todoIcons = true; + } + public static class EnchSolvers { @Expose @ConfigOption( - name = "Prevent Misclicks", - desc = "Prevent accidentally failing the Chronomatron and Ultrasequencer experiments" + name = "Enable Solvers", + desc = "Turn on solvers for the experimentation table" ) @ConfigEditorBoolean - public boolean preventMisclicks = true; + public boolean enableEnchantingSolvers = true; @Expose @ConfigOption( @@ -1282,21 +1334,6 @@ public class NEUConfig extends Config { @ConfigEditorBoolean public boolean titaniumAlert = true; - @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 { @@ -1494,6 +1531,14 @@ public class NEUConfig extends Config { values = {"Background", "No Shadow", "Shadow Only", "Full Shadow"} ) public int petInfoOverlayStyle = 0; + + @Expose + @ConfigOption( + name = "Show Last Pet", + desc = "Show 2 pets on the overlay\nUseful if training two pets at once with autopet" + ) + @ConfigEditorBoolean + public boolean dualPets = false; } public static class AuctionHouseSearch { @@ -1586,6 +1631,7 @@ public class NEUConfig extends Config { public static class Hidden { @Expose public HashMap<String, HiddenProfileSpecific> profileSpecific = new HashMap<>(); + @Expose public List<InventoryButton> inventoryButtons = createDefaultInventoryButtons(); @Expose public boolean enableItemEditing = false; @Expose public boolean cacheRenderedItempane = true; @@ -1612,6 +1658,95 @@ public class NEUConfig extends Config { "Looting:\u003e:3:5:0"); } + public static List<InventoryButton> createDefaultInventoryButtons() { + List<InventoryButton> buttons = new ArrayList<>(); + //Below crafting + buttons.add(new InventoryButton(87, 63, null, true, false, false, 0, "")); + buttons.add(new InventoryButton(87+21, 63, null, true, false, false, 0, "")); + buttons.add(new InventoryButton(87+21*2, 63, null, true, false, false, 0, "")); + buttons.add(new InventoryButton(87+21*3, 63, null, true, false, false, 0, "")); + + //Above crafting + buttons.add(new InventoryButton(87, 5, null, true, false, false, 0, "")); + buttons.add(new InventoryButton(87+21, 5, null, true, false, false, 0, "")); + buttons.add(new InventoryButton(87+21*2, 5, null, true, false, false, 0, "")); + buttons.add(new InventoryButton(87+21*3, 5, null, true, false, false, 0, "")); + + //Crafting square + buttons.add(new InventoryButton(87, 25, null, true, false, false, 0, "")); + buttons.add(new InventoryButton(87+18, 25, null, true, false, false, 0, "")); + buttons.add(new InventoryButton(87, 25+18, null, true, false, false, 0, "")); + buttons.add(new InventoryButton(87+18, 25+18, null, true, false, false, 0, "")); + + //Crafting result + buttons.add(new InventoryButton(143, 35, null, true, false, false, 0, "")); + + //Player menu area + buttons.add(new InventoryButton(60, 8, null, true, false, false, 0, "")); + buttons.add(new InventoryButton(60, 60, null, true, false, false, 0, "")); + buttons.add(new InventoryButton(26, 8, null, true, false, false, 0, "")); + buttons.add(new InventoryButton(26, 60, null, true, false, false, 0, "")); + + //Right side + for(int i=0; i<8; i++) { + int y = 2+20*i; + if(y < 80) { + buttons.add(new InventoryButton(2, 2+20*i, null, false, true, false, 0, "")); + } else { + buttons.add(new InventoryButton(2, 2+20*i-166, null, false, true, true, 0, "")); + } + } + + //Top side + for(int i=0; i<8; i++) { + buttons.add(new InventoryButton(4+21*i, -19, null, false, false, false, 0, "")); + } + + //Left side + for(int i=0; i<8; i++) { + int y = 2+20*i; + if(y < 80) { + buttons.add(new InventoryButton(-19, 2+20*i, null, false, false, false, 0, "")); + } else { + buttons.add(new InventoryButton(-19, 2+20*i-166, null, false, false, true, 0, "")); + } + } + + //Bottom side + for(int i=0; i<8; i++) { + buttons.add(new InventoryButton(4+21*i, 2, null, false, false, true, 0, "")); + } + return buttons; + } + + public static class InventoryButton { + @Expose public int x; + @Expose public int y; + @Expose public boolean playerInvOnly; + + @Expose public boolean anchorRight; + @Expose public boolean anchorBottom; + + @Expose public int backgroundIndex; + @Expose public String command; + @Expose public String icon; + + public boolean isActive() { + return command.trim().length() > 0; + } + + public InventoryButton(int x, int y, String icon, boolean playerInvOnly, boolean anchorRight, boolean anchorBottom, int backgroundIndex, String command) { + this.x = x; + this.y = y; + this.icon = icon; + this.playerInvOnly = playerInvOnly; + this.anchorRight = anchorRight; + this.anchorBottom = anchorBottom; + this.backgroundIndex = backgroundIndex; + this.command = command; + } + } + public static class DungeonMap { @Expose @ConfigOption( 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 da2b9bee..d4132f76 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/overlays/TimersOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/overlays/TimersOverlay.java @@ -103,6 +103,11 @@ public class TimersOverlay extends TextOverlay { @Override protected void renderLine(String line, Vector2f position, boolean dummy) { + if(!NotEnoughUpdates.INSTANCE.config.miscOverlays.todoIcons) { + return; + } + GlStateManager.enableDepth(); + ItemStack icon = null; String clean = Utils.cleanColour(line); @@ -115,7 +120,7 @@ public class TimersOverlay extends TextOverlay { if(FETCHUR_ICONS == null) { FETCHUR_ICONS = new ItemStack[] { new ItemStack(Blocks.wool, 50, 14), - new ItemStack(Blocks.glass, 20, 4), + new ItemStack(Blocks.stained_glass, 20, 4), new ItemStack(Items.compass, 1, 0), new ItemStack(Items.prismarine_crystals, 20, 0), new ItemStack(Items.fireworks, 1, 0), diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java index 4a9a9257..13ada4bf 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java @@ -840,7 +840,7 @@ public class GuiProfileViewer extends GuiScreen { Utils.renderAlignedString(EnumChatFormatting.YELLOW+"Secrets (Total) ", EnumChatFormatting.WHITE.toString()+shortNumberFormat(secrets, 0), x, miscTopY+20, sectionWidth); Utils.renderAlignedString(EnumChatFormatting.YELLOW+"Secrets (/Run) ", - EnumChatFormatting.WHITE.toString()+(Math.round(secrets/Math.max(1, totalRunsF5)*100)/100f), x, miscTopY+30, sectionWidth); + EnumChatFormatting.WHITE.toString()+(Math.round(secrets/Math.max(1, totalRuns)*100)/100f), x, miscTopY+30, sectionWidth); Utils.renderAlignedString(EnumChatFormatting.YELLOW+"Mob Kills (Total) ", EnumChatFormatting.WHITE.toString()+shortNumberFormat(mobKills, 0), x, miscTopY+40, sectionWidth); @@ -2528,7 +2528,6 @@ public class GuiProfileViewer extends GuiScreen { Arrays.fill(entityPlayer.inventory.armorInventory, null); } } - System.out.println(entityPlayer.getUniqueID().toString()); if(entityPlayer.getUniqueID().toString().equals("ae6193ab-494a-4719-b6e7-d50392c8f012")) { entityPlayer.inventory.armorInventory[3] = NotEnoughUpdates.INSTANCE.manager.jsonToStack( NotEnoughUpdates.INSTANCE.manager.getItemInformation().get("SMALL_BACKPACK")); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewer.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewer.java index c61a0914..b2b19189 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewer.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewer.java @@ -398,7 +398,7 @@ public class ProfileViewer { JsonObject bzInfo2 = manager.auctionManager.getBazaarInfo(internalname2); int auctionPrice2; - if(bzInfo2 != null && bzInfo.has("curr_sell")) { + if(bzInfo2 != null && bzInfo2.has("curr_sell")) { auctionPrice2 = (int)bzInfo2.get("curr_sell").getAsFloat(); } else { auctionPrice2 = (int)manager.auctionManager.getItemAvgBin(internalname2); |