From 58509dd21c282d4e0cf2b0efb6095fcef93b21a1 Mon Sep 17 00:00:00 2001 From: Cobble8 <41165207+Cobble8@users.noreply.github.com> Date: Wed, 19 Oct 2022 20:45:51 -0400 Subject: Made it so the user could customize how long the mod waits before pau… (#359) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../options/seperateSections/SkillOverlays.java | 52 ++ .../overlays/CombatSkillOverlay.java | 2 +- .../notenoughupdates/overlays/FarmingOverlay.java | 544 --------------------- .../overlays/FarmingSkillOverlay.java | 544 +++++++++++++++++++++ .../overlays/FishingSkillOverlay.java | 2 +- .../overlays/MiningSkillOverlay.java | 2 +- .../notenoughupdates/overlays/OverlayManager.java | 4 +- 7 files changed, 601 insertions(+), 549 deletions(-) delete mode 100644 src/main/java/io/github/moulberry/notenoughupdates/overlays/FarmingOverlay.java create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/overlays/FarmingSkillOverlay.java (limited to 'src/main/java/io') diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/SkillOverlays.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/SkillOverlays.java index 943417e6..ca970a84 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/SkillOverlays.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/SkillOverlays.java @@ -98,6 +98,19 @@ public class SkillOverlays { @ConfigAccordionId(id = 0) public boolean useBZPrice = true; + @Expose + @ConfigOption( + name = "Pause Timer", + desc = "How many seconds does it wait before pausing" + ) + @ConfigAccordionId(id = 0) + @ConfigEditorSlider( + minValue = 1, + maxValue = 20, + minStep = 1 + ) + public int farmingPauseTimer = 3; + @Expose @ConfigOption( name = "Edit Farming Overlay Position", @@ -157,6 +170,19 @@ public class SkillOverlays { @ConfigAccordionId(id = 1) public List miningText = new ArrayList<>(Arrays.asList(0, 8, 1, 2, 3, 4, 5, 7)); + @Expose + @ConfigOption( + name = "Pause Timer", + desc = "How many seconds does it wait before pausing" + ) + @ConfigAccordionId(id = 1) + @ConfigEditorSlider( + minValue = 1, + maxValue = 20, + minStep = 1 + ) + public int miningPauseTimer = 3; + @Expose @ConfigOption( name = "Edit Mining Overlay Position", @@ -218,6 +244,19 @@ public class SkillOverlays { @ConfigAccordionId(id = 3) public List fishingText = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5, 6)); + @Expose + @ConfigOption( + name = "Pause Timer", + desc = "How many seconds does it wait before pausing" + ) + @ConfigAccordionId(id = 3) + @ConfigEditorSlider( + minValue = 1, + maxValue = 20, + minStep = 1 + ) + public int fishingPauseTimer = 3; + @Expose @ConfigOption( name = "Edit Fishing Overlay Position", @@ -312,6 +351,19 @@ public class SkillOverlays { @ConfigAccordionId(id = 4) public List combatText = new ArrayList<>(Arrays.asList(0, 6, 1, 2, 3, 4, 5)); + @Expose + @ConfigOption( + name = "Pause Timer", + desc = "How many seconds does it wait before pausing" + ) + @ConfigAccordionId(id = 4) + @ConfigEditorSlider( + minValue = 1, + maxValue = 20, + minStep = 1 + ) + public int combatPauseTimer = 3; + @Expose @ConfigOption( name = "Edit Combat Overlay Position", diff --git a/src/main/java/io/github/moulberry/notenoughupdates/overlays/CombatSkillOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/overlays/CombatSkillOverlay.java index d73b5eb2..45ce0098 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/overlays/CombatSkillOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/overlays/CombatSkillOverlay.java @@ -179,7 +179,7 @@ public class CombatSkillOverlay float delta = totalXp - lastTotalXp; if (delta > 0 && delta < 1000) { - xpGainTimer = 3; + xpGainTimer = NotEnoughUpdates.INSTANCE.config.skillOverlays.combatPauseTimer; xpGainQueue.add(0, delta); while (xpGainQueue.size() > 30) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/overlays/FarmingOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/overlays/FarmingOverlay.java deleted file mode 100644 index 970c74ab..00000000 --- a/src/main/java/io/github/moulberry/notenoughupdates/overlays/FarmingOverlay.java +++ /dev/null @@ -1,544 +0,0 @@ -/* - * Copyright (C) 2022 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.JsonObject; -import io.github.moulberry.notenoughupdates.NotEnoughUpdates; -import io.github.moulberry.notenoughupdates.core.config.Position; -import io.github.moulberry.notenoughupdates.core.util.lerp.LerpUtils; -import io.github.moulberry.notenoughupdates.util.Utils; -import io.github.moulberry.notenoughupdates.util.XPInformation; -import net.minecraft.client.Minecraft; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.EnumChatFormatting; - -import java.text.NumberFormat; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.function.Supplier; - -public class FarmingOverlay extends TextOverlay { - private long lastUpdate = -1; - private int counterLast = -1; - private int counter = -1; - private int cultivatingLast = -1; - private int cultivating = -1; - private int cultivatingTier = -1; - private String cultivatingTierAmount = "1"; - private int Farming = -1; - private int Alch = -1; - private int Foraging = -1; - private double Coins = -1; - private float cropsPerSecondLast = 0; - private float cropsPerSecond = 0; - private final LinkedList counterQueue = new LinkedList<>(); - - private XPInformation.SkillInfo skillInfo = null; - private XPInformation.SkillInfo skillInfoLast = null; - - private float lastTotalXp = -1; - private boolean isFarming = false; - private final LinkedList xpGainQueue = new LinkedList<>(); - private float xpGainHourLast = -1; - private float xpGainHour = -1; - - private int xpGainTimer = 0; - - private String skillType = "Farming"; - - public FarmingOverlay( - Position position, - Supplier> dummyStrings, - Supplier styleSupplier - ) { - super(position, dummyStrings, styleSupplier); - } - - private float interp(float now, float last) { - float interp = now; - if (last >= 0 && last != now) { - float factor = (System.currentTimeMillis() - lastUpdate) / 1000f; - factor = LerpUtils.clampZeroOne(factor); - interp = last + (now - last) * factor; - } - return interp; - } - - @Override - public void update() { - if (!NotEnoughUpdates.INSTANCE.config.skillOverlays.farmingOverlay) { - counter = -1; - overlayStrings = null; - return; - } - - lastUpdate = System.currentTimeMillis(); - counterLast = counter; - cultivatingLast = cultivating; - xpGainHourLast = xpGainHour; - counter = -1; - - if (Minecraft.getMinecraft().thePlayer == null) return; - - ItemStack stack = Minecraft.getMinecraft().thePlayer.getHeldItem(); - if (stack != null && stack.hasTagCompound()) { - NBTTagCompound tag = stack.getTagCompound(); - - if (tag.hasKey("ExtraAttributes", 10)) { - NBTTagCompound ea = tag.getCompoundTag("ExtraAttributes"); - - if (ea.hasKey("mined_crops", 99)) { - counter = ea.getInteger("mined_crops"); - cultivating = ea.getInteger("farmed_cultivating"); - counterQueue.add(0, counter); - } else if (ea.hasKey("farmed_cultivating", 99)) { - counter = ea.getInteger("farmed_cultivating"); - cultivating = ea.getInteger("farmed_cultivating"); - counterQueue.add(0, counter); - } - } - } - - if (cultivating < 1000) { - cultivatingTier = 1; - } else if (cultivating < 5000) { - cultivatingTier = 2; - } else if (cultivating < 25000) { - cultivatingTier = 3; - } else if (cultivating < 100000) { - cultivatingTier = 4; - } else if (cultivating < 300000) { - cultivatingTier = 5; - } else if (cultivating < 1500000) { - cultivatingTier = 6; - } else if (cultivating < 5000000) { - cultivatingTier = 7; - } else if (cultivating < 20000000) { - cultivatingTier = 8; - } else if (cultivating < 100000000) { - cultivatingTier = 9; - } else if (cultivating > 100000000) { - cultivatingTier = 10; - } - - switch (cultivatingTier) { - case 1: - cultivatingTierAmount = "1,000"; - break; - case 2: - cultivatingTierAmount = "5,000"; - break; - case 3: - cultivatingTierAmount = "25,000"; - break; - case 4: - cultivatingTierAmount = "100,000"; - break; - case 5: - cultivatingTierAmount = "300,000"; - break; - case 6: - cultivatingTierAmount = "1,500,000"; - break; - case 7: - cultivatingTierAmount = "5,000,000"; - break; - case 8: - cultivatingTierAmount = "20,000,000"; - break; - case 9: - cultivatingTierAmount = "100,000,000"; - break; - case 10: - cultivatingTierAmount = "Maxed"; - break; - } - - String internalname = NotEnoughUpdates.INSTANCE.manager.getInternalNameForItem(stack); - if (internalname != null && internalname.startsWith("THEORETICAL_HOE_WARTS")) { - skillType = "Alchemy"; - Farming = 0; - Alch = 1; - Foraging = 0; - } else if (internalname != null && internalname.startsWith("TREECAPITATOR_AXE") || - (internalname != null && internalname.startsWith("JUNGLE_AXE"))) { - skillType = "Foraging"; - Farming = 0; - Alch = 0; - Foraging = 1; - } else { - skillType = "Farming"; - Farming = 1; - Alch = 0; - Foraging = 0; - } - - if (!NotEnoughUpdates.INSTANCE.config.skillOverlays.useBZPrice || internalname != null && (internalname.equals( - "TREECAPITATOR_AXE")) || internalname != null && (internalname.equals("JUNGLE_AXE"))) { - if ((internalname != null && internalname.equals("COCO_CHOPPER"))) { - Coins = 3; - } else if (internalname != null && internalname.startsWith("THEORETICAL_HOE_POTATO") || - (internalname != null && internalname.startsWith("THEORETICAL_HOE_CARROT")) || - (internalname != null && internalname.equals("CACTUS_KNIFE")) || - (internalname != null && internalname.startsWith("THEORETICAL_HOE_WHEAT"))) { - Coins = 1; - } else if (internalname != null && internalname.startsWith("THEORETICAL_HOE_CANE") - || (internalname != null && internalname.equals("TREECAPITATOR_AXE")) - || (internalname != null && internalname.startsWith("THEORETICAL_HOE_WARTS")) - || (internalname != null && internalname.equals("JUNGLE_AXE"))) { - Coins = 2; - } else if ((internalname != null && internalname.equals("PUMPKIN_DICER")) || - (internalname != null && internalname.equals("FUNGI_CUTTER"))) { - Coins = 4; - } else if ((internalname != null && internalname.equals("MELON_DICER"))) { - Coins = 0.5; - } else { - Coins = 0; - } - } - if (NotEnoughUpdates.INSTANCE.config.skillOverlays.useBZPrice) { - if (internalname != null && internalname.startsWith("THEORETICAL_HOE_WARTS")) { - JsonObject crop = NotEnoughUpdates.INSTANCE.manager.auctionManager.getBazaarInfo("ENCHANTED_NETHER_STALK"); - if (crop != null) { - if (crop.has("curr_sell")) { - Coins = crop.get("curr_sell").getAsFloat() / 160; - } - } - } else if (internalname != null && internalname.startsWith("THEORETICAL_HOE_POTATO")) { - JsonObject crop = NotEnoughUpdates.INSTANCE.manager.auctionManager.getBazaarInfo("ENCHANTED_POTATO"); - if (crop != null) { - if (crop.has("curr_sell")) { - Coins = crop.get("curr_sell").getAsFloat() / 160; - } - } - } else if (internalname != null && internalname.startsWith("THEORETICAL_HOE_CARROT")) { - JsonObject crop = NotEnoughUpdates.INSTANCE.manager.auctionManager.getBazaarInfo("ENCHANTED_CARROT"); - if (crop != null) { - if (crop.has("curr_sell")) { - Coins = crop.get("curr_sell").getAsFloat() / 160; - } - } - } else if (internalname != null && internalname.startsWith("THEORETICAL_HOE_CANE")) { - JsonObject crop = NotEnoughUpdates.INSTANCE.manager.auctionManager.getBazaarInfo("ENCHANTED_SUGAR"); - if (crop != null) { - if (crop.has("curr_sell")) { - Coins = crop.get("curr_sell").getAsFloat() / 160; - } - } - } else if (internalname != null && internalname.startsWith("PUMPKIN_DICER")) { - JsonObject crop = NotEnoughUpdates.INSTANCE.manager.auctionManager.getBazaarInfo("ENCHANTED_PUMPKIN"); - if (crop != null) { - if (crop.has("curr_sell")) { - Coins = crop.get("curr_sell").getAsFloat() / 160; - } - } - } else if (internalname != null && internalname.startsWith("FUNGI_CUTTER")) { - JsonObject red = NotEnoughUpdates.INSTANCE.manager.auctionManager.getBazaarInfo("ENCHANTED_RED_MUSHROOM"); - JsonObject brown = NotEnoughUpdates.INSTANCE.manager.auctionManager.getBazaarInfo("ENCHANTED_BROWN_MUSHROOM"); - if (red != null && brown != null) { - if (red.has("curr_sell") && (brown.has("curr_sell"))) { - double crop = (red.get("curr_sell").getAsFloat() + red.get("curr_sell").getAsFloat()) / 2; - Coins = crop / 160; - } - } - } else if (internalname != null && internalname.startsWith("MELON_DICER")) { - JsonObject crop = NotEnoughUpdates.INSTANCE.manager.auctionManager.getBazaarInfo("ENCHANTED_MELON"); - if (crop != null) { - if (crop.has("curr_sell")) { - Coins = crop.get("curr_sell").getAsFloat() / 160; - } - } - } else if (internalname != null && internalname.startsWith("THEORETICAL_HOE_WHEAT")) { - JsonObject crop = NotEnoughUpdates.INSTANCE.manager.auctionManager.getBazaarInfo("ENCHANTED_HAY_BLOCK"); - if (crop != null) { - if (crop.has("curr_sell")) { - Coins = crop.get("curr_sell").getAsFloat() / 1296; - } - } - } else if (internalname != null && internalname.startsWith("CACTUS_KNIFE")) { - JsonObject crop = NotEnoughUpdates.INSTANCE.manager.auctionManager.getBazaarInfo("ENCHANTED_CACTUS_GREEN"); - if (crop != null) { - if (crop.has("curr_sell")) { - Coins = crop.get("curr_sell").getAsFloat() / 160; - } - } - } - } - - skillInfoLast = skillInfo; - skillInfo = XPInformation.getInstance().getSkillInfo(skillType); - if (skillInfo != null) { - float totalXp = skillInfo.totalXp; - - if (lastTotalXp > 0) { - float delta = totalXp - lastTotalXp; - - if (delta > 0 && delta < 1000) { - xpGainTimer = 3; - - xpGainQueue.add(0, delta); - while (xpGainQueue.size() > 30) { - xpGainQueue.removeLast(); - } - - float totalGain = 0; - for (float f : xpGainQueue) totalGain += f; - - xpGainHour = totalGain * (60 * 60) / xpGainQueue.size(); - - isFarming = true; - } else if (xpGainTimer > 0) { - xpGainTimer--; - - xpGainQueue.add(0, 0f); - while (xpGainQueue.size() > 30) { - xpGainQueue.removeLast(); - } - - float totalGain = 0; - for (float f : xpGainQueue) totalGain += f; - - xpGainHour = totalGain * (60 * 60) / xpGainQueue.size(); - - isFarming = true; - } else if (delta <= 0) { - isFarming = false; - } - } - - lastTotalXp = totalXp; - } - - while (counterQueue.size() >= 4) { - counterQueue.removeLast(); - } - - if (counterQueue.isEmpty()) { - cropsPerSecond = -1; - cropsPerSecondLast = 0; - } else { - cropsPerSecondLast = cropsPerSecond; - int last = counterQueue.getLast(); - int first = counterQueue.getFirst(); - - cropsPerSecond = (first - last) / 3f; - } - - if (counter != -1) { - overlayStrings = new ArrayList<>(); - } else { - overlayStrings = null; - } - - } - - @Override - public void updateFrequent() { - super.updateFrequent(); - - if (counter < 0) { - overlayStrings = null; - } else { - HashMap lineMap = new HashMap<>(); - - overlayStrings = new ArrayList<>(); - - NumberFormat format = NumberFormat.getIntegerInstance(); - - if (counter >= 0 && cultivating != counter) { - int counterInterp = (int) interp(counter, counterLast); - - lineMap.put( - 0, - EnumChatFormatting.AQUA + "Counter: " + EnumChatFormatting.YELLOW + format.format(counterInterp) - ); - } - - if (counter >= 0) { - if (cropsPerSecondLast == cropsPerSecond && cropsPerSecond <= 0) { - lineMap.put( - 1, - EnumChatFormatting.AQUA + (Foraging == 1 ? "Logs/m: " : "Crops/m: ") + EnumChatFormatting.YELLOW + "N/A" - ); - } else { - float cpsInterp = interp(cropsPerSecond, cropsPerSecondLast); - - lineMap.put( - 1, - EnumChatFormatting.AQUA + (Foraging == 1 ? "Logs/m: " : "Crops/m: ") + EnumChatFormatting.YELLOW + - String.format("%,.2f", cpsInterp * 60) - ); - } - } - - if (counter >= 0 && Coins > 0) { - if (cropsPerSecondLast == cropsPerSecond && cropsPerSecond <= 0) { - lineMap.put(10, EnumChatFormatting.AQUA + "Coins/m: " + EnumChatFormatting.YELLOW + "N/A"); - } else { - float cpsInterp = interp(cropsPerSecond, cropsPerSecondLast); - - lineMap.put(10, EnumChatFormatting.AQUA + "Coins/m: " + EnumChatFormatting.YELLOW + - String.format("%,.2f", (cpsInterp * 60) * Coins)); - } - } - - if (cultivatingTier <= 9 && cultivating > 0) { - int counterInterp = (int) interp(cultivating, cultivatingLast); - lineMap.put( - 9, - EnumChatFormatting.AQUA + "Cultivating: " + EnumChatFormatting.YELLOW + format.format(counterInterp) + "/" + - cultivatingTierAmount - ); - } - if (cultivatingTier == 10) { - int counterInterp = (int) interp(cultivating, cultivatingLast); - lineMap.put( - 9, - EnumChatFormatting.AQUA + "Cultivating: " + EnumChatFormatting.YELLOW + format.format(counterInterp) - ); - } - - float xpInterp = xpGainHour; - if (xpGainHourLast == xpGainHour && xpGainHour <= 0) { - lineMap.put(5, EnumChatFormatting.AQUA + "XP/h: " + EnumChatFormatting.YELLOW + "N/A"); - } else { - xpInterp = interp(xpGainHour, xpGainHourLast); - - lineMap.put(5, EnumChatFormatting.AQUA + "XP/h: " + EnumChatFormatting.YELLOW + - format.format(xpInterp) + (isFarming ? "" : EnumChatFormatting.RED + " (PAUSED)")); - } - - if (skillInfo != null && skillInfo.level < 60) { - StringBuilder levelStr = new StringBuilder(EnumChatFormatting.AQUA + skillType + ": "); - - levelStr.append(EnumChatFormatting.YELLOW) - .append(skillInfo.level) - .append(EnumChatFormatting.GRAY) - .append(" ["); - - float progress = skillInfo.currentXp / skillInfo.currentXpMax; - if (skillInfoLast != null && skillInfo.currentXpMax == skillInfoLast.currentXpMax) { - progress = interp(progress, skillInfoLast.currentXp / skillInfoLast.currentXpMax); - } - - float lines = 25; - for (int i = 0; i < lines; i++) { - if (i / lines < progress) { - levelStr.append(EnumChatFormatting.YELLOW); - } else { - levelStr.append(EnumChatFormatting.DARK_GRAY); - } - levelStr.append('|'); - } - - levelStr.append(EnumChatFormatting.GRAY) - .append("] ") - .append(EnumChatFormatting.YELLOW) - .append((int) (progress * 100)) - .append("%"); - - int current = (int) skillInfo.currentXp; - if (skillInfoLast != null && skillInfo.currentXpMax == skillInfoLast.currentXpMax) { - current = (int) interp(current, skillInfoLast.currentXp); - } - - int remaining = (int) (skillInfo.currentXpMax - skillInfo.currentXp); - if (skillInfoLast != null && skillInfo.currentXpMax == skillInfoLast.currentXpMax) { - remaining = (int) interp(remaining, (int) (skillInfoLast.currentXpMax - skillInfoLast.currentXp)); - } - - lineMap.put(2, levelStr.toString()); - lineMap.put(3, EnumChatFormatting.AQUA + "Current XP: " + EnumChatFormatting.YELLOW + format.format(current)); - if (remaining < 0) { - lineMap.put(4, EnumChatFormatting.AQUA + "Remaining XP: " + EnumChatFormatting.YELLOW + "MAXED!"); - lineMap.put(7, EnumChatFormatting.AQUA + "ETA: " + EnumChatFormatting.YELLOW + "MAXED!"); - } else { - lineMap.put( - 4, - EnumChatFormatting.AQUA + "Remaining XP: " + EnumChatFormatting.YELLOW + format.format(remaining) - ); - if (xpGainHour < 1000) { - lineMap.put(7, EnumChatFormatting.AQUA + "ETA: " + EnumChatFormatting.YELLOW + "N/A"); - } else { - lineMap.put( - 7, - EnumChatFormatting.AQUA + "ETA: " + EnumChatFormatting.YELLOW + - Utils.prettyTime((long) (remaining) * 1000 * 60 * 60 / (long) xpInterp) - ); - } - } - - } - - if (skillInfo != null && skillInfo.level == 60 || Alch == 1 && skillInfo != null && skillInfo.level == 50) { - int current = (int) skillInfo.currentXp; - if (skillInfoLast != null && skillInfo.currentXpMax == skillInfoLast.currentXpMax) { - current = (int) interp(current, skillInfoLast.currentXp); - } - - if (Alch == 0) { - lineMap.put( - 2, - EnumChatFormatting.AQUA + "Farming: " + EnumChatFormatting.YELLOW + "60 " + EnumChatFormatting.RED + - "(Maxed)" - ); - } else if (Foraging == 1) { - lineMap.put( - 2, - EnumChatFormatting.AQUA + "Foraging: " + EnumChatFormatting.YELLOW + "50 " + EnumChatFormatting.RED + - "(Maxed)" - ); - } else { - lineMap.put( - 2, - EnumChatFormatting.AQUA + "Alch: " + EnumChatFormatting.YELLOW + "50 " + EnumChatFormatting.RED + "(Maxed)" - ); - } - lineMap.put(3, EnumChatFormatting.AQUA + "Current XP: " + EnumChatFormatting.YELLOW + format.format(current)); - - } - - float yaw = Minecraft.getMinecraft().thePlayer.rotationYawHead; - float pitch = Minecraft.getMinecraft().thePlayer.rotationPitch; - yaw %= 360; - if (yaw < 0) yaw += 360; - if (yaw > 180) yaw -= 360; - pitch %= 360; - if (pitch < 0) pitch += 360; - if (pitch > 180) pitch -= 360; - - lineMap.put(6, EnumChatFormatting.AQUA + "Yaw: " + EnumChatFormatting.YELLOW + - String.format("%.2f", yaw) + EnumChatFormatting.BOLD + "\u1D52"); - - lineMap.put(8, EnumChatFormatting.AQUA + "Pitch: " + EnumChatFormatting.YELLOW + - String.format("%.2f", pitch) + EnumChatFormatting.BOLD + "\u1D52"); - - for (int strIndex : NotEnoughUpdates.INSTANCE.config.skillOverlays.farmingText) { - if (lineMap.get(strIndex) != null) { - overlayStrings.add(lineMap.get(strIndex)); - } - } - if (overlayStrings != null && overlayStrings.isEmpty()) overlayStrings = null; - } - } -} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/overlays/FarmingSkillOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/overlays/FarmingSkillOverlay.java new file mode 100644 index 00000000..39b64136 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/overlays/FarmingSkillOverlay.java @@ -0,0 +1,544 @@ +/* + * Copyright (C) 2022 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.JsonObject; +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.core.config.Position; +import io.github.moulberry.notenoughupdates.core.util.lerp.LerpUtils; +import io.github.moulberry.notenoughupdates.util.Utils; +import io.github.moulberry.notenoughupdates.util.XPInformation; +import net.minecraft.client.Minecraft; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.EnumChatFormatting; + +import java.text.NumberFormat; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.function.Supplier; + +public class FarmingSkillOverlay extends TextOverlay { + private long lastUpdate = -1; + private int counterLast = -1; + private int counter = -1; + private int cultivatingLast = -1; + private int cultivating = -1; + private int cultivatingTier = -1; + private String cultivatingTierAmount = "1"; + private int Farming = -1; + private int Alch = -1; + private int Foraging = -1; + private double Coins = -1; + private float cropsPerSecondLast = 0; + private float cropsPerSecond = 0; + private final LinkedList counterQueue = new LinkedList<>(); + + private XPInformation.SkillInfo skillInfo = null; + private XPInformation.SkillInfo skillInfoLast = null; + + private float lastTotalXp = -1; + private boolean isFarming = false; + private final LinkedList xpGainQueue = new LinkedList<>(); + private float xpGainHourLast = -1; + private float xpGainHour = -1; + + private int xpGainTimer = 0; + + private String skillType = "Farming"; + + public FarmingSkillOverlay( + Position position, + Supplier> dummyStrings, + Supplier styleSupplier + ) { + super(position, dummyStrings, styleSupplier); + } + + private float interp(float now, float last) { + float interp = now; + if (last >= 0 && last != now) { + float factor = (System.currentTimeMillis() - lastUpdate) / 1000f; + factor = LerpUtils.clampZeroOne(factor); + interp = last + (now - last) * factor; + } + return interp; + } + + @Override + public void update() { + if (!NotEnoughUpdates.INSTANCE.config.skillOverlays.farmingOverlay) { + counter = -1; + overlayStrings = null; + return; + } + + lastUpdate = System.currentTimeMillis(); + counterLast = counter; + cultivatingLast = cultivating; + xpGainHourLast = xpGainHour; + counter = -1; + + if (Minecraft.getMinecraft().thePlayer == null) return; + + ItemStack stack = Minecraft.getMinecraft().thePlayer.getHeldItem(); + if (stack != null && stack.hasTagCompound()) { + NBTTagCompound tag = stack.getTagCompound(); + + if (tag.hasKey("ExtraAttributes", 10)) { + NBTTagCompound ea = tag.getCompoundTag("ExtraAttributes"); + + if (ea.hasKey("mined_crops", 99)) { + counter = ea.getInteger("mined_crops"); + cultivating = ea.getInteger("farmed_cultivating"); + counterQueue.add(0, counter); + } else if (ea.hasKey("farmed_cultivating", 99)) { + counter = ea.getInteger("farmed_cultivating"); + cultivating = ea.getInteger("farmed_cultivating"); + counterQueue.add(0, counter); + } + } + } + + if (cultivating < 1000) { + cultivatingTier = 1; + } else if (cultivating < 5000) { + cultivatingTier = 2; + } else if (cultivating < 25000) { + cultivatingTier = 3; + } else if (cultivating < 100000) { + cultivatingTier = 4; + } else if (cultivating < 300000) { + cultivatingTier = 5; + } else if (cultivating < 1500000) { + cultivatingTier = 6; + } else if (cultivating < 5000000) { + cultivatingTier = 7; + } else if (cultivating < 20000000) { + cultivatingTier = 8; + } else if (cultivating < 100000000) { + cultivatingTier = 9; + } else if (cultivating > 100000000) { + cultivatingTier = 10; + } + + switch (cultivatingTier) { + case 1: + cultivatingTierAmount = "1,000"; + break; + case 2: + cultivatingTierAmount = "5,000"; + break; + case 3: + cultivatingTierAmount = "25,000"; + break; + case 4: + cultivatingTierAmount = "100,000"; + break; + case 5: + cultivatingTierAmount = "300,000"; + break; + case 6: + cultivatingTierAmount = "1,500,000"; + break; + case 7: + cultivatingTierAmount = "5,000,000"; + break; + case 8: + cultivatingTierAmount = "20,000,000"; + break; + case 9: + cultivatingTierAmount = "100,000,000"; + break; + case 10: + cultivatingTierAmount = "Maxed"; + break; + } + + String internalname = NotEnoughUpdates.INSTANCE.manager.getInternalNameForItem(stack); + if (internalname != null && internalname.startsWith("THEORETICAL_HOE_WARTS")) { + skillType = "Alchemy"; + Farming = 0; + Alch = 1; + Foraging = 0; + } else if (internalname != null && internalname.startsWith("TREECAPITATOR_AXE") || + (internalname != null && internalname.startsWith("JUNGLE_AXE"))) { + skillType = "Foraging"; + Farming = 0; + Alch = 0; + Foraging = 1; + } else { + skillType = "Farming"; + Farming = 1; + Alch = 0; + Foraging = 0; + } + + if (!NotEnoughUpdates.INSTANCE.config.skillOverlays.useBZPrice || internalname != null && (internalname.equals( + "TREECAPITATOR_AXE")) || internalname != null && (internalname.equals("JUNGLE_AXE"))) { + if ((internalname != null && internalname.equals("COCO_CHOPPER"))) { + Coins = 3; + } else if (internalname != null && internalname.startsWith("THEORETICAL_HOE_POTATO") || + (internalname != null && internalname.startsWith("THEORETICAL_HOE_CARROT")) || + (internalname != null && internalname.equals("CACTUS_KNIFE")) || + (internalname != null && internalname.startsWith("THEORETICAL_HOE_WHEAT"))) { + Coins = 1; + } else if (internalname != null && internalname.startsWith("THEORETICAL_HOE_CANE") + || (internalname != null && internalname.equals("TREECAPITATOR_AXE")) + || (internalname != null && internalname.startsWith("THEORETICAL_HOE_WARTS")) + || (internalname != null && internalname.equals("JUNGLE_AXE"))) { + Coins = 2; + } else if ((internalname != null && internalname.equals("PUMPKIN_DICER")) || + (internalname != null && internalname.equals("FUNGI_CUTTER"))) { + Coins = 4; + } else if ((internalname != null && internalname.equals("MELON_DICER"))) { + Coins = 0.5; + } else { + Coins = 0; + } + } + if (NotEnoughUpdates.INSTANCE.config.skillOverlays.useBZPrice) { + if (internalname != null && internalname.startsWith("THEORETICAL_HOE_WARTS")) { + JsonObject crop = NotEnoughUpdates.INSTANCE.manager.auctionManager.getBazaarInfo("ENCHANTED_NETHER_STALK"); + if (crop != null) { + if (crop.has("curr_sell")) { + Coins = crop.get("curr_sell").getAsFloat() / 160; + } + } + } else if (internalname != null && internalname.startsWith("THEORETICAL_HOE_POTATO")) { + JsonObject crop = NotEnoughUpdates.INSTANCE.manager.auctionManager.getBazaarInfo("ENCHANTED_POTATO"); + if (crop != null) { + if (crop.has("curr_sell")) { + Coins = crop.get("curr_sell").getAsFloat() / 160; + } + } + } else if (internalname != null && internalname.startsWith("THEORETICAL_HOE_CARROT")) { + JsonObject crop = NotEnoughUpdates.INSTANCE.manager.auctionManager.getBazaarInfo("ENCHANTED_CARROT"); + if (crop != null) { + if (crop.has("curr_sell")) { + Coins = crop.get("curr_sell").getAsFloat() / 160; + } + } + } else if (internalname != null && internalname.startsWith("THEORETICAL_HOE_CANE")) { + JsonObject crop = NotEnoughUpdates.INSTANCE.manager.auctionManager.getBazaarInfo("ENCHANTED_SUGAR"); + if (crop != null) { + if (crop.has("curr_sell")) { + Coins = crop.get("curr_sell").getAsFloat() / 160; + } + } + } else if (internalname != null && internalname.startsWith("PUMPKIN_DICER")) { + JsonObject crop = NotEnoughUpdates.INSTANCE.manager.auctionManager.getBazaarInfo("ENCHANTED_PUMPKIN"); + if (crop != null) { + if (crop.has("curr_sell")) { + Coins = crop.get("curr_sell").getAsFloat() / 160; + } + } + } else if (internalname != null && internalname.startsWith("FUNGI_CUTTER")) { + JsonObject red = NotEnoughUpdates.INSTANCE.manager.auctionManager.getBazaarInfo("ENCHANTED_RED_MUSHROOM"); + JsonObject brown = NotEnoughUpdates.INSTANCE.manager.auctionManager.getBazaarInfo("ENCHANTED_BROWN_MUSHROOM"); + if (red != null && brown != null) { + if (red.has("curr_sell") && (brown.has("curr_sell"))) { + double crop = (red.get("curr_sell").getAsFloat() + red.get("curr_sell").getAsFloat()) / 2; + Coins = crop / 160; + } + } + } else if (internalname != null && internalname.startsWith("MELON_DICER")) { + JsonObject crop = NotEnoughUpdates.INSTANCE.manager.auctionManager.getBazaarInfo("ENCHANTED_MELON"); + if (crop != null) { + if (crop.has("curr_sell")) { + Coins = crop.get("curr_sell").getAsFloat() / 160; + } + } + } else if (internalname != null && internalname.startsWith("THEORETICAL_HOE_WHEAT")) { + JsonObject crop = NotEnoughUpdates.INSTANCE.manager.auctionManager.getBazaarInfo("ENCHANTED_HAY_BLOCK"); + if (crop != null) { + if (crop.has("curr_sell")) { + Coins = crop.get("curr_sell").getAsFloat() / 1296; + } + } + } else if (internalname != null && internalname.startsWith("CACTUS_KNIFE")) { + JsonObject crop = NotEnoughUpdates.INSTANCE.manager.auctionManager.getBazaarInfo("ENCHANTED_CACTUS_GREEN"); + if (crop != null) { + if (crop.has("curr_sell")) { + Coins = crop.get("curr_sell").getAsFloat() / 160; + } + } + } + } + skillInfoLast = skillInfo; + skillInfo = XPInformation.getInstance().getSkillInfo(skillType); + if (skillInfo != null) { + float totalXp = skillInfo.totalXp; + + if (lastTotalXp > 0) { + float delta = totalXp - lastTotalXp; + + if (delta > 0 && delta < 1000) { + + xpGainTimer = NotEnoughUpdates.INSTANCE.config.skillOverlays.farmingPauseTimer; + + xpGainQueue.add(0, delta); + while (xpGainQueue.size() > 30) { + xpGainQueue.removeLast(); + } + + float totalGain = 0; + for (float f : xpGainQueue) totalGain += f; + + xpGainHour = totalGain * (60 * 60) / xpGainQueue.size(); + + isFarming = true; + } else if (xpGainTimer > 0) { + xpGainTimer--; + + xpGainQueue.add(0, 0f); + while (xpGainQueue.size() > 30) { + xpGainQueue.removeLast(); + } + + float totalGain = 0; + for (float f : xpGainQueue) totalGain += f; + + xpGainHour = totalGain * (60 * 60) / xpGainQueue.size(); + + isFarming = true; + } else if (delta <= 0) { + isFarming = false; + } + } + + lastTotalXp = totalXp; + } + + while (counterQueue.size() >= 4) { + counterQueue.removeLast(); + } + + if (counterQueue.isEmpty()) { + cropsPerSecond = -1; + cropsPerSecondLast = 0; + } else { + cropsPerSecondLast = cropsPerSecond; + int last = counterQueue.getLast(); + int first = counterQueue.getFirst(); + + cropsPerSecond = (first - last) / 3f; + } + + if (counter != -1) { + overlayStrings = new ArrayList<>(); + } else { + overlayStrings = null; + } + + } + + @Override + public void updateFrequent() { + super.updateFrequent(); + + if (counter < 0) { + overlayStrings = null; + } else { + HashMap lineMap = new HashMap<>(); + + overlayStrings = new ArrayList<>(); + + NumberFormat format = NumberFormat.getIntegerInstance(); + + if (counter >= 0 && cultivating != counter) { + int counterInterp = (int) interp(counter, counterLast); + + lineMap.put( + 0, + EnumChatFormatting.AQUA + "Counter: " + EnumChatFormatting.YELLOW + format.format(counterInterp) + ); + } + + if (counter >= 0) { + if (cropsPerSecondLast == cropsPerSecond && cropsPerSecond <= 0) { + lineMap.put( + 1, + EnumChatFormatting.AQUA + (Foraging == 1 ? "Logs/m: " : "Crops/m: ") + EnumChatFormatting.YELLOW + "N/A" + ); + } else { + float cpsInterp = interp(cropsPerSecond, cropsPerSecondLast); + + lineMap.put( + 1, + EnumChatFormatting.AQUA + (Foraging == 1 ? "Logs/m: " : "Crops/m: ") + EnumChatFormatting.YELLOW + + String.format("%,.2f", cpsInterp * 60) + ); + } + } + + if (counter >= 0 && Coins > 0) { + if (cropsPerSecondLast == cropsPerSecond && cropsPerSecond <= 0) { + lineMap.put(10, EnumChatFormatting.AQUA + "Coins/m: " + EnumChatFormatting.YELLOW + "N/A"); + } else { + float cpsInterp = interp(cropsPerSecond, cropsPerSecondLast); + + lineMap.put(10, EnumChatFormatting.AQUA + "Coins/m: " + EnumChatFormatting.YELLOW + + String.format("%,.2f", (cpsInterp * 60) * Coins)); + } + } + + if (cultivatingTier <= 9 && cultivating > 0) { + int counterInterp = (int) interp(cultivating, cultivatingLast); + lineMap.put( + 9, + EnumChatFormatting.AQUA + "Cultivating: " + EnumChatFormatting.YELLOW + format.format(counterInterp) + "/" + + cultivatingTierAmount + ); + } + if (cultivatingTier == 10) { + int counterInterp = (int) interp(cultivating, cultivatingLast); + lineMap.put( + 9, + EnumChatFormatting.AQUA + "Cultivating: " + EnumChatFormatting.YELLOW + format.format(counterInterp) + ); + } + + float xpInterp = xpGainHour; + if (xpGainHourLast == xpGainHour && xpGainHour <= 0) { + lineMap.put(5, EnumChatFormatting.AQUA + "XP/h: " + EnumChatFormatting.YELLOW + "N/A"); + } else { + xpInterp = interp(xpGainHour, xpGainHourLast); + + lineMap.put(5, EnumChatFormatting.AQUA + "XP/h: " + EnumChatFormatting.YELLOW + + format.format(xpInterp) + (isFarming ? "" : EnumChatFormatting.RED + " (PAUSED)")); + } + + if (skillInfo != null && skillInfo.level < 60) { + StringBuilder levelStr = new StringBuilder(EnumChatFormatting.AQUA + skillType + ": "); + + levelStr.append(EnumChatFormatting.YELLOW) + .append(skillInfo.level) + .append(EnumChatFormatting.GRAY) + .append(" ["); + + float progress = skillInfo.currentXp / skillInfo.currentXpMax; + if (skillInfoLast != null && skillInfo.currentXpMax == skillInfoLast.currentXpMax) { + progress = interp(progress, skillInfoLast.currentXp / skillInfoLast.currentXpMax); + } + + float lines = 25; + for (int i = 0; i < lines; i++) { + if (i / lines < progress) { + levelStr.append(EnumChatFormatting.YELLOW); + } else { + levelStr.append(EnumChatFormatting.DARK_GRAY); + } + levelStr.append('|'); + } + + levelStr.append(EnumChatFormatting.GRAY) + .append("] ") + .append(EnumChatFormatting.YELLOW) + .append((int) (progress * 100)) + .append("%"); + + int current = (int) skillInfo.currentXp; + if (skillInfoLast != null && skillInfo.currentXpMax == skillInfoLast.currentXpMax) { + current = (int) interp(current, skillInfoLast.currentXp); + } + + int remaining = (int) (skillInfo.currentXpMax - skillInfo.currentXp); + if (skillInfoLast != null && skillInfo.currentXpMax == skillInfoLast.currentXpMax) { + remaining = (int) interp(remaining, (int) (skillInfoLast.currentXpMax - skillInfoLast.currentXp)); + } + + lineMap.put(2, levelStr.toString()); + lineMap.put(3, EnumChatFormatting.AQUA + "Current XP: " + EnumChatFormatting.YELLOW + format.format(current)); + if (remaining < 0) { + lineMap.put(4, EnumChatFormatting.AQUA + "Remaining XP: " + EnumChatFormatting.YELLOW + "MAXED!"); + lineMap.put(7, EnumChatFormatting.AQUA + "ETA: " + EnumChatFormatting.YELLOW + "MAXED!"); + } else { + lineMap.put( + 4, + EnumChatFormatting.AQUA + "Remaining XP: " + EnumChatFormatting.YELLOW + format.format(remaining) + ); + if (xpGainHour < 1000) { + lineMap.put(7, EnumChatFormatting.AQUA + "ETA: " + EnumChatFormatting.YELLOW + "N/A"); + } else { + lineMap.put( + 7, + EnumChatFormatting.AQUA + "ETA: " + EnumChatFormatting.YELLOW + + Utils.prettyTime((long) (remaining) * 1000 * 60 * 60 / (long) xpInterp) + ); + } + } + + } + + if (skillInfo != null && skillInfo.level == 60 || Alch == 1 && skillInfo != null && skillInfo.level == 50) { + int current = (int) skillInfo.currentXp; + if (skillInfoLast != null && skillInfo.currentXpMax == skillInfoLast.currentXpMax) { + current = (int) interp(current, skillInfoLast.currentXp); + } + + if (Alch == 0) { + lineMap.put( + 2, + EnumChatFormatting.AQUA + "Farming: " + EnumChatFormatting.YELLOW + "60 " + EnumChatFormatting.RED + + "(Maxed)" + ); + } else if (Foraging == 1) { + lineMap.put( + 2, + EnumChatFormatting.AQUA + "Foraging: " + EnumChatFormatting.YELLOW + "50 " + EnumChatFormatting.RED + + "(Maxed)" + ); + } else { + lineMap.put( + 2, + EnumChatFormatting.AQUA + "Alch: " + EnumChatFormatting.YELLOW + "50 " + EnumChatFormatting.RED + "(Maxed)" + ); + } + lineMap.put(3, EnumChatFormatting.AQUA + "Current XP: " + EnumChatFormatting.YELLOW + format.format(current)); + + } + + float yaw = Minecraft.getMinecraft().thePlayer.rotationYawHead; + float pitch = Minecraft.getMinecraft().thePlayer.rotationPitch; + yaw %= 360; + if (yaw < 0) yaw += 360; + if (yaw > 180) yaw -= 360; + pitch %= 360; + if (pitch < 0) pitch += 360; + if (pitch > 180) pitch -= 360; + + lineMap.put(6, EnumChatFormatting.AQUA + "Yaw: " + EnumChatFormatting.YELLOW + + String.format("%.2f", yaw) + EnumChatFormatting.BOLD + "\u1D52"); + + lineMap.put(8, EnumChatFormatting.AQUA + "Pitch: " + EnumChatFormatting.YELLOW + + String.format("%.2f", pitch) + EnumChatFormatting.BOLD + "\u1D52"); + + for (int strIndex : NotEnoughUpdates.INSTANCE.config.skillOverlays.farmingText) { + if (lineMap.get(strIndex) != null) { + overlayStrings.add(lineMap.get(strIndex)); + } + } + if (overlayStrings != null && overlayStrings.isEmpty()) overlayStrings = null; + } + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/overlays/FishingSkillOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/overlays/FishingSkillOverlay.java index 717ff944..b1143042 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/overlays/FishingSkillOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/overlays/FishingSkillOverlay.java @@ -180,7 +180,7 @@ public class FishingSkillOverlay float delta = totalXp - lastTotalXp; if (delta > 0 && delta < 1000) { - xpGainTimer = 3; + xpGainTimer = NotEnoughUpdates.INSTANCE.config.skillOverlays.fishingPauseTimer; xpGainQueue.add(0, delta); while (xpGainQueue.size() > 30) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/overlays/MiningSkillOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/overlays/MiningSkillOverlay.java index a20b1d27..4422e3ad 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/overlays/MiningSkillOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/overlays/MiningSkillOverlay.java @@ -172,7 +172,7 @@ public class MiningSkillOverlay float delta = totalXp - lastTotalXp; if (delta > 0 && delta < 1000) { - xpGainTimer = 3; + xpGainTimer = NotEnoughUpdates.INSTANCE.config.skillOverlays.miningPauseTimer; xpGainQueue.add(0, delta); while (xpGainQueue.size() > 30) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/overlays/OverlayManager.java b/src/main/java/io/github/moulberry/notenoughupdates/overlays/OverlayManager.java index fef11a45..d580b556 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/overlays/OverlayManager.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/overlays/OverlayManager.java @@ -30,7 +30,7 @@ public class OverlayManager { public static Class dontRenderOverlay = null; public static MiningOverlay miningOverlay; - public static FarmingOverlay farmingOverlay; + public static FarmingSkillOverlay farmingOverlay; public static FishingSkillOverlay fishingSkillOverlay; public static MiningSkillOverlay miningSkillOverlay; public static CombatSkillOverlay combatSkillOverlay; @@ -106,7 +106,7 @@ public class OverlayManager { "\u00a7bXP/h: \u00a7e238,129", "\u00a7bYaw: \u00a7e68.25\u00a7l\u1D52" ); - farmingOverlay = new FarmingOverlay(NotEnoughUpdates.INSTANCE.config.skillOverlays.farmingPosition, () -> { + farmingOverlay = new FarmingSkillOverlay(NotEnoughUpdates.INSTANCE.config.skillOverlays.farmingPosition, () -> { List strings = new ArrayList<>(); for (int i : NotEnoughUpdates.INSTANCE.config.skillOverlays.farmingText) { if (i >= 0 && i < farmingDummy.size()) strings.add(farmingDummy.get(i)); -- cgit