aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoman / Linnea Gräf <roman.graef@gmail.com>2022-10-30 21:11:36 +0100
committerGitHub <noreply@github.com>2022-10-30 21:11:36 +0100
commit99734ab57bed735b30c1c37c902c3cfa9c77bebc (patch)
tree13f43fb8673325e77ff5c88c86fd99fde47b293f
parent08d6696c36b116f9fe537b767fa23e57afe87cbc (diff)
parent5697b510ee9e397c71439f7960c671e1b7641f34 (diff)
downloadNotEnoughUpdates-nobuttons.tar.gz
NotEnoughUpdates-nobuttons.tar.bz2
NotEnoughUpdates-nobuttons.zip
Merge branch 'master' into nobuttonsnobuttons
-rw-r--r--Update Notes/2.1.1.md5
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java12
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java4
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java4
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java7
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/core/util/render/RenderUtils.java12
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/listener/ChatListener.java5
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/listener/ItemTooltipRngListener.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/listener/NEUEventListener.java7
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/listener/RenderListener.java17
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DungeonNpcProfitOverlay.java391
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/EnderNodes.java42
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/FairySouls.java1
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiItemRecipe.java15
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiContainer.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Dungeons.java37
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Misc.java9
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Notifications.java42
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/BasicPage.java14
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/DungeonPage.java29
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java26
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewer.java60
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/recipes/RecipeHistory.java74
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/TitleUtil.java92
24 files changed, 871 insertions, 38 deletions
diff --git a/Update Notes/2.1.1.md b/Update Notes/2.1.1.md
index 1f4e0311..988913cc 100644
--- a/Update Notes/2.1.1.md
+++ b/Update Notes/2.1.1.md
@@ -18,3 +18,8 @@
- Add exponent and percentage to calculator - u9g
- Add total trophy fish count to /pv - Vixid
- Allow hiding messages below a set skyblock level - nopo
+ - Add crimson isle quests to todo overlay - Vixid
+ - Add replace chat social options to both party and guild chat - Vixid
+ - Add class average to dungeons page in /pv - Vixid
+ - Add recipe history and fairy soul waypoint distance - Vixid
+ - Fix buggy cape on player model in /pv - Vixid
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java
index af190244..71aa10b6 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java
@@ -34,6 +34,7 @@ import io.github.moulberry.notenoughupdates.recipes.CraftingOverlay;
import io.github.moulberry.notenoughupdates.recipes.CraftingRecipe;
import io.github.moulberry.notenoughupdates.recipes.Ingredient;
import io.github.moulberry.notenoughupdates.recipes.NeuRecipe;
+import io.github.moulberry.notenoughupdates.recipes.RecipeHistory;
import io.github.moulberry.notenoughupdates.util.ApiUtil;
import io.github.moulberry.notenoughupdates.util.Constants;
import io.github.moulberry.notenoughupdates.util.HotmInformation;
@@ -113,12 +114,16 @@ public class NEUManager {
new KeyBinding("Show usages for item", Keyboard.KEY_U, "NotEnoughUpdates");
public final KeyBinding keybindViewRecipe =
new KeyBinding("Show recipe for item", Keyboard.KEY_R, "NotEnoughUpdates");
+ public final KeyBinding keybindPreviousRecipe =
+ new KeyBinding("Show previous recipe", Keyboard.KEY_LBRACKET, "NotEnoughUpdates");
+ public final KeyBinding keybindNextRecipe =
+ new KeyBinding("Show next recipe", Keyboard.KEY_RBRACKET, "NotEnoughUpdates");
public final KeyBinding keybindToggleDisplay = new KeyBinding("Toggle NEU overlay", 0, "NotEnoughUpdates");
public final KeyBinding keybindClosePanes = new KeyBinding("Close NEU panes", 0, "NotEnoughUpdates");
public final KeyBinding keybindItemSelect = new KeyBinding("Select Item", -98 /*middle*/, "NotEnoughUpdates");
public final KeyBinding[] keybinds = new KeyBinding[]{
- keybindGive, keybindFavourite, keybindViewUsages, keybindViewRecipe,
- keybindToggleDisplay, keybindClosePanes, keybindItemSelect
+ keybindGive, keybindFavourite, keybindViewUsages, keybindViewRecipe, keybindPreviousRecipe,
+ keybindNextRecipe, keybindToggleDisplay, keybindClosePanes, keybindItemSelect
};
public String viewItemAttemptID = null;
@@ -884,7 +889,6 @@ public class NEUManager {
case "viewpotion":
neu.sendChatMessage("/viewpotion " + internalName.split(";")[0].toLowerCase(Locale.ROOT));
}
- displayGuiItemRecipe(internalName);
}
public void showRecipe(String internalName) {
@@ -988,6 +992,7 @@ public class NEUManager {
List<NeuRecipe> usages = getAvailableUsagesFor(internalName);
if (usages.isEmpty()) return false;
NotEnoughUpdates.INSTANCE.openGui = (new GuiItemRecipe(usages, this));
+ RecipeHistory.add(NotEnoughUpdates.INSTANCE.openGui);
return true;
}
@@ -996,6 +1001,7 @@ public class NEUManager {
List<NeuRecipe> recipes = getAvailableRecipesFor(internalName);
if (recipes.isEmpty()) return false;
NotEnoughUpdates.INSTANCE.openGui = (new GuiItemRecipe(recipes, this));
+ RecipeHistory.add(NotEnoughUpdates.INSTANCE.openGui);
return true;
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java
index 2f55c338..87ce915b 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java
@@ -1219,8 +1219,8 @@ public class NEUOverlay extends Gui {
String internal1 = o1.get("internalname").getAsString();
String internal2 = o2.get("internalname").getAsString();
- double cost1 = manager.auctionManager.getBazaarOrBin(internal1);
- double cost2 = manager.auctionManager.getBazaarOrBin(internal2);
+ double cost1 = manager.auctionManager.getBazaarOrBin(internal1, false);
+ double cost2 = manager.auctionManager.getBazaarOrBin(internal2, false);
if (cost1 < cost2) return mult;
if (cost1 > cost2) return -mult;
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java
index 143033b7..b514e419 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java
@@ -45,6 +45,7 @@ import io.github.moulberry.notenoughupdates.miscfeatures.CrystalOverlay;
import io.github.moulberry.notenoughupdates.miscfeatures.CrystalWishingCompassSolver;
import io.github.moulberry.notenoughupdates.miscfeatures.CustomItemEffects;
import io.github.moulberry.notenoughupdates.miscfeatures.CustomSkulls;
+import io.github.moulberry.notenoughupdates.miscfeatures.DungeonNpcProfitOverlay;
import io.github.moulberry.notenoughupdates.miscfeatures.DwarvenMinesWaypoints;
import io.github.moulberry.notenoughupdates.miscfeatures.EnchantingSolvers;
import io.github.moulberry.notenoughupdates.miscfeatures.FairySouls;
@@ -78,6 +79,7 @@ import io.github.moulberry.notenoughupdates.profileviewer.ProfileViewer;
import io.github.moulberry.notenoughupdates.recipes.RecipeGenerator;
import io.github.moulberry.notenoughupdates.util.Constants;
import io.github.moulberry.notenoughupdates.util.SBInfo;
+import io.github.moulberry.notenoughupdates.util.TitleUtil;
import io.github.moulberry.notenoughupdates.util.Utils;
import io.github.moulberry.notenoughupdates.util.XPInformation;
import net.minecraft.client.Minecraft;
@@ -295,6 +297,7 @@ public class NotEnoughUpdates {
MinecraftForge.EVENT_BUS.register(new DwarvenMinesWaypoints());
MinecraftForge.EVENT_BUS.register(new FuelBar());
MinecraftForge.EVENT_BUS.register(new AuctionProfit());
+ MinecraftForge.EVENT_BUS.register(new DungeonNpcProfitOverlay());
MinecraftForge.EVENT_BUS.register(XPInformation.getInstance());
MinecraftForge.EVENT_BUS.register(OverlayManager.petInfoOverlay);
MinecraftForge.EVENT_BUS.register(OverlayManager.timersOverlay);
@@ -322,6 +325,7 @@ public class NotEnoughUpdates {
MinecraftForge.EVENT_BUS.register(MinionHelperManager.getInstance());
MinecraftForge.EVENT_BUS.register(navigation);
MinecraftForge.EVENT_BUS.register(new WorldListener(this));
+ MinecraftForge.EVENT_BUS.register(TitleUtil.getInstance());
if (Minecraft.getMinecraft().getResourceManager() instanceof IReloadableResourceManager) {
IReloadableResourceManager manager = (IReloadableResourceManager) Minecraft.getMinecraft().getResourceManager();
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java b/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java
index 1b6896db..755e53f5 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java
@@ -822,10 +822,11 @@ public class APIManager {
return keys;
}
- public double getBazaarOrBin(String internalName) {
+ public double getBazaarOrBin(String internalName, boolean useSellingPrice) {
+ String curr = (useSellingPrice ? "curr_sell" : "curr_buy");
JsonObject bazaarInfo = manager.auctionManager.getBazaarInfo(internalName);
- if (bazaarInfo != null && bazaarInfo.get("curr_buy") != null) {
- return bazaarInfo.get("curr_buy").getAsFloat();
+ if (bazaarInfo != null && bazaarInfo.get(curr) != null) {
+ return bazaarInfo.get(curr).getAsFloat();
} else {
return manager.auctionManager.getLowestBin(internalName);
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/util/render/RenderUtils.java b/src/main/java/io/github/moulberry/notenoughupdates/core/util/render/RenderUtils.java
index e7ce29c3..d7bd097a 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/core/util/render/RenderUtils.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/core/util/render/RenderUtils.java
@@ -378,14 +378,18 @@ public class RenderUtils {
}
public static void renderWayPoint(List<String> str, Vec3i loc, float partialTicks) {
- renderWayPoint(str, new Vector3f(loc.getX(), loc.getY(), loc.getZ()), partialTicks);
+ renderWayPoint(str, new Vector3f(loc.getX(), loc.getY(), loc.getZ()), partialTicks, false);
}
public static void renderWayPoint(String str, Vector3f loc, float partialTicks) {
- renderWayPoint(Arrays.asList(str), loc, partialTicks);
+ renderWayPoint(Arrays.asList(str), loc, partialTicks, false);
+ }
+
+ public static void renderWayPoint(Vec3i loc, float partialTicks) {
+ renderWayPoint(Arrays.asList(""), new Vector3f(loc.getX(), loc.getY(), loc.getZ()), partialTicks, true);
}
- public static void renderWayPoint(List<String> lines, Vector3f loc, float partialTicks) {
+ public static void renderWayPoint(List<String> lines, Vector3f loc, float partialTicks, boolean onlyShowDistance) {
GlStateManager.alphaFunc(516, 0.1F);
GlStateManager.pushMatrix();
@@ -409,7 +413,7 @@ public class RenderUtils {
GlStateManager.translate(x, y, z);
GlStateManager.translate(0, viewer.getEyeHeight(), 0);
- lines = new ArrayList<>(lines);
+ lines = onlyShowDistance ? new ArrayList<>() : new ArrayList<>(lines);
lines.add(EnumChatFormatting.YELLOW.toString() + Math.round(dist) + "m");
renderNametag(lines);
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/listener/ChatListener.java b/src/main/java/io/github/moulberry/notenoughupdates/listener/ChatListener.java
index a5acd5b4..6a94c0b3 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/listener/ChatListener.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/listener/ChatListener.java
@@ -23,6 +23,7 @@ import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
import io.github.moulberry.notenoughupdates.dungeons.DungeonWin;
import io.github.moulberry.notenoughupdates.miscfeatures.CookieWarning;
import io.github.moulberry.notenoughupdates.miscfeatures.CrystalMetalDetectorSolver;
+import io.github.moulberry.notenoughupdates.miscfeatures.EnderNodes;
import io.github.moulberry.notenoughupdates.miscfeatures.StreamerMode;
import io.github.moulberry.notenoughupdates.overlays.OverlayManager;
import io.github.moulberry.notenoughupdates.overlays.SlayerOverlay;
@@ -306,5 +307,9 @@ public class ChatListener {
unformatted.equals("You have successfully picked the lock on this chest!")
|| (unformatted.startsWith("You received +") && unformatted.endsWith(" Powder")))
OverlayManager.powderGrindingOverlay.message(unformatted);
+
+ if (unformatted.equals("ENDER NODE! You found Endermite Nest!")) {
+ EnderNodes.dispalyEndermiteNotif();
+ }
}
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/listener/ItemTooltipRngListener.java b/src/main/java/io/github/moulberry/notenoughupdates/listener/ItemTooltipRngListener.java
index fdae53ea..2b7a9bef 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/listener/ItemTooltipRngListener.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/listener/ItemTooltipRngListener.java
@@ -139,7 +139,7 @@ public class ItemTooltipRngListener {
private String getFormatCoinsPer(ItemStack stack, int needed, int multiplier, String label) {
String internalName = neu.manager.createItemResolutionQuery().withItemStack(stack).resolveInternalName();
- double profit = neu.manager.auctionManager.getBazaarOrBin(internalName);
+ double profit = neu.manager.auctionManager.getBazaarOrBin(internalName, false);
if (profit <= 0) return null;
//ask hypixel nicely to release a 'chest price api' with 4 dimensions for us. the 4 dimensions needed are: item name, floor, normal/mm, s/s+
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/listener/NEUEventListener.java b/src/main/java/io/github/moulberry/notenoughupdates/listener/NEUEventListener.java
index 43a1daf9..5b388dea 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/listener/NEUEventListener.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/listener/NEUEventListener.java
@@ -34,11 +34,13 @@ import io.github.moulberry.notenoughupdates.miscfeatures.ItemCustomizeManager;
import io.github.moulberry.notenoughupdates.miscfeatures.NPCRetexturing;
import io.github.moulberry.notenoughupdates.miscgui.AccessoryBagOverlay;
import io.github.moulberry.notenoughupdates.miscgui.GuiCustomEnchant;
+import io.github.moulberry.notenoughupdates.miscgui.GuiItemRecipe;
import io.github.moulberry.notenoughupdates.miscgui.hex.GuiCustomHex;
import io.github.moulberry.notenoughupdates.miscgui.StorageOverlay;
import io.github.moulberry.notenoughupdates.overlays.OverlayManager;
import io.github.moulberry.notenoughupdates.overlays.TextOverlay;
import io.github.moulberry.notenoughupdates.overlays.TextTabOverlay;
+import io.github.moulberry.notenoughupdates.recipes.RecipeHistory;
import io.github.moulberry.notenoughupdates.util.Constants;
import io.github.moulberry.notenoughupdates.util.NotificationHandler;
import io.github.moulberry.notenoughupdates.util.ProfileApiSyncer;
@@ -162,6 +164,11 @@ public class NEUEventListener {
if (longUpdate) {
+
+ if (!(Minecraft.getMinecraft().currentScreen instanceof GuiItemRecipe)) {
+ RecipeHistory.clear();
+ }
+
CrystalOverlay.tick();
FairySouls.getInstance().tick();
XPInformation.getInstance().tick();
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/listener/RenderListener.java b/src/main/java/io/github/moulberry/notenoughupdates/listener/RenderListener.java
index 2eb4c23a..949358ad 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/listener/RenderListener.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/listener/RenderListener.java
@@ -40,6 +40,7 @@ import io.github.moulberry.notenoughupdates.miscfeatures.AuctionBINWarning;
import io.github.moulberry.notenoughupdates.miscfeatures.AuctionProfit;
import io.github.moulberry.notenoughupdates.miscfeatures.BetterContainers;
import io.github.moulberry.notenoughupdates.miscfeatures.CrystalMetalDetectorSolver;
+import io.github.moulberry.notenoughupdates.miscfeatures.DungeonNpcProfitOverlay;
import io.github.moulberry.notenoughupdates.miscfeatures.EnchantingSolvers;
import io.github.moulberry.notenoughupdates.miscfeatures.StorageManager;
import io.github.moulberry.notenoughupdates.miscgui.AccessoryBagOverlay;
@@ -136,6 +137,8 @@ public class RenderListener {
public static long lastGuiClosed = 0;
public static boolean inventoryLoaded = false;
private final NotEnoughUpdates neu;
+ private final NumberFormat format = new DecimalFormat("#,##0.#", new DecimalFormatSymbols(Locale.US));
+ private final Pattern ESSENCE_PATTERN = Pattern.compile("§d(.+) Essence §8x([\\d,]+)");
ScheduledExecutorService ses = Executors.newScheduledThreadPool(1);
JsonObject essenceJson = new JsonObject();
private boolean hoverInv = false;
@@ -150,9 +153,6 @@ public class RenderListener {
private boolean typing;
private HashMap<String, String> cachedDefinitions;
private boolean inDungeonPage = false;
- private final NumberFormat format = new DecimalFormat("#,##0.#", new DecimalFormatSymbols(Locale.US));
-
- private final Pattern ESSENCE_PATTERN = Pattern.compile("§d(.+) Essence §8x([\\d,]+)");
public RenderListener(NotEnoughUpdates neu) {
this.neu = neu;
@@ -458,7 +458,6 @@ public class RenderListener {
return;
}
-
boolean tradeWindowActive = TradeWindow.tradeWindowActive(containerName);
boolean storageOverlayActive = StorageManager.getInstance().shouldRenderStorageOverlay(containerName);
boolean customAhActive =
@@ -559,7 +558,7 @@ public class RenderListener {
x -= 25;
}
}
- if (inDungeonPage) {
+ if (inDungeonPage || DungeonNpcProfitOverlay.isRendering()) {
if (x + 10 > guiLeft + xSize && x + 18 < guiLeft + xSize + 4 + 28 + 20 && y > guiTop - 180 &&
y < guiTop + 100) {
x += 185;
@@ -694,7 +693,7 @@ public class RenderListener {
}
}
- if (inDungeonPage) {
+ if (inDungeonPage || DungeonNpcProfitOverlay.isRendering()) {
if (x + 10 > guiLeft + xSize && x + 18 < guiLeft + xSize + 4 + 28 + 20 && y > guiTop - 180 &&
y < guiTop + 100) {
x += 185;
@@ -812,7 +811,7 @@ public class RenderListener {
if (bazaarPrice < 5000000 && internal.equals("RECOMBOBULATOR_3000")) bazaarPrice = 5000000;
double worth = -1;
- boolean isOnBz = false;
+ boolean isOnBz = false;
if (bazaarPrice >= 0) {
worth = bazaarPrice;
isOnBz = true;
@@ -1086,7 +1085,6 @@ public class RenderListener {
return;
}
-
boolean tradeWindowActive = TradeWindow.tradeWindowActive(containerName);
boolean storageOverlayActive = StorageManager.getInstance().shouldRenderStorageOverlay(containerName);
boolean customAhActive =
@@ -1176,7 +1174,7 @@ public class RenderListener {
x -= 25;
}
}
- if (inDungeonPage) {
+ if (inDungeonPage || DungeonNpcProfitOverlay.isRendering()) {
if (x + 10 > guiLeft + xSize && x + 18 < guiLeft + xSize + 4 + 28 + 20 && y > guiTop - 180 &&
y < guiTop + 100) {
x += 185;
@@ -1564,7 +1562,6 @@ public class RenderListener {
return;
}
-
boolean tradeWindowActive = TradeWindow.tradeWindowActive(containerName);
boolean storageOverlayActive = StorageManager.getInstance().shouldRenderStorageOverlay(containerName);
boolean customAhActive =
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DungeonNpcProfitOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DungeonNpcProfitOverlay.java
new file mode 100644
index 00000000..7caa4d6b
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DungeonNpcProfitOverlay.java
@@ -0,0 +1,391 @@
+/*
+ * 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 <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.miscfeatures;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.core.util.StringUtils;
+import io.github.moulberry.notenoughupdates.mixins.AccessorGuiContainer;
+import io.github.moulberry.notenoughupdates.util.ItemUtils;
+import io.github.moulberry.notenoughupdates.util.SBInfo;
+import io.github.moulberry.notenoughupdates.util.Utils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.Gui;
+import net.minecraft.client.gui.ScaledResolution;
+import net.minecraft.client.gui.inventory.GuiChest;
+import net.minecraft.client.renderer.GlStateManager;
+import net.minecraft.init.Items;
+import net.minecraft.inventory.Slot;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.EnumChatFormatting;
+import net.minecraft.util.ResourceLocation;
+import net.minecraftforge.client.event.GuiScreenEvent;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+import org.jetbrains.annotations.Nullable;
+import org.lwjgl.opengl.GL11;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+
+import java.awt.*;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class DungeonNpcProfitOverlay {
+
+ private static final ResourceLocation dungeonProfitResource =
+ new ResourceLocation("notenoughupdates:dungeon_chest_worth.png");
+
+ private static final Pattern chestNamePattern = Pattern.compile(".+ Catacombs - Floor .+");
+ private static final Pattern essencePattern = Pattern.compile(
+ "^§.(?<essenceType>\\w+) Essence §.x(?<essenceAmount>\\d+)$");
+ private static final Pattern enchantedBookPattern = Pattern.compile("^§.Enchanted Book \\((?<enchantName>.*)\\)");
+ private static List<DungeonChest> chestProfits;
+ private static List<Slot> previousSlots;
+
+ /**
+ * Check the current status for the overlay
+ *
+ * @return if the overlay is rendering right now
+ */
+ public static boolean isRendering() {
+ return NotEnoughUpdates.INSTANCE.config.dungeons.croesusProfitOverlay && chestProfits != null;
+ }
+
+ /**
+ * Highlight the slot that is being drawn if applicable. Called by MixinGuiContainer
+ *
+ * @param slot the slot to be checked
+ * @see io.github.moulberry.notenoughupdates.mixins.MixinGuiContainer#drawSlotRet(Slot, CallbackInfo)
+ */
+ public static void onDrawSlot(Slot slot) {
+ if (isRendering() && NotEnoughUpdates.INSTANCE.config.dungeons.croesusHighlightHighestProfit) {
+ for (DungeonChest chestProfit : chestProfits) {
+ if (chestProfit.shouldHighlight) {
+ if (slot.slotNumber == chestProfit.slot) {
+ Gui.drawRect(
+ slot.xDisplayPosition,
+ slot.yDisplayPosition,
+ slot.xDisplayPosition + 16,
+ slot.yDisplayPosition + 16,
+ Color.GREEN.getRGB()
+ );
+ }
+ }
+ }
+ }
+ }
+
+ @SubscribeEvent
+ public void onDrawBackground(GuiScreenEvent.BackgroundDrawnEvent event) {
+ if (!NotEnoughUpdates.INSTANCE.config.dungeons.croesusProfitOverlay || !(event.gui instanceof GuiChest)) {
+ chestProfits = null;
+ previousSlots = null;
+ return;
+ }
+
+ String lastOpenChestName = SBInfo.getInstance().lastOpenChestName;
+ Matcher matcher = chestNamePattern.matcher(lastOpenChestName);
+ if (!matcher.matches()) {
+ chestProfits = null;
+ previousSlots = null;
+ return;
+ }
+ GuiChest guiChest = (GuiChest) event.gui;
+ List<Slot> slots = guiChest.inventorySlots.inventorySlots;
+
+ if (chestProfits == null || chestProfits.isEmpty() || !slots.equals(previousSlots)) {
+ updateDungeonChests(slots);
+ }
+ previousSlots = guiChest.inventorySlots.inventorySlots;
+
+ render(guiChest);
+ }
+
+ /**
+ * Update the profit applicable for the chests currently visible
+ *
+ * @param inventorySlots list of Slots from the GUI containing the dungeon chest previews
+ */
+ private void updateDungeonChests(List<Slot> inventorySlots) {
+ chestProfits = new ArrayList<>();
+ //loop through the upper chest
+ for (int i = 0; i < 27; i++) {
+ Slot inventorySlot = inventorySlots.get(i);
+ if (inventorySlot == null) {
+ continue;
+ }
+
+ ItemStack stack = inventorySlot.getStack();
+ if (stack != null && stack.getItem() != null && stack.getItem() == Items.skull) {
+ //each item is a DungeonChest
+ DungeonChest dungeonChest = new DungeonChest();
+ dungeonChest.slot = i;
+
+ List<String> lore = ItemUtils.getLore(stack);
+ if ("§7Contents".equals(lore.get(0))) {
+ dungeonChest.name = stack.getDisplayName();
+ List<SkyblockItem> items = new ArrayList<>();
+ for (String s : lore) {
+ //check if this line is showing the cost of opening the Chest
+ if (s.endsWith(" Coins")) {
+ String coinString = StringUtils.cleanColour(s);
+ int whitespace = coinString.indexOf(' ');
+ if (whitespace != -1) {
+ String amountString = coinString.substring(0, whitespace).replace(",", "");
+ dungeonChest.costToOpen = Integer.parseInt(amountString);
+ continue;
+ }
+ } else if (s.equals("§aFREE")) {
+ dungeonChest.costToOpen = 0;
+ }
+
+ //check if the line can be converted to a SkyblockItem
+ SkyblockItem skyblockItem = SkyblockItem.createFromLoreEntry(s);
+ if (skyblockItem != null) {
+ items.add(skyblockItem);
+ }
+ }
+ dungeonChest.items = items;
+ if (dungeonChest.costToOpen != -1) {
+ dungeonChest.calculateProfitAndBuildLore();
+ chestProfits.add(dungeonChest);
+ }
+ }
+ }
+ }
+
+ if (NotEnoughUpdates.INSTANCE.config.dungeons.croesusSortByProfit) {
+ chestProfits.sort(Comparator.comparing(DungeonChest::getProfit).reversed());
+ }
+
+ if (NotEnoughUpdates.INSTANCE.config.dungeons.croesusHighlightHighestProfit && chestProfits.size() >= 1) {
+ List<DungeonChest> copiedList = new ArrayList<>(chestProfits);
+ copiedList.sort(Comparator.comparing(DungeonChest::getProfit).reversed());
+
+ copiedList.get(0).shouldHighlight = true;
+ }
+ }
+
+ public void render(GuiChest guiChest) {
+ int xSize = ((AccessorGuiContainer) guiChest).getXSize();
+ int guiLeft = ((AccessorGuiContainer) guiChest).getGuiLeft();
+ int guiTop = ((AccessorGuiContainer) guiChest).getGuiTop();
+ Minecraft.getMinecraft().getTextureManager().bindTexture(dungeonProfitResource);
+ GL11.glColor4f(1, 1, 1, 1);
+ GlStateManager.disableLighting();
+ Utils.drawTexturedRect(guiLeft + xSize + 4, guiTop, 180, 101, 0, 180 / 256f, 0, 101 / 256f, GL11.GL_NEAREST);
+
+ for (int i = 0; i < chestProfits.size(); i++) {
+ DungeonChest chestProfit = chestProfits.get(i);
+ int x = guiLeft + xSize + 14;
+ int y = guiTop + 6 + (i * 10);
+ Utils.renderAlignedString(
+ chestProfit.name,
+ (chestProfit.profit > 0
+ ? EnumChatFormatting.GREEN.toString()
+ : EnumChatFormatting.RED) + Utils.shortNumberFormat(chestProfit.profit, 0),
+ x,
+ y,
+ 160
+ );
+
+ ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft());
+ int width = scaledResolution.getScaledWidth();
+ int height = scaledResolution.getScaledHeight();
+
+ int mouseX = Utils.getMouseX();
+ int mouseY = Utils.getMouseY();
+
+ if (Utils.isWithinRect(mouseX, mouseY, x, y, 160, 10))
+ Utils.drawHoveringText(
+ chestProfit.lore,
+ mouseX,
+ mouseY,
+ width,
+ height,
+ -1,
+ Minecraft.getMinecraft().fontRendererObj
+ );
+ }
+
+ }
+
+ /**
+ * Dataclass holding info on a single Dungeon Chest Preview
+ * <p>