/* * Copyright (C) 2022-2024 NotEnoughUpdates contributors * * This file is part of NotEnoughUpdates. * * NotEnoughUpdates is free software: you can redistribute it * and/or modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation, either * version 3 of the License, or (at your option) any later version. * * NotEnoughUpdates is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with NotEnoughUpdates. If not, see . */ package io.github.moulberry.notenoughupdates.overlays; import com.google.gson.annotations.Expose; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.core.config.Position; import io.github.moulberry.notenoughupdates.core.util.StringUtils; import io.github.moulberry.notenoughupdates.core.util.lerp.LerpUtils; import io.github.moulberry.notenoughupdates.guifeatures.SkyMallDisplay; import io.github.moulberry.notenoughupdates.miscfeatures.GlaciteTunnelWaypoints; import io.github.moulberry.notenoughupdates.miscfeatures.HotmDesires; import io.github.moulberry.notenoughupdates.miscfeatures.ItemCooldowns; import io.github.moulberry.notenoughupdates.miscfeatures.tablisttutorial.TablistAPI; import io.github.moulberry.notenoughupdates.options.NEUConfig; import io.github.moulberry.notenoughupdates.options.separatesections.Mining; import io.github.moulberry.notenoughupdates.util.ItemResolutionQuery; import io.github.moulberry.notenoughupdates.util.SBInfo; import io.github.moulberry.notenoughupdates.util.StarCultCalculator; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.inventory.GuiChest; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.inventory.ContainerChest; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; import net.minecraft.util.EnumChatFormatting; import org.jetbrains.annotations.Nullable; import org.lwjgl.util.vector.Vector2f; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.function.Supplier; import java.util.regex.Matcher; import java.util.regex.Pattern; import static io.github.moulberry.notenoughupdates.util.Utils.showOutdatedRepoNotification; import static net.minecraft.util.EnumChatFormatting.DARK_AQUA; import static net.minecraft.util.EnumChatFormatting.GOLD; import static net.minecraft.util.EnumChatFormatting.GREEN; import static net.minecraft.util.EnumChatFormatting.RED; import static net.minecraft.util.EnumChatFormatting.YELLOW; public class MiningOverlay extends TextTabOverlay { public MiningOverlay( Position position, Supplier> dummyStrings, Supplier styleSupplier ) { super(position, dummyStrings, styleSupplier); } private static final Pattern NUMBER_PATTERN = Pattern.compile("(?\\d*,?\\d+)(?: |$)"); public static Map commissionProgress = new LinkedHashMap<>(); @Override public void updateFrequent() { if (Minecraft.getMinecraft().currentScreen instanceof GuiChest) { GuiChest chest = (GuiChest) Minecraft.getMinecraft().currentScreen; ContainerChest container = (ContainerChest) chest.inventorySlots; IInventory lower = container.getLowerChestInventory(); String containerName = lower.getDisplayName().getUnformattedText(); if (containerName.equals("Commissions") && lower.getSizeInventory() >= 27) { updateCommissions(lower); } else if (containerName.equals("Forge") && lower.getSizeInventory() >= 36) { updateForge(lower); } } } private void updateForge(IInventory lower) { NEUConfig.HiddenProfileSpecific hidden = NotEnoughUpdates.INSTANCE.config.getProfileSpecific(); if (hidden == null) { return; } itemLoop: for (int i = 0; i < 5; i++) { ItemStack stack = lower.getStackInSlot(i + 11); if (stack != null) { String[] lore = NotEnoughUpdates.INSTANCE.manager.getLoreFromNBT(stack.getTagCompound()); for (String line : lore) { Matcher matcher = timeRemainingForge.matcher(line); if (stack.getDisplayName().matches("\\xA7cSlot #([1-5])")) { ForgeItem newForgeItem = new ForgeItem(i, 1, false); replaceForgeOrAdd(newForgeItem, hidden.forgeItems, true); //empty Slot } else if (stack.getDisplayName().matches("\\xA7aSlot #([1-5])")) { ForgeItem newForgeItem = new ForgeItem(i, 0, false); replaceForgeOrAdd(newForgeItem, hidden.forgeItems, true); } else if (matcher.matches()) { String timeremainingString = matcher.group(1); long duration = 0; if (matcher.group("Completed") != null && !matcher.group("Completed").equals("")) { ForgeItem newForgeItem = new ForgeItem(Utils.cleanColour(stack.getDisplayName()), 0, i, false); replaceForgeOrAdd(newForgeItem, hidden.forgeItems, true); } else { try { if (matcher.group("days") != null && !matcher.group("days").equals("")) { duration = duration + (long) Integer.parseInt(matcher.group("days")) * 24 * 60 * 60 * 1000; } if (matcher.group("hours") != null && !matcher.group("hours").equals("")) { duration = duration + (long) Integer.parseInt(matcher.group("hours")) * 60 * 60 * 1000; } if (matcher.group("minutes") != null && !matcher.group("minutes").equals("")) { duration = duration + (long) Integer.parseInt(matcher.group("minutes")) * 60 * 1000; } if (matcher.group("seconds") != null && !matcher.group("seconds").equals("")) { duration = duration + (long) Integer.parseInt(matcher.group("seconds")) * 1000; } } catch (Exception ignored) { } if (duration > 0) { ForgeItem newForgeItem = new ForgeItem( Utils.cleanColour(stack.getDisplayName()), System.currentTimeMillis() + duration, i, false ); replaceForgeOrAdd(newForgeItem, hidden.forgeItems, true); } } continue itemLoop; } } //Locked Slot } } } private void updateCommissions(IInventory lower) { // Get the location (type) of the currently shown commissions ItemStack commTypeStack = lower.getStackInSlot(32); if (commTypeStack == null || !commTypeStack.hasTagCompound()) { return; } String name = Utils.cleanColour(commTypeStack.getDisplayName()).trim(); if (!name.equals("Filter")) { return; } String commLocation = null; String[] lore = NotEnoughUpdates.INSTANCE.manager.getLoreFromNBT(commTypeStack.getTagCompound()); for (String line : lore) { if (line == null) { continue; } if (!line.contains("▶")) continue; String cleanLine = Utils.cleanColour(line).replace("▶", "").trim(); if (cleanLine.equals("Dwarven Mines")) { commLocation = "mining_3"; } else if (cleanLine.equals("Crystal Hollows")) { commLocation = "crystal_hollows"; } else if (cleanLine.equals("Glacite Tunnels")) { commLocation = "mineshaft"; } else { continue; } break; } if (commLocation == null) { return; } // Now get the commission info for (int i = 9; i < 18; i++) { ItemStack stack = lower.getStackInSlot(i); if (stack != null && stack.hasTagCompound()) { lore = NotEnoughUpdates.INSTANCE.manager.getLoreFromNBT(stack.getTagCompound()); String commName = null; int numberValue = -1; for (String line : lore) { if (commName != null) { String clean = Utils.cleanColour(line).trim(); if (clean.isEmpty()) { break; } else { Matcher matcher = NUMBER_PATTERN.matcher(clean); if (matcher.find()) { try { numberValue = Integer.parseInt(matcher.group("number").replace(",", "")); } catch (NumberFormatException ignored) { } } } } if (line.startsWith("\u00a79")) { String textAfter = line.substring(2); if (!textAfter.contains("\u00a7") && !textAfter.equals("Rewards") && !textAfter.equals("Progress")) { commName = textAfter; } } } NEUConfig.HiddenLocationSpecific locationSpecific = NotEnoughUpdates.INSTANCE.config.getLocationSpecific( commLocation); if (commName != null && numberValue > 0) { locationSpecific.commissionMaxes.put(commName, numberValue); } } } } private static final Pattern timeRemainingForge = Pattern.compile( "\\xA77Time Remaining: \\xA7a((?Completed!)|(((?[0-9]+)d)? ?((?[0-9]+)h)? ?((?[0-9]+)m)? ?((?[0-9]+)s)?))"); private static final Pattern timeRemainingTab = Pattern.compile( ".*[1-5]\\) (?.*): ((?Ready!)|(((?[0-9]+)d)? ?((?[0-9]+)h)? ?((?[0-9]+)m)? ?((?[0-9]+)s)?))"); private static final Pattern forgeIntPattern = Pattern.compile( "[^)]*([1-5])\\).*"); @Override public boolean isEnabled() { return NotEnoughUpdates.INSTANCE.config.mining.dwarvenOverlay; } public @Nullable NEUConfig.HiddenLocationSpecific getMiningLocationSpecific() { String location = SBInfo.getInstance().getLocation(); if (location == null || location.isEmpty()) { return null; } String sideBarLoc = SBInfo.getInstance().getScoreboardLocation(); if (location.equals("mining_3") && (GlaciteTunnelWaypoints.INSTANCE.getGlaciteTunnelLocations().contains(sideBarLoc))) { location = "mineshaft"; } return NotEnoughUpdates.INSTANCE.config.getLocationSpecific(location); } @Override public void update() { overlayStrings = null; NEUConfig.HiddenProfileSpecific profileConfig = NotEnoughUpdates.INSTANCE.config.getProfileSpecific(); if (!NotEnoughUpdates.INSTANCE.config.mining.dwarvenOverlay && NotEnoughUpdates.INSTANCE.config.mining.emissaryWaypoints == 0 && !NotEnoughUpdates.INSTANCE.config.mining.titaniumAlert && NotEnoughUpdates.INSTANCE.config.mining.locWaypoints == 0 && NotEnoughUpdates.INSTANCE.config.mining.tunnelWaypoints.get() != Mining.GlaciteTunnelWaypointBehaviour.NONE && HotmDesires.wantsPowderInfo()) { return; } // Get commission and forge info even if the overlay isn't going to be rendered since it is used elsewhere //thanks to "Pure Genie#7250" for helping with this (makes tita alert and waypoints work without mine overlay) if (SBInfo.getInstance().getLocation() == null) return; if (SBInfo.getInstance().getLocation().equals("mining_3") || SBInfo.getInstance().getLocation().equals("crystal_hollows") || SBInfo.getInstance().getLocation().equals("mineshaft")) { commissionProgress.clear(); // These strings will be displayed one after the other when the player list is disabled String mithrilPowder = ""; String gemstonePowder = ""; String glacitePowder = ""; List powderLines = getTabLinesOrAddWarning(1, TablistAPI.WidgetNames.POWDER); getTabLinesOrAddWarning(2, TablistAPI.WidgetNames.POWDER); getTabLinesOrAddWarning(6, TablistAPI.WidgetNames.POWDER); for (String line : powderLines) { if (line.contains("Mithril:")) { mithrilPowder = DARK_AQUA + Utils.trimWhitespaceAndFormatCodes(line).replaceAll("\u00a7[f|F|r]", "") + HotmDesires.appendDesireForType("Mithril"); } if (line.contains("Gemstone:")) { gemstonePowder = DARK_AQUA + Utils.trimWhitespaceAndFormatCodes(line).replaceAll("\u00a7[f|F|r]", "") + HotmDesires.appendDesireForType("Gemstone"); } if (line.contains("Glacite: ")) { glacitePowder = DARK_AQUA + Utils.trimWhitespaceAndFormatCodes(line).replaceAll("\u00a7[f|F|r]", "") + HotmDesires.appendDesireForType("Glacite"); } } List tabForgeLines = getTabLinesOrAddWarning(3, TablistAPI.WidgetNames.FORGE); Set foundForges = new HashSet<>(); for (String name : tabForgeLines) { String cleanName = StringUtils.cleanColour(name); if (cleanName.startsWith(" ") && profileConfig != null) { char firstChar = cleanName.trim().charAt(0); if (firstChar < '0' || firstChar > '9') { break; } else { int forgeInt; Matcher forgeIntMatcher = forgeIntPattern.matcher(cleanName); if (forgeIntMatcher.matches()) { forgeInt = Integer.parseInt(forgeIntMatcher.group(1)) - 1; foundForges.add(forgeInt); } else { continue; } if (name.contains("LOCKED")) { ForgeItem item = new ForgeItem(forgeInt, 1, true); replaceForgeOrAdd(item, profileConfig.forgeItems, true); } else if (name.contains("EMPTY")) { ForgeItem item = new ForgeItem(forgeInt, 0, true); replaceForgeOrAdd(item, profileConfig.forgeItems, true); } else { Matcher matcher = timeRemainingTab.matcher(cleanName); if (matcher.matches()) { String itemName = matcher.group(1); if (matcher.group("Ready") != null && !matcher.group("Ready").equals("")) { ForgeItem item = new ForgeItem(Utils.cleanColour(itemName), 0, forgeInt, true); replaceForgeOrAdd(item, profileConfig.forgeItems, true); } else { long duration = 0; try { if (matcher.group("days") != null && !matcher.group("days").equals("")) { duration = duration + (long) Integer.parseInt(matcher.group("days")) * 24 * 60 * 60 * 1000; } if (matcher.group("hours") != null && !matcher.group("hours").equals("")) { duration = duration + (long) Integer.parseInt(matcher.group("hours")) * 60 * 60 * 1000; } if (matcher.group("minutes") != null && !matcher.group("minutes").equals("")) { duration = duration + (long) Integer.parseInt(matcher.group("minutes")) * 60 * 1000; } if (matcher.group("seconds") != null && !matcher.group("seconds").equals("")) { duration = duration + (long) Integer.parseInt(matcher.group("seconds")) * 1000; } } catch (Exception ignored) { } if (duration > 0) { duration = duration + 4000; ForgeItem item = new ForgeItem( Utils.cleanColour(itemName), System.currentTimeMillis() + duration, forgeInt, true ); replaceForgeOrAdd(item, profileConfig.forgeItems, false); } } } } } } } if (profileConfig != null) for (int i = 0; i < 5; i++) { if (foundForges.contains(i)) continue; ForgeItem item = new ForgeItem(i, 0, true); replaceForgeOrAdd(item, profileConfig.forgeItems, true); } List tabCommissionLines = getTabLinesOrAddWarning(0, TablistAPI.WidgetNames.COMMISSIONS); for (String name : tabCommissionLines) { String cleanName = StringUtils.cleanColour(name); if (cleanName.startsWith(" ") && profileConfig != null) { String[] split = cleanName.trim().split(": "); if (split.length == 2) { if (split[1].endsWith("%")) { try { float progress = Float.parseFloat(split[1].replace("%", "")) / 100; progress = LerpUtils.clampZeroOne(progress); commissionProgress.put(split[0], progress); } catch (Exception ignored) { } } else if (split[1].endsWith("DONE")) { commissionProgress.put(split[0], 1.0f); } } } } if (ItemCooldowns.firstLoadMillis > 0) { //set cooldown on first skyblock load. ItemCooldowns.pickaxeUseCooldownMillisRemaining = 60 * 1000 - (System.currentTimeMillis() - ItemCooldowns.firstLoadMillis); ItemCooldowns.firstLoadMillis = 0; } if (!NotEnoughUpdates.INSTANCE.config.mining.dwarvenOverlay) { overlayStrings = null; return; } List commissionsStrings = new ArrayList<>(); for (Map.Entry entry : commissionProgress.entrySet()) { if (entry.getValue() >= 1) { commissionsStrings.add(DARK_AQUA + entry.getKey() + ": " + GREEN + "DONE"); } else { EnumChatFormatting col = RED; if (entry.getValue() >= 0.75) { col = GREEN; } else if (entry.getValue() >= 0.5) { col = YELLOW; } else if (entry.getValue() >= 0.25) { col = GOLD; } String tips = getTipPart(entry.getKey()); boolean newLine = NotEnoughUpdates.INSTANCE.config.mining.commissionTaskTipNewLine; String newLineTip = null; if (newLine) { if (!tips.isEmpty()) { newLineTip = " " + tips; tips = ""; } } NEUConfig.HiddenLocationSpecific locationSpecific = getMiningLocationSpecific(); int max; if (-1 != (max = locationSpecific.commissionMaxes.getOrDefault(entry.getKey(), -1))) { commissionsStrings.add( DARK_AQUA + entry.getKey() + ": " + col + Math.round(entry.getValue() * max) + "/" + max + tips); } else { String valS = Utils.floatToString(entry.getValue() * 100, 1); commissionsStrings.add(DARK_AQUA + entry.getKey() + ": " + col + valS + "%" + tips); } if (newLineTip != null) { commissionsStrings.add(newLineTip); } } } String pickaxeCooldown; if (ItemCooldowns.pickaxeUseCooldownMillisRemaining <= 0) { pickaxeCooldown = DARK_AQUA + "Pickaxe CD: \u00a7aReady"; } else { pickaxeCooldown = DARK_AQUA + "Pickaxe CD: \u00a7a" + (ItemCooldowns.pickaxeUseCooldownMillisRemaining / 1000) + "s"; } overlayStrings = new ArrayList<>(); for (int index : NotEnoughUpdates.INSTANCE.config.mining.dwarvenText2) { switch (index) { case 0: overlayStrings.addAll(commissionsStrings); break; case 1: if (!mithrilPowder.isEmpty()) overlayStrings.add(mithrilPowder); break; case 2: if (!gemstonePowder.isEmpty()) overlayStrings.add(gemstonePowder); break; case 3: if (profileConfig != null) { overlayStrings.addAll(getForgeStrings(profileConfig.forgeItems)); } break; case 4: overlayStrings.add(pickaxeCooldown); break; case 5: overlayStrings.add( DARK_AQUA + "Star Cult: " + GREEN + StarCultCalculator.getNextStarCult()); break; case 6: overlayStrings.add("§3Sky Mall: §a" + SkyMallDisplay.Companion.getDisplayText()); break; case 7: if (!glacitePowder.isEmpty()) overlayStrings.add(glacitePowder); break; } } } else { if (profileConfig == null) { return; } boolean forgeDisplay = false; boolean starCultDisplay = false; boolean skyMallDisplay = false; for (int i = 0; i < NotEnoughUpdates.INSTANCE.config.mining.dwarvenText2.size(); i++) { if (NotEnoughUpdates.INSTANCE.config.mining.dwarvenText2.get(i) == 3) { forgeDisplay = true; } if (NotEnoughUpdates.INSTANCE.config.mining.dwarvenText2.get(i) == 5) { starCultDisplay = true; } if (NotEnoughUpdates.INSTANCE.config.mining.dwarvenText2.get(i) == 6) { skyMallDisplay = true; } } if (starCultDisplay) { if (overlayStrings == null) overlayStrings = new ArrayList<>(); if (!NotEnoughUpdates.INSTANCE.config.mining.starCultDisplayOnlyShowTab || lastTabState) { if (NotEnoughUpdates.INSTANCE.config.mining.starCultDisplayEnabledLocations == 1 && !SBInfo.getInstance().isInDungeon) { overlayStrings.add( DARK_AQUA + "Star Cult: " + GREEN + StarCultCalculator.getNextStarCult()); } else if (NotEnoughUpdates.INSTANCE.config.mining.starCultDisplayEnabledLocations == 2) { overlayStrings.add( DARK_AQUA + "Star Cult: " + GREEN + StarCultCalculator.getNextStarCult()); } } } if (forgeDisplay) { if (overlayStrings == null) overlayStrings = new ArrayList<>(); if (!NotEnoughUpdates.INSTANCE.config.mining.forgeDisplayOnlyShowTab || lastTabState) { if (NotEnoughUpdates.INSTANCE.config.mining.forgeDisplayEnabledLocations == 1 && !SBInfo.getInstance().isInDungeon) { overlayStrings.addAll(getForgeStrings(profileConfig.forgeItems)); } else if (NotEnoughUpdates.INSTANCE.config.mining.forgeDisplayEnabledLocations == 2) { overlayStrings.addAll(getForgeStrings(profileConfig.forgeItems)); } } } if (skyMallDisplay) { if (overlayStrings == null) overlayStrings = new ArrayList<>(); if (!NotEnoughUpdates.INSTANCE.config.mining.skyMallDisplayOnlyShowTab || lastTabState) { if (NotEnoughUpdates.INSTANCE.config.mining.skyMallDisplayEnabledLocations == 1 && !SBInfo.getInstance().isInDungeon) { overlayStrings.add( DARK_AQUA + "Sky Mall: " + GREEN + SkyMallDisplay.Companion.getDisplayText()); } else if (NotEnoughUpdates.INSTANCE.config.mining.skyMallDisplayEnabledLocations == 2) { overlayStrings.add( DARK_AQUA + "Sky Mall: " + GREEN + SkyMallDisplay.Companion.getDisplayText()); } } } } if (overlayStrings != null && overlayStrings.isEmpty()) overlayStrings = null; } private List getTabLinesOrAddWarning(int configIndex, TablistAPI.WidgetNames widgetName) { List lines; if (NotEnoughUpdates.INSTANCE.config.mining.dwarvenText2.contains(configIndex) && NotEnoughUpdates.INSTANCE.config.mining.dwarvenOverlay) { lines = TablistAPI.getWidgetLinesWithoutNotification(widgetName); if (lines.isEmpty() && (overlayStrings == null || !overlayStrings.contains("§l§4One or more tab widgets missing!"))) { if (overlayStrings == null) overlayStrings = new ArrayList<>(); overlayStrings.add("§l§4One or more tab widgets missing!"); overlayStrings.add("§l§4Enable it in §b/tab§4!"); } } else { lines = TablistAPI.getOptionalWidgetLines(widgetName); } return lines; } private String getTipPart(String name) { int settings = NotEnoughUpdates.INSTANCE.config.mining.commissionTaskTips; if (settings == 0) return ""; if (!Minecraft.getMinecraft().thePlayer.isSneaking() && settings == 1) return ""; String tip = getTip(name); if (tip == null) return " §4???"; return " §8§l>§7 " + tip; } private String getTip(String name) { if (SBInfo.getInstance().getLocation().equals("mining_3")) { // Dwarven Mines if (name.equals("First Event")) return "Participate in any §6Mining Event"; // During Event if (name.equals("Lucky Raffle")) return "Collect 20 Raffle Tickets during §6Raffle Event"; if (name.equals("Goblin Raid Slayer")) return "Kill 20 Goblins during §6Goblin Raid Event"; if (name.equals("Raffle")) return "Participate in §6Raffle Event"; if (name.equals("Goblin Raid")) return "Participate in §6Goblin Raid event"; if (name.equals("2x Mithril Powder Collector")) return "Collect 500 Mithril Powder during §62x Powder event"; // Slay if (name.equals("Glacite Walker Slayer")) return "Kill 50 Glacite Walkers §b(Great Ice Wall)"; if (name.equals("Goblin Slayer")) return "Kill 100 Goblins §b(Goblin Burrows)"; if (name.equals("Golden Goblin Slayer")) return "Kill 1 Golden Goblin (anywhere)"; if (name.equals("Star Sentry Puncher")) return "Damage Star Sentries 10 times (anywhere)"; if (name.equals("Treasure Hoarder Puncher")) return "Damage Treasure Hoarders 10 times §b(Upper Mines)"; if (name.equals("Mines Slayer")) return "Kill 50 mobs (anywhere)"; // Mining if (name.equals("Mithril Miner")) return "Break 350 Mithril (anywhere)"; if (name.equals("Titanium Miner")) return "Break 15 Titanium (anywhere)"; if (name.equals("Cliffside Veins Mithril")) return "Break 250 Mithril §b(Cliffside Veins)"; if (name.equals("Royal Mines Mithril")) return "Break 250 Mithril §b(Royal Mines)"; if (name.equals("Lava Springs Mithril")) return "Break 250 Mithril §b(Lava Springs)"; if (name.equals("Rampart's Quarry Mithril")) return "Break 250 Mithril §b(Rampart's Quarry)"; if (name.equals("Upper Mines Mithril")) return "Break 250 Mithril §b(Upper Mines)"; if (name.equals("Cliffside Veins Titanium")) return "Break 10 Titanium §b(Cliffside Veins)"; if (name.equals("Lava Springs Titanium")) return "Break 10 Titanium §b(Lava Springs)"; if (name.equals("Royal Mines Titanium")) return "Break 10 Titanium §b(Royal Mines)"; if (name.equals("Rampart's Quarry Titanium")) return "Break 10 Titanium §b(Rampart's Quarry)"; if (name.equals("Upper Mines Titanium")) return "Break 10 Titanium §b(Upper Mines)"; // Glacite Tunnels if (name.equals("Corpse Looter")) return "Find Corpses in a Glacite Mineshaft"; if (name.equals("Mineshaft Explorer")) return "Discover a Glacite Mineshaft"; if (name.equals("Scrap Collector")) return "Break non-vanilla Ores and not Hard Stone in a Glacite Mineshaft"; if (name.equals("Umber Collector")) return "Break red sand/hardened clay"; if (name.equals("Tungsten Collector")) return "Break cobblestone/clay"; if (name.equals("Glacite Collector")) return "Break ice"; if (name.equals("Onyx Gemstone Collector")) return "Break black glass"; if (name.equals("Aquamarine Gemstone Collector")) return "Break aqua glass"; if (name.equals("Peridot Gemstone Collector")) return "Break dark green glass"; if (name.equals("Citrine Gemstone Collector")) return "Break brown glass"; if (name.equals("Maniac Slayer")) return "Kill mobs in a Glacite Mineshaft"; } else if (SBInfo.getInstance().getLocation().equals("crystal_hollows")) { // Crystal Hollows if (name.equals("Chest Looter")) return "Open 3 chests"; if (name.equals("Hard Stone Miner")) return "Break 1,000 Hard Stone"; String jungle = " §a(Jungle)"; String goblin = " §6(Goblin Holdout)"; String mithril = " §b(Mithril Deposits)"; String precursor = " §8(Precursor Remenants)"; String magma = " §c(Magma Fields)"; if (name.equals("Goblin Slayer")) return "Kill 13 Goblins" + goblin; if (name.equals("Sludge Slayer")) return "Kill 25 Sludges" + jungle; if (name.equals("Thyst Slayer")) return "Kill 5 Thysts, when breaking Amethysts" + jungle; if (name.equals("Boss Corleone Slayer")) return "Find and kill Corleone" + mithril; if (name.equals("Yog Slayer")) return "Kill 13 Yogs" + magma; if (name.equals("Automaton Slayer")) return "Kill 13 Automatons" + precursor; if (name.equals("Team Treasurite Member Slayer")) return "Kill 13 Team Treasurite Members" + mithril; if (name.endsWith("Crystal Hunter")) { if (name.startsWith("Amethyst")) return "Temple Jump & Run" + jungle; if (name.startsWith("Jade")) return "4 weapons from Mines of Divan" + mithril; if (name.startsWith("Amber")) return "King and Queen" + goblin; if (name.startsWith("Sapphire")) return "6 Robot Parts in Precursor City" + precursor; if (name.startsWith("Topaz")) return "Kill Bal" + magma; } if (name.endsWith("Gemstone Collector")) { if (name.startsWith("Amber")) return "Break orange glass" + goblin; if (name.startsWith("Sapphire")) return "Break blue glass" + precursor; if (name.startsWith("Jade")) return "Break green glass" + mithril; if (name.startsWith("Amethyst")) return "Break purple glass" + jungle; if (name.startsWith("Ruby")) return "Break red glass (anywhere)"; if (name.startsWith("Topaz")) return "Break yellow glass" + magma; } } else if (SBInfo.getInstance().getLocation().equals("mineshaft")) { if (name.equals("Corpse Looter")) return "Find Corpses and click them"; if (name.equals("Mineshaft Explorer")) return "Discover a Glacite Mineshaft"; if (name.equals("Scrap Collector")) return "Break non-vanilla Ores and not Hard Stone"; if (name.equals("Umber Collector")) return "Break red sand/hardened clay"; if (name.equals("Tungsten Collector")) return "Break cobblestone/clay"; if (name.equals("Glacite Collector")) return "Break ice"; if (name.equals("Onyx Gemstone Collector")) return "Break black glass"; if (name.equals("Aquamarine Gemstone Collector")) return "Break aqua glass"; if (name.equals("Peridot Gemstone Collector")) return "Break dark green glass"; if (name.equals("Citrine Gemstone Collector")) return "Break brown glass"; } return null; } private static List getForgeStrings(List forgeItems) { List forgeString = new ArrayList<>(); long currentTimeMillis = System.currentTimeMillis(); forgeIDLabel: for (int i = 0; i < 5; i++) { for (ForgeItem item : forgeItems) { if (item.forgeID == i) { if (NotEnoughUpdates.INSTANCE.config.mining.forgeDisplay == 0) { if (item.status == 2 && item.finishTime < currentTimeMillis) { forgeString.add(item.getFormattedString(currentTimeMillis)); continue forgeIDLabel; } } else if (NotEnoughUpdates.INSTANCE.config.mining.forgeDisplay == 1) { if (item.status == 2) { forgeString.add(item.getFormattedString(currentTimeMillis)); continue forgeIDLabel; } } else if (NotEnoughUpdates.INSTANCE.config.mining.forgeDisplay == 2) { if (item.status == 2 || item.status == 0) { forgeString.add(item.getFormattedString(currentTimeMillis)); continue forgeIDLabel; } } else if (NotEnoughUpdates.INSTANCE.config.mining.forgeDisplay == 3) { forgeString.add(item.getFormattedString(currentTimeMillis)); continue forgeIDLabel; } } } } return forgeString; } private static void replaceForgeOrAdd(ForgeItem item, List forgeItems, boolean overwrite) { for (int i = 0; i < forgeItems.size(); i++) { if (forgeItems.get(i).forgeID == item.forgeID) { if (overwrite) { forgeItems.set(i, item); return; } else { ForgeItem currentItem = forgeItems.get(i); if (!(currentItem.status == 2 && item.status == 2)) { forgeItems.set(i, item); return; } else if (currentItem.fromScoreBoard) { forgeItems.set(i, item); return; } } return; } } forgeItems.add(item); } public static class ForgeItem { public ForgeItem(String itemName, long finishTime, int forgeID, boolean fromScoreBoard) { this.itemName = itemName; this.finishTime = finishTime; this.status = 2; this.forgeID = forgeID; this.fromScoreBoard = fromScoreBoard; } public ForgeItem(int forgeID, int status, boolean fromScoreBoard) { this.forgeID = forgeID; this.status = status; this.fromScoreBoard = fromScoreBoard; } @Expose public String itemName; @Expose public long finishTime; @Expose public final int status; @Expose public final int forgeID; @Expose public final boolean fromScoreBoard; public String getFormattedString(long currentTimeMillis) { String returnText = EnumChatFormatting.DARK_AQUA + "Forge " + (this.forgeID + 1) + ": "; if (status == 0) { return returnText + EnumChatFormatting.GRAY + "Empty"; } else if (status == 1) { return returnText + EnumChatFormatting.DARK_RED + "Locked"; } long timeDuration = finishTime - currentTimeMillis; returnText = returnText + EnumChatFormatting.DARK_PURPLE + this.itemName + ": "; int days = (int) (timeDuration / (1000 * 60 * 60 * 24)); timeDuration = timeDuration - (days * (1000 * 60 * 60 * 24)); int hours = (int) ((timeDuration / (1000 * 60 * 60)) % 24); if (days > 0) { return returnText + EnumChatFormatting.AQUA + days + "d " + hours + "h"; } timeDuration = timeDuration - (hours * (1000 * 60 * 60)); int minutes = (int) ((timeDuration / (1000 * 60)) % 60); if (hours > 0) { return returnText + EnumChatFormatting.AQUA + hours + "h " + minutes + "m"; } timeDuration = timeDuration - (minutes * (1000 * 60)); int seconds = (int) (timeDuration / 1000) % 60; if (minutes > 0) { return returnText + EnumChatFormatting.AQUA + minutes + "m " + seconds + "s"; } else if (seconds > 0) { return returnText + EnumChatFormatting.AQUA + seconds + "s"; } else { return returnText + EnumChatFormatting.DARK_GREEN + "Done"; } } } @Override protected Vector2f getSize(List strings) { if (NotEnoughUpdates.INSTANCE.config.mining.dwarvenOverlayIcons) return super.getSize(strings).translate(12, 0); return super.getSize(strings); } @Override protected void renderLine(String line, Vector2f position, boolean dummy) { if (!NotEnoughUpdates.INSTANCE.config.mining.dwarvenOverlayIcons) return; GlStateManager.enableDepth(); // No icon for the tip line if (line.contains(">")) return; ItemStack icon = null; String cleaned = Utils.cleanColour(line); String beforeColon = cleaned.split(":")[0]; if (miningOverlayCommissionItems == null) { setupMiningOverlayCommissionItems(); } if (miningOverlayCommissionItems.containsKey(beforeColon)) { icon = miningOverlayCommissionItems.get(beforeColon); } else { if (beforeColon.startsWith("Forge")) { icon = miningOverlayCommissionItems.get("Forge"); } else if (beforeColon.contains("Mithril")) { icon = miningOverlayCommissionItems.get("Mithril"); } else if (beforeColon.endsWith(" Gemstone Collector")) { String gemName = "ROUGH_" + beforeColon.replace(" Gemstone Collector", "").toUpperCase(Locale.ROOT) + "_GEM"; if (miningOverlayRoughGems.containsKey(gemName)) { icon = miningOverlayRoughGems.get(gemName); } else { icon = NotEnoughUpdates.INSTANCE.manager.jsonToStack(NotEnoughUpdates.INSTANCE.manager .getItemInformation() .get(gemName)); miningOverlayRoughGems.put(gemName, icon); } } else if (beforeColon.endsWith(" Crystal Hunter")) { String gemName = "PERFECT_" + beforeColon.replace(" Crystal Hunter", "").toUpperCase(Locale.ROOT) + "_GEM"; if (miningOverlayPerfectGems.containsKey(gemName)) { icon = miningOverlayPerfectGems.get(gemName); } else { icon = NotEnoughUpdates.INSTANCE.manager.jsonToStack(NotEnoughUpdates.INSTANCE.manager .getItemInformation() .get(gemName)); miningOverlayPerfectGems.put(gemName, icon); } } else if (beforeColon.contains("Titanium")) { icon = miningOverlayCommissionItems.get("Titanium"); } else if (beforeColon.contains("Sky Mall")) { icon = SkyMallDisplay.Companion.getDisplayItem(); } } if (icon != null) { GlStateManager.pushMatrix(); GlStateManager.translate(position.x, position.y, 0); GlStateManager.scale(0.5f, 0.5f, 1f); Utils.drawItemStack(icon, 0, 0); GlStateManager.popMatrix(); position.x += 12; } super.renderLine(line, position, dummy); } private static final HashMap miningOverlayRoughGems = new HashMap() {}; private static final HashMap miningOverlayPerfectGems = new HashMap() {}; private static HashMap miningOverlayCommissionItems; private static void setupMiningOverlayCommissionItems() { miningOverlayCommissionItems = new HashMap() { { addItem("Mithril Powder", "INK_SACK-10"); addItem("Gemstone Powder", "INK_SACK-9"); addItem("Lucky Raffle", "MINING_RAFFLE_TICKET"); addItem("Raffle", "MINING_RAFFLE_TICKET"); addItem("Pickaxe CD", "DIAMOND_PICKAXE"); addItem("Star Cult", "FALLEN_STAR_HAT"); addItem("Thyst Slayer", "THYST_MONSTER"); addItem("Hard Stone Miner", "HARD_STONE"); addItem("Glacite Walker Slayer", "ENCHANTED_ICE"); addItem("Goblin Slayer", "GOBLIN_MONSTER"); addItem("Star Sentry Puncher", "NETHER_STAR"); addItem("Treasure Hoarder Puncher", "TREASURE_HOARDER_MONSTER"); addItem("Mines Slayer", "IRON_SWORD"); addItem("Goblin Raid", "ENCHANTED_GOLD"); addItem("Goblin Raid Slayer", "ENCHANTED_GOLD"); addItem("Golden Goblin Slayer", "GOLD_HELMET"); addItem("2x Mithril Powder Collector", "ENCHANTED_GLOWSTONE_DUST"); addItem("Automaton Slayer", "AUTOMATON_MONSTER"); addItem("Sludge Slayer", "SLUDGE_MONSTER"); addItem("Team Treasurite Member Slayer", "EXECUTIVE_WENDY_MONSTER"); addItem("Yog Slayer", "YOG_MONSTER"); addItem("Boss Corleone Slayer", "BOSS_CORLEONE_BOSS"); addItem("Chest Looter", "CHEST"); addItem("Titanium", "TITANIUM_ORE"); addItem("Mithril", "MITHRIL_ORE"); addItem("Gemstone", "ROCK_GEMSTONE"); addItem("Glacite", "GLACITE"); addItem("Forge", "ANVIL"); addItem("First Event", "FIREWORK"); addItem("Corpse Looter", "MINERAL_HELMET"); addItem("Mineshaft Explorer", "STORAGE_MINECART"); addItem("Scrap Collector", "SUSPICIOUS_SCRAP"); addItem("Umber Collector", "UMBER"); addItem("Tungsten Collector", "TUNGSTEN"); addItem("Glacite Collector", "GLACITE"); addItem("Maniac Slayer", "GLACITE_MUTT_MONSTER"); } private void addItem(String eventName, String internalName) { ItemStack itemStack = new ItemResolutionQuery(NotEnoughUpdates.INSTANCE.manager) .withKnownInternalName(internalName).resolveToItemStack(); if (itemStack == null) { showOutdatedRepoNotification(internalName); return; } put(eventName, itemStack.copy()); } }; } }