From d1600393e933ff993a11fc81c2c43a2f23c49b50 Mon Sep 17 00:00:00 2001 From: Cobble8 <41165207+Cobble8@users.noreply.github.com> Date: Wed, 22 Mar 2023 05:27:46 -0400 Subject: Made it so you can use per hour instead of per minute on crops and coins (#625) Co-authored-by: hannibal2 <24389977+hannibal00212@users.noreply.github.com> --- .../notenoughupdates/dungeons/DungeonMap.java | 16 +- .../options/seperateSections/SkillOverlays.java | 23 ++- .../overlays/FarmingSkillOverlay.java | 222 ++++++++++++++++----- .../moulberry/notenoughupdates/util/SBInfo.java | 28 +-- 4 files changed, 196 insertions(+), 93 deletions(-) (limited to 'src/main/java') diff --git a/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonMap.java b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonMap.java index 686cef8e..1e0c8c8e 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonMap.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonMap.java @@ -26,6 +26,7 @@ import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe; import io.github.moulberry.notenoughupdates.core.BackgroundBlur; import io.github.moulberry.notenoughupdates.core.config.Position; import io.github.moulberry.notenoughupdates.util.NEUResourceManager; +import io.github.moulberry.notenoughupdates.util.SidebarUtil; import io.github.moulberry.notenoughupdates.util.SpecialColour; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.block.material.MapColor; @@ -48,10 +49,7 @@ import net.minecraft.init.Items; import net.minecraft.item.Item; import net.minecraft.item.ItemMap; import net.minecraft.item.ItemStack; -import net.minecraft.scoreboard.Score; -import net.minecraft.scoreboard.ScoreObjective; import net.minecraft.scoreboard.ScorePlayerTeam; -import net.minecraft.scoreboard.Scoreboard; import net.minecraft.util.Matrix4f; import net.minecraft.util.ResourceLocation; import net.minecraft.util.Vec4b; @@ -1154,18 +1152,8 @@ public class DungeonMap { lastClearCache = System.currentTimeMillis(); isFloorOne = false; - Scoreboard scoreboard = Minecraft.getMinecraft().thePlayer.getWorldScoreboard(); - - ScoreObjective sidebarObjective = scoreboard.getObjectiveInDisplaySlot(1); - - List scores = new ArrayList<>(scoreboard.getSortedScores(sidebarObjective)); - - for (int i = scores.size() - 1; i >= 0; i--) { - Score score = scores.get(i); - ScorePlayerTeam scoreplayerteam1 = scoreboard.getPlayersTeam(score.getPlayerName()); - String line = ScorePlayerTeam.formatPlayerName(scoreplayerteam1, score.getPlayerName()); - line = Utils.cleanColour(line); + for (String line : SidebarUtil.readSidebarLines()) { if (line.contains("(F1)") || line.contains("(E)") || line.contains("(M1)")) { isFloorOne = true; if (line.contains("(E)")) { 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 f9dbe69e..6437f4f8 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 @@ -82,11 +82,12 @@ public class SkillOverlays { "\u00a7bETA: \u00a7e13h12m", "\u00a7bPitch: \u00a7e69.42\u00a7l\u1D52", "\u00a7bCultivating: \u00a7e10,137,945/20,000,000", - "\u00a7bCoins/m \u00a7e57,432" + "\u00a7bCoins/m \u00a7e57,432", + "\u00a7bContest Estimate \u00a7e342,784" } ) @ConfigAccordionId(id = 0) - public List farmingText = new ArrayList<>(Arrays.asList(0, 9, 10, 1, 2, 3, 4, 5, 7, 6)); + public List farmingText = new ArrayList<>(Arrays.asList(0, 9, 10, 1, 2, 3, 4, 5, 7, 6, 11)); @Expose @ConfigOption( @@ -97,6 +98,24 @@ public class SkillOverlays { @ConfigAccordionId(id = 0) public boolean useBZPrice = true; + @Expose + @ConfigOption( + name = "Use coins per hour", + desc = "Uses coins/h instead of coins/m" + ) + @ConfigEditorBoolean + @ConfigAccordionId(id = 0) + public boolean coinsPerHour = false; + + @Expose + @ConfigOption( + name = "Use crops per hour", + desc = "Uses crops/h instead of crops/m" + ) + @ConfigEditorBoolean + @ConfigAccordionId(id = 0) + public boolean cropsPerHour = false; + @Expose @ConfigOption( name = "Pause Timer", diff --git a/src/main/java/io/github/moulberry/notenoughupdates/overlays/FarmingSkillOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/overlays/FarmingSkillOverlay.java index 51f3d351..49b653f2 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/overlays/FarmingSkillOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/overlays/FarmingSkillOverlay.java @@ -20,9 +20,11 @@ package io.github.moulberry.notenoughupdates.overlays; import com.google.gson.JsonObject; +import io.github.moulberry.notenoughupdates.NEUManager; 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.SidebarUtil; import io.github.moulberry.notenoughupdates.util.Utils; import io.github.moulberry.notenoughupdates.util.XPInformation; import net.minecraft.client.Minecraft; @@ -32,6 +34,7 @@ import net.minecraft.util.EnumChatFormatting; import java.text.NumberFormat; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.LinkedList; import java.util.List; @@ -45,13 +48,16 @@ public class FarmingSkillOverlay extends TextOverlay { private int cultivating = -1; private int cultivatingTier = -1; private String cultivatingTierAmount = "1"; - private int Farming = 1; - private int Alch = 0; - private int Foraging = 0; - private double Coins = -1; + private int alchemy = 0; + private int foraging = 0; + private double coins = -1; private float cropsPerSecondLast = 0; private float cropsPerSecond = 0; private final LinkedList counterQueue = new LinkedList<>(); + private String lastItemHeld = "null"; + private int jacobPredictionLast = -1; + private int jacobPrediction = -1; + private boolean inJacobContest = false; private XPInformation.SkillInfo skillInfo = null; private XPInformation.SkillInfo skillInfoLast = null; @@ -94,6 +100,38 @@ public class FarmingSkillOverlay extends TextOverlay { return 0; } + private void gatherJacobData() { + inJacobContest = false; + if (isJacobTime()) { + int timeLeftInContest = (20 * 60) - ((int) ((System.currentTimeMillis() % 3600000 - 900000) / 1000)); + + int cropsFarmed = -1; + for (String line : SidebarUtil.readSidebarLines()) { + if (line.contains("Collected") || line.contains("BRONZE") || line.contains("SILVER") || + line.contains("GOLD")) { + inJacobContest = true; + String l = line.replaceAll("[^A-Za-z0-9() ]", ""); + cropsFarmed = Integer.parseInt(l.substring(l.lastIndexOf(" ") + 1).replace(",", "")); + } + jacobPrediction = (int) (cropsFarmed + (cropsPerSecond * timeLeftInContest)); + } + + } else { + jacobPrediction = -1; + jacobPredictionLast = -1; + } + } + + // Check if there is an active Jacob's contest + private static boolean isJacobTime() { + long now = System.currentTimeMillis(); + return now % 3600000 >= 900000 && now % 3600000 <= 2100000; + } + + //This is a list of the last X cropsPerSeconds to try and calm down the fluctuation for crops/min (they will be averaged) + //Needed due to farming fortune causing inconsistent amounts of crops each block break + private static ArrayList cropsOverLastXSeconds = new ArrayList<>(); + @Override public void update() { if (!NotEnoughUpdates.INSTANCE.config.skillOverlays.farmingOverlay) { @@ -161,71 +199,69 @@ public class FarmingSkillOverlay extends TextOverlay { cultivatingTierAmount = "Maxed"; } - String internalname = NotEnoughUpdates.INSTANCE.manager.getInternalNameForItem(stack); - if (internalname != null) { + String internalName = NotEnoughUpdates.INSTANCE.manager.getInternalNameForItem(stack); + if (internalName != null) { - //Set default skilltype to Farming and get BZprice config value - boolean useBZPrice = NotEnoughUpdates.INSTANCE.config.skillOverlays.useBZPrice; + //Set default skillType to Farming and get BZ price config value skillType = "Farming"; - Farming = 1; - Alch = 0; - Foraging = 0; + alchemy = 0; + foraging = 0; //WARTS - if (internalname.startsWith("THEORETICAL_HOE_WARTS")) { + boolean useBZPrice = NotEnoughUpdates.INSTANCE.config.skillOverlays.useBZPrice; + if (internalName.startsWith("THEORETICAL_HOE_WARTS")) { skillType = "Alchemy"; - Farming = 0; - Alch = 1; - Foraging = 0; - Coins = useBZPrice ? getCoinsBz("ENCHANTED_NETHER_STALK", ENCH_SIZE) : 2; + alchemy = 1; + foraging = 0; + coins = useBZPrice ? getCoinsBz("ENCHANTED_NETHER_STALK", ENCH_SIZE) : 2; //WOOD - } else if (internalname.equals("TREECAPITATOR_AXE") || internalname.equalsIgnoreCase("JUNGLE_AXE")) { + } else if (internalName.equals("TREECAPITATOR_AXE") || internalName.equalsIgnoreCase("JUNGLE_AXE")) { skillType = "Foraging"; - Farming = 0; - Alch = 0; - Foraging = 1; - Coins = 2; + alchemy = 0; + foraging = 1; + coins = 2; //COCOA - } else if (internalname.equals("COCO_CHOPPER")) { - Coins = useBZPrice ? getCoinsBz("ENCHANTED_COCOA", ENCH_SIZE) : 3; + } else if (internalName.equals("COCO_CHOPPER")) { + coins = useBZPrice ? getCoinsBz("ENCHANTED_COCOA", ENCH_SIZE) : 3; //CACTUS - } else if (internalname.equals("CACTUS_KNIFE")) { - Coins = useBZPrice ? getCoinsBz("ENCHANTED_CACTUS_GREEN", ENCH_SIZE) : 2; + } else if (internalName.equals("CACTUS_KNIFE")) { + coins = useBZPrice ? getCoinsBz("ENCHANTED_CACTUS_GREEN", ENCH_SIZE) : 2; //CANE - } else if (internalname.startsWith("THEORETICAL_HOE_CANE")) { - Coins = useBZPrice ? getCoinsBz("ENCHANTED_SUGAR", ENCH_SIZE) : 2; + } else if (internalName.startsWith("THEORETICAL_HOE_CANE")) { + coins = useBZPrice ? getCoinsBz("ENCHANTED_SUGAR", ENCH_SIZE) : 2; //CARROT - } else if (internalname.startsWith("THEORETICAL_HOE_CARROT")) { - Coins = useBZPrice ? getCoinsBz("ENCHANTED_CARROT", ENCH_SIZE) : 1; + } else if (internalName.startsWith("THEORETICAL_HOE_CARROT")) { + coins = useBZPrice ? getCoinsBz("ENCHANTED_CARROT", ENCH_SIZE) : 1; //POTATO - } else if (internalname.startsWith("THEORETICAL_HOE_POTATO")) { - Coins = useBZPrice ? getCoinsBz("ENCHANTED_POTATO", ENCH_SIZE) : 1; + } else if (internalName.startsWith("THEORETICAL_HOE_POTATO")) { + coins = useBZPrice ? getCoinsBz("ENCHANTED_POTATO", ENCH_SIZE) : 1; //MUSHROOM - } else if (internalname.equals("FUNGI_CUTTER")) { - Coins = useBZPrice ? ((getCoinsBz("ENCHANTED_RED_MUSHROOM", ENCH_SIZE) + - getCoinsBz("ENCHANTED_BROWN_MUSHROOM", ENCH_SIZE))/2) : 4; + } else if (internalName.equals("FUNGI_CUTTER")) { + coins = useBZPrice ? ((getCoinsBz("ENCHANTED_RED_MUSHROOM", ENCH_SIZE) + + getCoinsBz("ENCHANTED_BROWN_MUSHROOM", ENCH_SIZE)) / 2) : 4; //PUMPKIN - } else if (internalname.equals("PUMPKIN_DICER")) { - Coins = useBZPrice ? getCoinsBz("ENCHANTED_PUMPKIN", ENCH_SIZE) : 4; + } else if (internalName.startsWith("PUMPKIN_DICER")) { + coins = useBZPrice ? getCoinsBz("ENCHANTED_PUMPKIN", ENCH_SIZE) : 4; //MELON - } else if (internalname.equals("MELON_DICER")) { - Coins = useBZPrice ? getCoinsBz("ENCHANTED_MELON", ENCH_SIZE) : 0.5; + } else if (internalName.startsWith("MELON_DICER")) { + coins = useBZPrice ? getCoinsBz("ENCHANTED_MELON", ENCH_SIZE) : 0.5; //WHEAT - } else if (internalname.startsWith("THEORETICAL_HOE_WHEAT")) { - Coins = useBZPrice ? getCoinsBz("ENCHANTED_HAY_BLOCK", ENCH_BLOCK_SIZE) : 1; + } else if (internalName.startsWith("THEORETICAL_HOE_WHEAT")) { + coins = useBZPrice + ? getCoinsBz("ENCHANTED_HAY_BLOCK", ENCH_BLOCK_SIZE) : 1; } else { - Coins = 0; + coins = 0; } } @@ -286,7 +322,58 @@ public class FarmingSkillOverlay extends TextOverlay { int last = counterQueue.getLast(); int first = counterQueue.getFirst(); - cropsPerSecond = (first - last) / 3f; + //This is a list of the last X cropsPerSeconds to try and calm down the fluctuation for crops/min (they will be averaged) + //Needed due to farming fortune causing inconsistent amounts of crops each block break + //Making this while in case somehow it goes over X+1 + while (cropsOverLastXSeconds.size() > 60) { + cropsOverLastXSeconds.remove(0); + } + if ((first - last) / 2f != 0) { + cropsOverLastXSeconds.add((first - last) / 2f); + } else { + if (cropsPerSecondLast == 0) { + //This is to prevent bleeding from one crop to the next (or if you stop and then start again at a different pace) + //It removes 12 per tick because otherwise it would take 60s to go to N/A (now it only takes 5s) + int i = 12; + while (i > 0) { + i--; + if (cropsOverLastXSeconds.size() > 0) { + cropsOverLastXSeconds.remove(0); + } else { + break; + } + } + } + } + + if (!lastItemHeld.equals(NEUManager.getUUIDForItem(Minecraft.getMinecraft().thePlayer.getHeldItem()) == null + ? "null" + : NEUManager.getUUIDForItem(Minecraft.getMinecraft().thePlayer.getHeldItem()))) { + lastItemHeld = NEUManager.getUUIDForItem(Minecraft.getMinecraft().thePlayer.getHeldItem()) == null + ? "null" + : NEUManager.getUUIDForItem(Minecraft.getMinecraft().thePlayer.getHeldItem()); + cropsOverLastXSeconds.clear(); + } + + ArrayList temp = new ArrayList<>(cropsOverLastXSeconds); + if (cropsOverLastXSeconds.size() >= 3) { + temp.remove(Collections.min(temp)); + } + if (cropsOverLastXSeconds.size() >= 6) { + temp.remove(Collections.min(temp)); + temp.remove(Collections.max(temp)); + } + if (cropsOverLastXSeconds.size() >= 10) { + temp.remove(Collections.max(temp)); + } + + float cropsOverLastXSecondsTotal = 0; + for (Float crops : temp) { + cropsOverLastXSecondsTotal += crops; + } + //To prevent 0/0 + cropsPerSecond = + temp.size() != 0 && cropsOverLastXSecondsTotal != 0 ? cropsOverLastXSecondsTotal / temp.size() : 0; } if (counter != -1) { @@ -294,7 +381,7 @@ public class FarmingSkillOverlay extends TextOverlay { } else { overlayStrings = null; } - + gatherJacobData(); } @Override @@ -310,6 +397,14 @@ public class FarmingSkillOverlay extends TextOverlay { NumberFormat format = NumberFormat.getIntegerInstance(); + String cropsTimeSuffix = NotEnoughUpdates.INSTANCE.config.skillOverlays.cropsPerHour ? "h" : "m"; + int cropMultiplier = NotEnoughUpdates.INSTANCE.config.skillOverlays.cropsPerHour ? 60 : 1; + int cropDecimals = NotEnoughUpdates.INSTANCE.config.skillOverlays.cropsPerHour ? 0 : 2; + + String coinsTimeSuffix = NotEnoughUpdates.INSTANCE.config.skillOverlays.coinsPerHour ? "h" : "m"; + int coinMultiplier = NotEnoughUpdates.INSTANCE.config.skillOverlays.coinsPerHour ? 60 : 1; + int coinDecimals = NotEnoughUpdates.INSTANCE.config.skillOverlays.coinsPerHour ? 0 : 2; + if (counter >= 0 && cultivating != counter) { int counterInterp = (int) interp(counter, counterLast); @@ -323,27 +418,33 @@ public class FarmingSkillOverlay extends TextOverlay { if (cropsPerSecondLast == cropsPerSecond && cropsPerSecond <= 0) { lineMap.put( 1, - EnumChatFormatting.AQUA + (Foraging == 1 ? "Logs/m: " : "Crops/m: ") + EnumChatFormatting.YELLOW + "N/A" + EnumChatFormatting.AQUA + + (foraging == 1 ? "Logs/" + cropsTimeSuffix + ": " : "Crops/" + cropsTimeSuffix + ": ") + + 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) + EnumChatFormatting.AQUA + + (foraging == 1 ? "Logs/" + cropsTimeSuffix + ": " : "Crops/" + cropsTimeSuffix + ": ") + + EnumChatFormatting.YELLOW + + String.format("%,." + cropDecimals + "f", cpsInterp * 60 * cropMultiplier) ); } } - if (counter >= 0 && Coins > 0) { + if (counter >= 0 && coins > 0) { if (cropsPerSecondLast == cropsPerSecond && cropsPerSecond <= 0) { - lineMap.put(10, EnumChatFormatting.AQUA + "Coins/m: " + EnumChatFormatting.YELLOW + "N/A"); + lineMap.put( + 10, + EnumChatFormatting.AQUA + "Coins/" + coinsTimeSuffix + ": " + 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)); + lineMap.put(10, EnumChatFormatting.AQUA + "Coins/" + coinsTimeSuffix + ": " + EnumChatFormatting.YELLOW + + String.format("%,." + coinDecimals + "f", (cpsInterp * 60) * coins * coinMultiplier)); } } @@ -363,6 +464,19 @@ public class FarmingSkillOverlay extends TextOverlay { ); } + if (isJacobTime() && inJacobContest) { + if (jacobPredictionLast == jacobPrediction && jacobPrediction <= 0) { + lineMap.put(11, EnumChatFormatting.AQUA + "Contest Estimate: " + EnumChatFormatting.YELLOW + "N/A"); + } else { + float predInterp = interp(jacobPrediction, jacobPredictionLast); + lineMap.put( + 11, + EnumChatFormatting.AQUA + "Contest Estimate: " + EnumChatFormatting.YELLOW + + String.format("%,.0f", predInterp) + ); + } + } + float xpInterp = xpGainHour; if (xpGainHourLast == xpGainHour && xpGainHour <= 0) { lineMap.put(5, EnumChatFormatting.AQUA + "XP/h: " + EnumChatFormatting.YELLOW + "N/A"); @@ -435,19 +549,19 @@ public class FarmingSkillOverlay extends TextOverlay { } - if (skillInfo != null && skillInfo.level == 60 || Alch == 1 && skillInfo != null && skillInfo.level == 50) { + if (skillInfo != null && skillInfo.level == 60 || alchemy == 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) { + if (alchemy == 0) { lineMap.put( 2, EnumChatFormatting.AQUA + "Farming: " + EnumChatFormatting.YELLOW + "60 " + EnumChatFormatting.RED + "(Maxed)" ); - } else if (Foraging == 1) { + } else if (foraging == 1) { lineMap.put( 2, EnumChatFormatting.AQUA + "Foraging: " + EnumChatFormatting.YELLOW + "50 " + EnumChatFormatting.RED + diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java b/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java index 9d2d1056..ffde9ca1 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java @@ -37,10 +37,6 @@ import net.minecraft.inventory.ContainerChest; import net.minecraft.inventory.Slot; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.scoreboard.Score; -import net.minecraft.scoreboard.ScoreObjective; -import net.minecraft.scoreboard.ScorePlayerTeam; -import net.minecraft.scoreboard.Scoreboard; import net.minecraft.util.EnumChatFormatting; import net.minecraft.util.IChatComponent; import net.minecraftforge.client.event.ClientChatReceivedEvent; @@ -315,7 +311,6 @@ public class SBInfo { private static final Pattern SKILL_LEVEL_PATTERN = Pattern.compile("([^0-9:]+) (\\d{1,2})"); public void tick() { - boolean tempIsInDungeon = false; long currentTime = System.currentTimeMillis(); @@ -367,26 +362,13 @@ public class SBInfo { } try { - Scoreboard scoreboard = Minecraft.getMinecraft().thePlayer.getWorldScoreboard(); - - ScoreObjective sidebarObjective = scoreboard.getObjectiveInDisplaySlot(1); - - List scores = new ArrayList<>(scoreboard.getSortedScores(sidebarObjective)); - - List lines = new ArrayList<>(); - for (int i = scores.size() - 1; i >= 0; i--) { - Score score = scores.get(i); - ScorePlayerTeam scoreplayerteam1 = scoreboard.getPlayersTeam(score.getPlayerName()); - String line = ScorePlayerTeam.formatPlayerName(scoreplayerteam1, score.getPlayerName()); - line = Utils.cleanDuplicateColourCodes(line); - - String cleanLine = Utils.cleanColour(line); - - if (cleanLine.contains("Cleared:") && cleanLine.contains("%")) { + List lines = SidebarUtil.readSidebarLines(); + boolean tempIsInDungeon = false; + for (String line : lines) { + if (line.contains("Cleared:") && line.contains("%")) { tempIsInDungeon = true; + break; } - - lines.add(line); } isInDungeon = tempIsInDungeon; -- cgit