aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorLorenz <lo.scherf@gmail.com>2022-09-08 20:42:17 +0200
committerLorenz <lo.scherf@gmail.com>2022-09-08 20:42:17 +0200
commitbd35a713caac99069e795ea189b0f0e1f6000bff (patch)
treed61f07df55ba54de55435061c0227be292bbed93 /src/main/java
parent7d95510b60406fbef32c342c5c2adbce31d057c4 (diff)
parentd1488df319a1d19154d294cb29627b9026deb564 (diff)
downloadNotEnoughUpdates-bd35a713caac99069e795ea189b0f0e1f6000bff.tar.gz
NotEnoughUpdates-bd35a713caac99069e795ea189b0f0e1f6000bff.tar.bz2
NotEnoughUpdates-bd35a713caac99069e795ea189b0f0e1f6000bff.zip
Merge branch 'master' into minion_helper_2
# Conflicts: # src/main/java/io/github/moulberry/notenoughupdates/core/util/StringUtils.java # src/main/java/io/github/moulberry/notenoughupdates/overlays/MiningOverlay.java # src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ExtraPage.java
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/ItemPriceInformation.java91
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java108
-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.java14
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/core/util/StringUtils.java28
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/events/RepositoryReloadEvent.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/itemeditor/NEUItemEditor.java13
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/listener/ChatListener.java4
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/listener/ItemTooltipEssenceShopListener.java84
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/listener/ItemTooltipListener.java34
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/listener/ItemTooltipRngListener.java330
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/listener/NEUEventListener.java12
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/listener/RenderListener.java64
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AuctionProfit.java6
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/BazaarSacksProfit.java9
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DamageCommas.java29
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/EnchantingSolvers.java4
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/AccessoryBagOverlay.java4
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/TrophyRewardOverlay.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiContainer.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinRenderItem.java6
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinSkyclientCosmetics.java39
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java10
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/BazaarTweaks.java81
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Dungeons.java9
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Mining.java10
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Misc.java8
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/MiscOverlays.java9
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/SkillOverlays.java9
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/TooltipTweaks.java40
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/overlays/AuctionSearchOverlay.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/overlays/BazaarSearchOverlay.java572
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/overlays/CombatSkillOverlay.java82
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/overlays/MiningOverlay.java20
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/overlays/TextTabOverlay.java47
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/overlays/TimersOverlay.java9
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/BasicPage.java5
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/CollectionsPage.java3
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/DungeonPage.java21
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ExtraPage.java70
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java20
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/InventoriesPage.java108
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/MiningPage.java11
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/PetsPage.java7
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewer.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/bestiary/BestiaryPage.java7
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/Calculator.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/ItemResolutionQuery.java239
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/ItemUtils.java14
50 files changed, 1984 insertions, 326 deletions
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/ItemPriceInformation.java b/src/main/java/io/github/moulberry/notenoughupdates/ItemPriceInformation.java
index b47a7c7f..a773abdc 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/ItemPriceInformation.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/ItemPriceInformation.java
@@ -39,6 +39,8 @@ import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
import java.text.NumberFormat;
import java.util.HashSet;
import java.util.List;
@@ -49,6 +51,7 @@ public class ItemPriceInformation {
private static File file;
private static HashSet<String> auctionableItems = null;
private static Gson gson;
+ private static final NumberFormat format = new DecimalFormat("#,##0.#", new DecimalFormatSymbols(Locale.US));
public static boolean addToTooltip(List<String> tooltip, String internalname, ItemStack stack) {
return addToTooltip(tooltip, internalname, stack, true);
@@ -103,7 +106,7 @@ public class ItemPriceInformation {
JsonObject bazaarInfo = NotEnoughUpdates.INSTANCE.manager.auctionManager.getBazaarInfo(internalname);
double lowestBinAvg = NotEnoughUpdates.INSTANCE.manager.auctionManager.getItemAvgBin(internalname);
- long lowestBin = NotEnoughUpdates.INSTANCE.manager.auctionManager.getLowestBin(internalname);
+ double lowestBin = NotEnoughUpdates.INSTANCE.manager.auctionManager.getLowestBin(internalname);
APIManager.CraftInfo craftCost = NotEnoughUpdates.INSTANCE.manager.auctionManager.getCraftCost(internalname);
boolean bazaarItem = bazaarInfo != null;
@@ -119,8 +122,6 @@ public class ItemPriceInformation {
}
}
- NumberFormat format = NumberFormat.getInstance(Locale.US);
- boolean shortNumber = NotEnoughUpdates.INSTANCE.config.tooltipTweaks.shortNumberFormatPrices;
if (bazaarItem) {
List<Integer> lines = NotEnoughUpdates.INSTANCE.config.tooltipTweaks.priceInfoBaz;
@@ -145,11 +146,8 @@ public class ItemPriceInformation {
tooltip.add(EnumChatFormatting.DARK_GRAY + "[SHIFT show x" + shiftStackMultiplier + "]");
added = true;
}
- long bazaarBuyPrice = (long) bazaarInfo.get("avg_buy").getAsFloat() * stackMultiplier;
- tooltip.add(EnumChatFormatting.YELLOW.toString() + EnumChatFormatting.BOLD + "Bazaar Buy: " +
- EnumChatFormatting.GOLD + EnumChatFormatting.BOLD + (shortNumber && bazaarBuyPrice > 1000
- ? Utils.shortNumberFormat(bazaarBuyPrice, 0)
- : format.format(bazaarBuyPrice)) + " coins");
+ double bazaarBuyPrice = bazaarInfo.get("avg_buy").getAsFloat() * stackMultiplier;
+ tooltip.add(formatPrice("Bazaar Buy: ", bazaarBuyPrice));
}
break;
case 1:
@@ -160,11 +158,8 @@ public class ItemPriceInformation {
tooltip.add(EnumChatFormatting.DARK_GRAY + "[SHIFT show x" + shiftStackMultiplier + "]");
added = true;
}
- long bazaarSellPrice = (long) bazaarInfo.get("avg_sell").getAsFloat() * stackMultiplier;
- tooltip.add(EnumChatFormatting.YELLOW.toString() + EnumChatFormatting.BOLD + "Bazaar Sell: " +
- EnumChatFormatting.GOLD + EnumChatFormatting.BOLD + (shortNumber && bazaarSellPrice > 1000
- ? Utils.shortNumberFormat(bazaarSellPrice, 0)
- : format.format(bazaarSellPrice)) + " coins");
+ double bazaarSellPrice = bazaarInfo.get("avg_sell").getAsDouble() * stackMultiplier;
+ tooltip.add(formatPrice("Bazaar Sell: ", bazaarSellPrice));
}
break;
case 2:
@@ -175,12 +170,8 @@ public class ItemPriceInformation {
tooltip.add(EnumChatFormatting.DARK_GRAY + "[SHIFT show x" + shiftStackMultiplier + "]");
added = true;
}
- long bazaarInstantBuyPrice = (long) bazaarInfo.get("curr_buy").getAsFloat() * stackMultiplier;
- tooltip.add(EnumChatFormatting.YELLOW.toString() + EnumChatFormatting.BOLD + "Bazaar Insta-Buy: " +
- EnumChatFormatting.GOLD + EnumChatFormatting.BOLD + (shortNumber && bazaarInstantBuyPrice > 1000
- ? Utils.shortNumberFormat(bazaarInstantBuyPrice, 0)
- : format.format(bazaarInstantBuyPrice)) +
- " coins");
+ double bazaarInstantBuyPrice = bazaarInfo.get("curr_buy").getAsFloat() * stackMultiplier;
+ tooltip.add(formatPrice("Bazaar Insta-Buy: ", bazaarInstantBuyPrice));
}
break;
case 3:
@@ -191,20 +182,13 @@ public class ItemPriceInformation {
tooltip.add(EnumChatFormatting.DARK_GRAY + "[SHIFT show x" + shiftStackMultiplier + "]");
added = true;
}
- long bazaarInstantSellPrice = (long) bazaarInfo.get("curr_sell").getAsFloat() * stackMultiplier;
- tooltip.add(EnumChatFormatting.YELLOW.toString() + EnumChatFormatting.BOLD + "Bazaar Insta-Sell: " +
- EnumChatFormatting.GOLD + EnumChatFormatting.BOLD + (shortNumber && bazaarInstantSellPrice > 1000
- ? Utils.shortNumberFormat(
- bazaarInstantSellPrice,
- 0
- )
- : format.format(bazaarInstantSellPrice)) +
- " coins");
+ double bazaarInstantSellPrice = bazaarInfo.get("curr_sell").getAsFloat() * stackMultiplier;
+ tooltip.add(formatPrice("Bazaar Insta-Sell: ", bazaarInstantSellPrice));
}
break;
case 4:
if (craftCost != null && craftCost.fromRecipe) {
- if ((int) craftCost.craftCost == 0) {
+ if (craftCost.craftCost == 0) {
continue;
}
if (!added) {
@@ -213,10 +197,7 @@ public class ItemPriceInformation {
}
double cost = craftCost.craftCost;
if (shiftPressed) cost = cost * shiftStackMultiplier;
-
- tooltip.add(EnumChatFormatting.YELLOW.toString() + EnumChatFormatting.BOLD + "Raw Craft Cost: " +
- EnumChatFormatting.GOLD + EnumChatFormatting.BOLD +
- (shortNumber && cost > 1000 ? Utils.shortNumberFormat(cost, 0) : format.format((int) cost)) + " coins");
+ tooltip.add(formatPrice("Raw Craft Cost: ", cost));
}
break;
}
@@ -236,8 +217,7 @@ public class ItemPriceInformation {
tooltip.add("");
added = true;
}
- tooltip.add(EnumChatFormatting.YELLOW.toString() + EnumChatFormatting.BOLD + "Lowest BIN: " +
- EnumChatFormatting.GOLD + EnumChatFormatting.BOLD + format.format(lowestBin) + " coins");
+ tooltip.add(formatPrice("Lowest BIN: ", lowestBin));
}
break;
case 1:
@@ -248,21 +228,11 @@ public class ItemPriceInformation {
}
if (auctionInfo.has("clean_price")) {
- tooltip.add(EnumChatFormatting.YELLOW.toString() + EnumChatFormatting.BOLD + "AH Price (Clean): " +
- EnumChatFormatting.GOLD + EnumChatFormatting.BOLD +
- (shortNumber && auctionInfo.get("clean_price").getAsFloat() > 1000 ? Utils.shortNumberFormat(
- auctionInfo.get("clean_price").getAsFloat(),
- 0
- ) : format.format((int) auctionInfo.get("clean_price").getAsFloat())
- + " coins"));
+ double cleanPrice = auctionInfo.get("clean_price").getAsDouble();
+ tooltip.add(formatPrice("AH Price (Clean): ", cleanPrice));
} else {
- int auctionPrice =
- (int) (auctionInfo.get("price").getAsFloat() / auctionInfo.get("count").getAsFloat());
- tooltip.add(EnumChatFormatting.YELLOW.toString() + EnumChatFormatting.BOLD + "AH Price: " +
- EnumChatFormatting.GOLD + EnumChatFormatting.BOLD +
- (shortNumber && auctionPrice > 1000
- ? Utils.shortNumberFormat(auctionPrice, 0)
- : format.format(auctionPrice)) + " coins");
+ double auctionPrice = auctionInfo.get("price").getAsDouble() / auctionInfo.get("count").getAsFloat();
+ tooltip.add(formatPrice("AH Price: ", auctionPrice));
}
}
@@ -292,18 +262,14 @@ public class ItemPriceInformation {
break;
case 3:
if (craftCost != null && craftCost.fromRecipe) {
- if ((int) craftCost.craftCost == 0) {
+ if (craftCost.craftCost == 0) {
continue;
}
if (!added) {
tooltip.add("");
added = true;
}
- tooltip.add(EnumChatFormatting.YELLOW.toString() + EnumChatFormatting.BOLD + "Raw Craft Cost: " +
- EnumChatFormatting.GOLD + EnumChatFormatting.BOLD +
- (shortNumber && craftCost.craftCost > 1000
- ? Utils.shortNumberFormat(craftCost.craftCost, 0)
- : format.format((int) craftCost.craftCost)) + " coins");
+ tooltip.add(formatPrice("Raw Craft Cost: ", craftCost.craftCost));
}
break;
case 4:
@@ -312,11 +278,7 @@ public class ItemPriceInformation {
tooltip.add("");
added = true;
}
- tooltip.add(EnumChatFormatting.YELLOW.toString() + EnumChatFormatting.BOLD + "AVG Lowest BIN: " +
- EnumChatFormatting.GOLD + EnumChatFormatting.BOLD +
- (shortNumber && lowestBinAvg > 1000
- ? Utils.shortNumberFormat(lowestBinAvg, 0)
- : format.format(lowestBinAvg)) + " coins");
+ tooltip.add(formatPrice("AVG Lowest BIN: ", lowestBinAvg));
}
break;
case 5:
@@ -391,4 +353,13 @@ public class ItemPriceInformation {
return false;
}
+
+ private static String formatPrice(String label, double price) {
+ boolean shortNumber = NotEnoughUpdates.INSTANCE.config.tooltipTweaks.shortNumberFormatPrices;
+ String number = (shortNumber && price > 1000
+ ? Utils.shortNumberFormat(price, 0)
+ : price > 5 ? format.format((int) price) : format.format(price));
+ return "§e§l" + label + "§6§l" + number + " coins";
+ }
+
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java
index 407e6852..cad2235b 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java
@@ -36,6 +36,8 @@ import io.github.moulberry.notenoughupdates.recipes.NeuRecipe;
import io.github.moulberry.notenoughupdates.util.Constants;
import io.github.moulberry.notenoughupdates.util.HotmInformation;
import io.github.moulberry.notenoughupdates.util.HypixelApi;
+import io.github.moulberry.notenoughupdates.util.ItemResolutionQuery;
+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;
@@ -677,82 +679,18 @@ public class NEUManager {
return null;
}
+ /**
+ * Replaced with {@link #createItemResolutionQuery()}
+ */
+ @Deprecated
public String getInternalnameFromNBT(NBTTagCompound tag) {
- String internalname = null;
- if (tag != null && tag.hasKey("ExtraAttributes", 10)) {
- NBTTagCompound ea = tag.getCompoundTag("ExtraAttributes");
-
- if (ea.hasKey("id", 8)) {
- internalname = ea.getString("id").replaceAll(":", "-");
- } else {
- return null;
- }
-
- if ("PET".equals(internalname)) {
- String petInfo = ea.getString("petInfo");
- if (petInfo.length() > 0) {
- JsonObject petInfoObject = gson.fromJson(petInfo, JsonObject.class);
- internalname = petInfoObject.get("type").getAsString();
- String tier = petInfoObject.get("tier").getAsString();
- switch (tier) {
- case "COMMON":
- internalname += ";0";
- break;
- case "UNCOMMON":
- internalname += ";1";
- break;
- case "RARE":
- internalname += ";2";
- break;
- case "EPIC":
- internalname += ";3";
- break;
- case "LEGENDARY":
- internalname += ";4";
- break;
- case "MYTHIC":
- internalname += ";5";
- break;
- }
- }
- }
- if ("ENCHANTED_BOOK".equals(internalname) && ea.hasKey("enchantments", 10)) {
- NBTTagCompound enchants = ea.getCompoundTag("enchantments");
-
- for (String enchname : enchants.getKeySet()) {
- internalname = enchname.toUpperCase() + ";" + enchants.getInteger(enchname);
- break;
- }
- }
- if ("RUNE".equals(internalname) && ea.hasKey("runes", 10)) {
- NBTTagCompound rune = ea.getCompoundTag("runes");
-
- for (String runename : rune.getKeySet()) {
- internalname = runename.toUpperCase() + "_RUNE" + ";" + rune.getInteger(runename);
- break;
- }
- }
- if ("PARTY_HAT_CRAB".equals(internalname) && (ea.getString("party_hat_color") != null)) {
- String crabhat = ea.getString("party_hat_color");
- internalname = "PARTY_HAT_CRAB" + "_" + crabhat.toUpperCase();
- }
- }
-
- return internalname;
+ return createItemResolutionQuery()
+ .withItemNBT(tag)
+ .resolveInternalName();
}
public String[] getLoreFromNBT(NBTTagCompound tag) {
- String[] lore = new String[0];
- NBTTagCompound display = tag.getCompoundTag("display");
-
- if (display.hasKey("Lore", 9)) {
- NBTTagList list = display.getTagList("Lore", 8);
- lore = new String[list.tagCount()];
- for (int k = 0; k < list.tagCount(); k++) {
- lore[k] = list.getStringTagAt(k);
- }
- }
- return lore;
+ return ItemUtils.getLore(tag).toArray(new String[0]);
}
public JsonObject getJsonFromNBT(NBTTagCompound tag) {
@@ -912,10 +850,18 @@ public class NEUManager {
return getSkullValueFromNBT(tag);
}
+ public ItemResolutionQuery createItemResolutionQuery() {
+ return new ItemResolutionQuery(this);
+ }
+
+ /**
+ * Replaced with {@link #createItemResolutionQuery()}
+ */
+ @Deprecated
public String getInternalNameForItem(ItemStack stack) {
- if (stack == null) return null;
- NBTTagCompound tag = stack.getTagCompound();
- return getInternalnameFromNBT(tag);
+ return createItemResolutionQuery()
+ .withItemStack(stack)
+ .resolveInternalName();
}
public String getUUIDForItem(ItemStack stack) {
@@ -1572,10 +1518,14 @@ public class NEUManager {
return comp;
}
- public ItemStack createItem(String internalname) {
- JsonObject jsonObject = itemMap.get(internalname);
- if (jsonObject == null) return null;
- return jsonToStack(jsonObject);
+ public ItemStack createItem(String internalName) {
+ return createItemResolutionQuery()
+ .withKnownInternalName(internalName)
+ .resolveToItemStack();
+ }
+
+ public boolean isValidInternalName(String internalName) {
+ return itemMap.containsKey(internalName);
}
public String getDisplayName(String internalName) {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java
index 19f5a780..18be69e6 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java
@@ -1265,8 +1265,8 @@ public class NEUOverlay extends Gui {
String internal1 = o1.get("internalname").getAsString();
String internal2 = o2.get("internalname").getAsString();
- double cost1 = manager.auctionManager.getLowestBin(internal1);
- double cost2 = manager.auctionManager.getLowestBin(internal2);
+ double cost1 = manager.auctionManager.getBazaarOrBin(internal1);
+ double cost2 = manager.auctionManager.getBazaarOrBin(internal2);
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 3a2fa7ef..08f0552c 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java
@@ -29,7 +29,9 @@ import io.github.moulberry.notenoughupdates.cosmetics.CapeManager;
import io.github.moulberry.notenoughupdates.cosmetics.ShaderManager;
import io.github.moulberry.notenoughupdates.dungeons.DungeonMap;
import io.github.moulberry.notenoughupdates.listener.ChatListener;
+import io.github.moulberry.notenoughupdates.listener.ItemTooltipEssenceShopListener;
import io.github.moulberry.notenoughupdates.listener.ItemTooltipListener;
+import io.github.moulberry.notenoughupdates.listener.ItemTooltipRngListener;
import io.github.moulberry.notenoughupdates.listener.NEUEventListener;
import io.github.moulberry.notenoughupdates.listener.OldAnimationChecker;
import io.github.moulberry.notenoughupdates.listener.RenderListener;
@@ -284,6 +286,8 @@ public class NotEnoughUpdates {
MinecraftForge.EVENT_BUS.register(CustomBiomes.INSTANCE);
MinecraftForge.EVENT_BUS.register(new ChatListener(this));
MinecraftForge.EVENT_BUS.register(new ItemTooltipListener(this));
+ MinecraftForge.EVENT_BUS.register(new ItemTooltipRngListener(this));
+ MinecraftForge.EVENT_BUS.register(new ItemTooltipEssenceShopListener(this));
MinecraftForge.EVENT_BUS.register(new RenderListener(this));
MinecraftForge.EVENT_BUS.register(new OldAnimationChecker());
MinecraftForge.EVENT_BUS.register(new SignCalculator());
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 c3999fb6..2dc02b7e 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java
@@ -168,6 +168,7 @@ public class APIManager {
return stack;
} else {
JsonObject item = manager.getJsonFromNBT(item_tag);
+ if (item == null) return null;
ItemStack stack = manager.jsonToStack(item, false);
JsonObject itemDefault = manager.getItemInformation().get(item.get("internalname").getAsString());
@@ -806,9 +807,18 @@ public class APIManager {
return keys;
}
- public JsonObject getBazaarInfo(String internalname) {
+ public double getBazaarOrBin(String internalName) {
+ JsonObject bazaarInfo = manager.auctionManager.getBazaarInfo(internalName);
+ if (bazaarInfo != null && bazaarInfo.get("curr_buy") != null) {
+ return bazaarInfo.get("curr_buy").getAsFloat();
+ } else {
+ return manager.auctionManager.getLowestBin(internalName);
+ }
+ }
+
+ public JsonObject getBazaarInfo(String internalName) {
if (bazaarJson == null) return null;
- JsonElement e = bazaarJson.get(internalname);
+ JsonElement e = bazaarJson.get(internalName);
if (e == null) {
return null;
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/util/StringUtils.java b/src/main/java/io/github/moulberry/notenoughupdates/core/util/StringUtils.java
index 2b6f7fc7..7ea9cd00 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/core/util/StringUtils.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/core/util/StringUtils.java
@@ -67,6 +67,26 @@ public class StringUtils {
return Integer.parseInt(str);
}
+ public static String shortNumberFormat(double n) {
+ return shortNumberFormat(n, 0);
+ }
+
+ private static final char[] c = new char[] { 'k', 'm', 'b', 't' };
+
+ public static String shortNumberFormat(double n, int iteration) {
+ if (n < 1000) {
+ if (n % 1 == 0) {
+ return Integer.toString((int) n);
+ } else {
+ return String.format("%.2f", n);
+ }
+ }
+
+ double d = ((long) n / 100) / 10.0;
+ boolean isRound = (d * 10) % 10 == 0;
+ return d < 1000 ? (isRound || d > 9.99 ? (int) d * 10 / 10 : d + "") + "" + c[iteration] : shortNumberFormat(d, iteration + 1);
+ }
+
public static String urlEncode(String something) {
try {
return URLEncoder.encode(something, StandardCharsets.UTF_8.name());
@@ -75,6 +95,14 @@ public class StringUtils {
}
}
+ /**
+ * taken and modified from https://stackoverflow.com/a/23326014/5507634
+ */
+ public static String replaceLast(String string, String toReplace, String replacement) {
+ int start = string.lastIndexOf(toReplace);
+ return string.substring(0, start) + replacement + string.substring(start + toReplace.length());
+ }
+
public static String removeLastWord(String string, String splitString) {
try {
String[] split = string.split(splitString);
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/events/RepositoryReloadEvent.java b/src/main/java/io/github/moulberry/notenoughupdates/events/RepositoryReloadEvent.java
index bf6448a2..ab650c54 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/events/RepositoryReloadEvent.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/events/RepositoryReloadEvent.java
@@ -23,7 +23,7 @@ import java.io.File;
public class RepositoryReloadEvent extends NEUEvent {
private final File baseFile;
- private boolean isFirstLoad;
+ private final boolean isFirstLoad;
public RepositoryReloadEvent(File baseFile, boolean isFirstLoad) {
this.baseFile = baseFile;
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/itemeditor/NEUItemEditor.java b/src/main/java/io/github/moulberry/notenoughupdates/itemeditor/NEUItemEditor.java
index 9dc8d8b0..6a080ff8 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/itemeditor/NEUItemEditor.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/itemeditor/NEUItemEditor.java
@@ -93,19 +93,6 @@ public class NEUItemEditor extends GuiScreen {
extraAttributes.removeTag("uuid");
extraAttributes.removeTag("timestamp");
- if (extraAttributes.hasKey("petInfo")) {
- try {
- NBTTagCompound petInfo = JsonToNBT.getTagFromJson(extraAttributes.getString("petInfo"));
-
- petInfo.removeTag("\"heldItem\"");
- petInfo.setString("\"exp\"", "0.0");
- petInfo.setString("\"candyUsed\"", "0");
- petInfo.removeTag("\"uuid\"");
-
- extraAttributes.setString("petInfo", petInfo.toString());
- } catch (NBTException ignored) {
- }
- }
savedRepoItem = NotEnoughUpdates.INSTANCE.manager.getItemInformation().getOrDefault(internalName, null);
internalName = internalName == null ? "" : internalName;
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 ea7f2f5b..79b134a7 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/listener/ChatListener.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/listener/ChatListener.java
@@ -197,8 +197,8 @@ public class ChatListener {
timeSinceLastBoss2 = timeSinceLastBoss;
timeSinceLastBoss = System.currentTimeMillis();
}
- } else if (unformatted.startsWith(" RNGesus Meter:")) {
- RNGMeter = unformatted.substring(" RNGesus Meter: -------------------- ".length());
+ } else if (unformatted.startsWith(" RNG Meter")) {
+ RNGMeter = unformatted.substring(" RNG Meter - ".length());
} else if (matcher.matches()) {
//matcher.group(1);
SlayerOverlay.slayerLVL = matcher.group(2);
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/listener/ItemTooltipEssenceShopListener.java b/src/main/java/io/github/moulberry/notenoughupdates/listener/ItemTooltipEssenceShopListener.java
new file mode 100644
index 00000000..4b380c2f
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/listener/ItemTooltipEssenceShopListener.java
@@ -0,0 +1,84 @@
+/*
+ * 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.listener;
+
+import com.google.gson.JsonObject;
+import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.core.util.StringUtils;
+import io.github.moulberry.notenoughupdates.util.Utils;
+import net.minecraftforge.event.entity.player.ItemTooltipEvent;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class ItemTooltipEssenceShopListener {
+ private final NotEnoughUpdates neu;
+
+ private final Pattern ESSENCE_PATTERN = Pattern.compile("§5§o§d([\\d,]+) (.+) Essence");
+
+ public ItemTooltipEssenceShopListener(NotEnoughUpdates neu) {
+ this.neu = neu;
+ }
+
+ @SubscribeEvent
+ public void onItemTooltip(ItemTooltipEvent event) {
+ if (!neu.isOnSkyblock()) return;
+ if (event.toolTip == null) return;
+ if (!Utils.getOpenChestName().endsWith(" Essence Shop")) return;
+ if (!NotEnoughUpdates.INSTANCE.config.tooltipTweaks.essencePriceInEssenceShop) return;
+
+ List<String> newToolTip = new ArrayList<>();
+ boolean next = false;
+ for (String line : event.toolTip) {
+
+ if (next) {
+ next = false;
+ Matcher matcher = ESSENCE_PATTERN.matcher(line);
+ if (matcher.matches()) {
+ String rawNumber = matcher.group(1).replace(",", "");
+ int amount = Integer.parseInt(rawNumber);
+ String type = matcher.group(2);
+
+ String essenceName = "ESSENCE_" + type.toUpperCase();
+ JsonObject bazaarInfo = neu.manager.auctionManager.getBazaarInfo(essenceName);
+
+ if (bazaarInfo != null && bazaarInfo.has("curr_sell")) {
+ float bazaarPrice = bazaarInfo.get("curr_sell").getAsFloat();
+ double price = bazaarPrice * amount;
+ String format = StringUtils.shortNumberFormat(price);
+ newToolTip.add(line + " §7(§6" + format + " coins§7)");
+ continue;
+ }
+ }
+ }
+
+ if (line.contains("Cost")) {
+ next = true;
+ }
+ newToolTip.add(line);
+ }
+
+ event.toolTip.clear();
+ event.toolTip.addAll(newToolTip);
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/listener/ItemTooltipListener.java b/src/main/java/io/github/moulberry/notenoughupdates/listener/ItemTooltipListener.java
index f3ed8e7c..3936ad74 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/listener/ItemTooltipListener.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/listener/ItemTooltipListener.java
@@ -28,6 +28,7 @@ import com.mojang.authlib.minecraft.MinecraftProfileTexture;
import io.github.moulberry.notenoughupdates.ItemPriceInformation;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
import io.github.moulberry.notenoughupdates.core.util.MiscUtils;
+import io.github.moulberry.notenoughupdates.core.util.StringUtils;
import io.github.moulberry.notenoughupdates.miscfeatures.PetInfoOverlay;
import io.github.moulberry.notenoughupdates.miscgui.GuiEnchantColour;
import io.github.moulberry.notenoughupdates.profileviewer.GuiProfileViewer;
@@ -42,7 +43,6 @@ import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.nbt.NBTUtil;
import net.minecraft.util.EnumChatFormatting;
-import net.minecraft.util.StringUtils;
import net.minecraftforge.event.entity.player.ItemTooltipEvent;
import net.minecraftforge.fml.common.Loader;
import net.minecraftforge.fml.common.eventhandler.EventPriority;
@@ -104,8 +104,13 @@ public class ItemTooltipListener {
public void onItemTooltipLow(ItemTooltipEvent event) {
if (!NotEnoughUpdates.INSTANCE.isOnSkyblock()) return;
- String internalname = NotEnoughUpdates.INSTANCE.manager.getInternalNameForItem(event.itemStack);
- if (internalname == null) {
+ String internalName = NotEnoughUpdates.INSTANCE.manager
+ .createItemResolutionQuery()
+ .withCurrentGuiContext()
+ .withItemStack(event.itemStack)
+ .resolveInternalName();
+
+ if (internalName == null) {
return;
}
petToolTipXPExtendPetMenu(event);
@@ -155,7 +160,8 @@ public class ItemTooltipListener {
for (int j = 0; j < Utils.rarityArrC.length; j++) {
for (Map.Entry<String, JsonElement> entry : enchantsObj.entrySet()) {
if (line.contains(Utils.rarityArrC[j] + " " + entry.getKey()) || line.contains(
- Utils.rarityArrC[j] + " DUNGEON " + entry.getKey()) || line.contains("SHINY " + Utils.rarityArrC[j].replaceAll("§.§.","") + " DUNGEON " + entry.getKey())) {
+ Utils.rarityArrC[j] + " DUNGEON " + entry.getKey()) || line.contains(
+ "SHINY " + Utils.rarityArrC[j].replaceAll("§.§.", "") + " DUNGEON " + entry.getKey())) {
allItemEnchs = entry.getValue().getAsJsonArray();
break out;
}
@@ -180,7 +186,7 @@ public class ItemTooltipListener {
NotEnoughUpdates.INSTANCE.config.tooltipTweaks.showReforgeStats) {
JsonObject reforgeStones = Constants.REFORGESTONES;
- if (reforgeStones != null && reforgeStones.has(internalname)) {
+ if (reforgeStones != null && reforgeStones.has(internalName)) {
boolean shift = Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown(Keyboard.KEY_RSHIFT);
if (!pressedShiftLast && shift) {
showReforgeStoneStats = !showReforgeStoneStats;
@@ -195,7 +201,7 @@ public class ItemTooltipListener {
newTooltip.add(EnumChatFormatting.DARK_GRAY + "[Press SHIFT to hide extra info]");
}
- JsonObject reforgeInfo = reforgeStones.get(internalname).getAsJsonObject();
+ JsonObject reforgeInfo = reforgeStones.get(internalName).getAsJsonObject();
JsonArray requiredRaritiesArray = reforgeInfo.get("requiredRarities").getAsJsonArray();
if (showReforgeStoneStats && requiredRaritiesArray.size() > 0) {
@@ -260,8 +266,7 @@ public class ItemTooltipListener {
newTooltip.add("");
}
- newTooltip.add(EnumChatFormatting.BLUE + "Stats for " + rarityFormatted +
- "\u00a79: [\u00a7l\u00a7m< \u00a79Switch\u00a7l\u27a1\u00a79]");
+ newTooltip.add(EnumChatFormatting.BLUE + "Stats for " + rarityFormatted + "§9: [§l§m< §9Switch§l➡§9]");
if (statsE != null && statsE.isJsonObject()) {
JsonObject stats = statsE.getAsJsonObject();
@@ -526,7 +531,7 @@ public class ItemTooltipListener {
newTooltip.add("");
newTooltip.add(EnumChatFormatting.GRAY + "[SHIFT for Price Info]");
} else {
- ItemPriceInformation.addToTooltip(newTooltip, internalname, event.itemStack);
+ ItemPriceInformation.addToTooltip(newTooltip, internalName, event.itemStack);
}
}
}
@@ -583,9 +588,10 @@ public class ItemTooltipListener {
JsonObject auctionInfo = neu.manager.auctionManager.getItemAuctionInfo(internal);
if (auctionInfo != null) {
if (auctionInfo.has("clean_price")) {
- worth = (long)auctionInfo.get("clean_price").getAsDouble();
+ worth = (long) auctionInfo.get("clean_price").getAsDouble();
} else {
- worth = (long) (auctionInfo.get("price").getAsDouble() / auctionInfo.get("count").getAsDouble());
+ worth =
+ (long) (auctionInfo.get("price").getAsDouble() / auctionInfo.get("count").getAsDouble());
}
}
break;
@@ -703,7 +709,7 @@ public class ItemTooltipListener {
event.toolTip.addAll(newTooltip);
if (NotEnoughUpdates.INSTANCE.config.tooltipTweaks.showPriceInfoInvItem) {
- ItemPriceInformation.addToTooltip(event.toolTip, internalname, event.itemStack);
+ ItemPriceInformation.addToTooltip(event.toolTip, internalName, event.itemStack);
}
if (event.itemStack.getTagCompound() != null && event.itemStack.getTagCompound().getBoolean("NEUHIDEPETTOOLTIP") &&
@@ -824,14 +830,14 @@ public class ItemTooltipListener {
if (event.toolTip == null) return;
if (event.toolTip.size() > 2 && NotEnoughUpdates.INSTANCE.config.tooltipTweaks.hideDefaultReforgeStats) {
- String secondLine = StringUtils.stripControlCodes(event.toolTip.get(1));
+ String secondLine = StringUtils.cleanColour(event.toolTip.get(1));
if (secondLine.equals("Reforge Stone")) {
Integer startIndex = null;
Integer cutoffIndex = null;
//loop from the back of the List to find the wanted index sooner
for (int i = event.toolTip.size() - 1; i >= 0; i--) {
//rarity or mining level requirement
- String line = StringUtils.stripControlCodes(event.toolTip.get(i));
+ String line = StringUtils.cleanColour(event.toolTip.get(i));
if (line.contains("REFORGE STONE") || line.contains("Requires Mining Skill Level")) {
cutoffIndex = i;
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/listener/ItemTooltipRngListener.java b/src/main/java/io/github/moulberry/notenoughupdates/listener/ItemTooltipRngListener.java
new file mode 100644
index 00000000..bbbb9049
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/listener/ItemTooltipRngListener.java
@@ -0,0 +1,330 @@
+/*
+ * 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.listener;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.core.util.StringUtils;
+import io.github.moulberry.notenoughupdates.events.RepositoryReloadEvent;
+import io.github.moulberry.notenoughupdates.profileviewer.GuiProfileViewer;
+import io.github.moulberry.notenoughupdates.util.Calculator;
+import io.github.moulberry.notenoughupdates.util.Constants;
+import io.github.moulberry.notenoughupdates.util.Utils;
+import net.minecraft.item.ItemStack;
+import net.minecraftforge.event.entity.player.ItemTooltipEvent;
+import net.minecraftforge.fml.common.eventhandler.EventPriority;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+import org.lwjgl.input.Keyboard;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class ItemTooltipRngListener {
+ private final NotEnoughUpdates neu;
+ private boolean showSlayerRngFractions = false;
+ private boolean pressedShiftLast = false;
+ private int currentSelected = 0;
+ private boolean pressedArrowLast = false;
+ private boolean repoReloadNeeded = true;
+
+ private final Pattern ODDS_PATTERN = Pattern.compile("§5§o§7Odds: (.+) §7\\(§7(.*)%\\)");
+ private final Pattern ODDS_SELECTED_PATTERN = Pattern.compile("§5§o§7Odds: (.+) §7\\(§8§m(.*)%§r §7(.+)%\\)");
+
+ private final Pattern RUNS_PATTERN = Pattern.compile("§5§o§7(Dungeon Score|Slayer XP): §d(.*)§5/§d(.+)");
+ private final Pattern RUNS_SELECTED_PATTERN = Pattern.compile("§5§o§d-(.+)- §d(.*)§5/§d(.+)");
+
+ private final Pattern SLAYER_INVENTORY_TITLE_PATTERN = Pattern.compile("(.+) RNG Meter");
+
+ private final Map<String, Integer> dungeonData = new LinkedHashMap<>();
+ private final Map<String, LinkedHashMap<String, Integer>> slayerData = new LinkedHashMap<>();
+
+ public ItemTooltipRngListener(NotEnoughUpdates neu) {
+ this.neu = neu;
+ }
+
+ @SubscribeEvent
+ public void onItemTooltip(ItemTooltipEvent event) {
+ if (!neu.isOnSkyblock()) return;
+ if (event.toolTip == null) return;
+ if (!Utils.getOpenChestName().endsWith(" RNG Meter") && !slayerData.containsKey(Utils.getOpenChestName())) return;
+
+ List<String> newToolTip = new ArrayList<>();
+
+ boolean nextLineProgress = false;
+ for (String line : event.toolTip) {
+
+ if (line.contains("Odds:")) {
+ if (NotEnoughUpdates.INSTANCE.config.tooltipTweaks.rngMeterFractionDisplay) {
+ fractionDisplay(newToolTip, line);
+ continue;
+ }
+ }
+
+ if (nextLineProgress || line.contains("Dungeon Score:") || line.contains("Slayer XP:")) {
+ Matcher matcher = RUNS_PATTERN.matcher(line);
+ Matcher matcherSelected = RUNS_SELECTED_PATTERN.matcher(line);
+ Matcher m = null;
+ if (matcher.matches()) {
+ m = matcher;
+ } else if (matcherSelected.matches()) {
+ m = matcherSelected;
+ }
+
+ if (m != null) {
+ int having;
+ try {
+ having = Calculator.calculate(m.group(2).replace(",", "")).intValue();
+ } catch (Calculator.CalculatorException e) {
+ having = -1;
+ }
+
+ int needed;
+ try {
+ needed = Calculator.calculate(m.group(3).replace(",", "")).intValue();
+ } catch (Calculator.CalculatorException e) {
+ needed = -1;
+ }
+ if (NotEnoughUpdates.INSTANCE.config.tooltipTweaks.rngMeterRunsNeeded) {
+ runsRequired(newToolTip, having, needed, nextLineProgress, event.itemStack);
+ }
+
+ if (NotEnoughUpdates.INSTANCE.config.tooltipTweaks.rngMeterProfitPerUnit) {
+ if (!NotEnoughUpdates.INSTANCE.config.tooltipTweaks.rngMeterRunsNeeded) {
+ String name = Utils.getOpenChestName().contains("Catacombs") ? "Score" : "XP";
+ String formatCoinsPer = getFormatCoinsPer(event.itemStack, needed, 1, name);
+ if (formatCoinsPer != null) {
+ newToolTip.add(line);
+ newToolTip.add(formatCoinsPer);
+ continue;
+ }
+ }
+ }
+ }
+ nextLineProgress = false;
+ }
+
+ if (line.contains("Progress:")) {
+ nextLineProgress = true;
+ }
+ newToolTip.add(line);
+ }
+
+ event.toolTip.clear();
+ event.toolTip.addAll(newToolTip);
+ }
+
+ private String getFormatCoinsPer(ItemStack stack, int needed, int multiplier, String name) {
+ String internalName = neu.manager.getInternalNameForItem(stack);
+ double bin = neu.manager.auctionManager.getBazaarOrBin(internalName);
+ if (bin <= 0) return null;
+
+ double coinsPer = (bin / needed) * multiplier;
+ String format = StringUtils.shortNumberFormat(coinsPer);
+ return "§7Coins per " + name + ": §6" + format + " coins";
+ }
+
+ private void fractionDisplay(List<String> newToolTip, String line) {
+ boolean shift = Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown(Keyboard.KEY_RSHIFT);
+ if (!pressedShiftLast && shift) {
+ showSlayerRngFractions = !showSlayerRngFractions;
+ }
+ pressedShiftLast = shift;
+
+ String result;
+ Matcher matcher = ODDS_PATTERN.matcher(line);
+ Matcher matcherSelected = ODDS_SELECTED_PATTERN.matcher(line);
+ if (matcher.matches()) {
+ String odds = matcher.group(1);
+ int baseChance = calculateChance(matcher.group(2));
+ String baseFormat = GuiProfileViewer.numberFormat.format(baseChance);
+
+ String fractionFormat = "§7(1/" + baseFormat + ")";
+ result = odds + " " + fractionFormat;
+ } else if (matcherSelected.matches()) {
+ String odds = matcherSelected.group(1);
+ int baseChance = calculateChance(matcherSelected.group(2));
+ String baseFormat = GuiProfileViewer.numberFormat.format(baseChance);
+
+ int increasedChance = calculateChance(matcherSelected.group(3));
+ String increased = GuiProfileViewer.numberFormat.format(increasedChance);
+ String fractionFormat = "§7(§8§m1/" + baseFormat + "§r §71/" + increased + ")";
+
+ result = odds + " " + fractionFormat;
+ } else {
+ return;
+ }
+
+ if (showSlayerRngFractions) {
+ newToolTip.add("§7Odds: " + result);
+ newToolTip.add("§8[Press SHIFT to show odds as percentages]");
+ } else {
+ newToolTip.add(line);
+ newToolTip.add("§8[Press SHIFT to show odds as fractions]");
+ }
+ }
+
+ /**
+ * This adds support for the /neureloadrepo command
+ */
+ @SubscribeEvent(priority = EventPriority.LOWEST)
+ public void onRepoReload(RepositoryReloadEvent event) {
+ repoReloadNeeded = true;
+ }
+
+ public void checkUpdateData() {
+ if (repoReloadNeeded) {
+ updateRepoData();
+ }
+ }
+
+ private void updateRepoData() {
+ slayerData.clear();
+ dungeonData.clear();
+
+ JsonObject leveling = Constants.LEVELING;
+ if (!leveling.has("slayer_boss_xp") ||
+ !leveling.has("slayer_highest_tier") ||
+ !leveling.has("slayer_tier_colors") ||
+ !leveling.has("rng_meter_dungeon_score")) {
+ Utils.showOutdatedRepoNotification();
+ return;
+ }
+
+ List<Integer> slayerExp = new ArrayList<>();
+ for (JsonElement element : leveling.get("slayer_boss_xp").getAsJsonArray()) {
+ slayerExp.add(element.getAsInt());
+ }
+
+ List<String> slayerColors = new ArrayList<>();
+ for (JsonElement element : leveling.get("slayer_tier_colors").getAsJsonArray()) {
+ slayerColors.add(element.getAsString());
+ }
+
+ for (Map.Entry<String, JsonElement> entry : leveling.get("slayer_highest_tier").getAsJsonObject().entrySet()) {
+ String slayerName = entry.getKey();
+ int maxTier = entry.getValue().getAsInt();
+ LinkedHashMap<String, Integer> singleSlayerData = new LinkedHashMap<>();
+ for (int i = 0; i < maxTier; i++) {
+ String name = slayerColors.get(i) + "Tier " + (i + 1);
+ singleSlayerData.put(name, slayerExp.get(i));
+ }
+ slayerData.put(slayerName, singleSlayerData);
+ }
+
+ for (Map.Entry<String, JsonElement> entry : leveling.get("rng_meter_dungeon_score").getAsJsonObject().entrySet()) {
+ String dungeonScore = entry.getKey();
+ int score = entry.getValue().getAsInt();
+ dungeonData.put(dungeonScore, score);
+ }
+
+ repoReloadNeeded = false;
+ }
+
+ private void runsRequired(
+ List<String> toolTip,
+ int having,
+ int needed,
+ boolean nextLineProgress,
+ ItemStack stack
+ ) {
+ checkUpdateData();
+ if (repoReloadNeeded) return;
+
+ String openChestName = Utils.getOpenChestName();
+ Map<String, Integer> runsData;
+ String labelPlural;
+ String labelSingular;
+ if (openChestName.contains("Catacombs")) {
+ runsData = dungeonData;
+ labelPlural = "Runs";
+ labelSingular = "Run";
+ } else { // Slayer
+ Matcher matcher = SLAYER_INVENTORY_TITLE_PATTERN.matcher(openChestName);
+ if (!matcher.matches()) {
+ //Happens for the first 4-5 ticks after inventory opens. Thanks hypixel
+ return;
+ }
+
+ String slayerName = matcher.group(1);
+ runsData = slayerData.get(slayerName);
+ labelPlural = "Bosses";
+ labelSingular = "Boss";
+ }
+
+ handleArrowKeys(runsData);
+
+ if (currentSelected >= runsData.keySet().size()) {
+ currentSelected = 0;
+ }
+
+ String name = (String) runsData.keySet().toArray()[currentSelected];
+ int gainPerRun = runsData.get(name);
+
+ int runsNeeded = needed / gainPerRun;
+ int runsHaving = having / gainPerRun;
+ String runsNeededFormat = GuiProfileViewer.numberFormat.format(runsNeeded);
+ String runsHavingFormat = GuiProfileViewer.numberFormat.format(runsHaving);
+
+ String progressString = null;
+ if (nextLineProgress) {
+ progressString = toolTip.remove(toolTip.size() - 1);
+ }
+
+ toolTip.add("§9Stats for " + name + "§9: [§l§m< §9Switch§l➡§9]");
+ toolTip.add(
+ " §7" + labelPlural + " completed: §e" + runsHavingFormat + " §7(of §e" + runsNeededFormat + " §7needed)");
+
+ if (NotEnoughUpdates.INSTANCE.config.tooltipTweaks.rngMeterProfitPerUnit) {
+ String formatCoinsPer = getFormatCoinsPer(stack, needed, gainPerRun, labelSingular);
+ if (formatCoinsPer != null) {
+ toolTip.add(" " + formatCoinsPer);
+ }
+ }
+
+ toolTip.add(" ");
+ if (progressString != null) {
+ toolTip.add(progressString);
+ }
+ }
+
+ private void handleArrowKeys(Map<String, Integer> runsData) {
+ boolean left = Keyboard.isKeyDown(Keyboard.KEY_LEFT);
+ boolean right = Keyboard.isKeyDown(Keyboard.KEY_RIGHT);
+ if (!pressedArrowLast && (left || right)) {
+ if (Utils.getOpenChestName().contains("Catacombs") ? right : left) {
+ currentSelected--;
+ } else {
+ currentSelected++;
+ }
+ if (currentSelected < 0) currentSelected = 0;
+ if (currentSelected >= runsData.size()) currentSelected = runsData.size() - 1;
+ }
+ pressedArrowLast = left || right;
+ }
+
+ private int calculateChance(String string) {
+ return (int) (100.0 / Double.parseDouble(string));
+ }
+}
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 7435d941..542c885a 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/listener/NEUEventListener.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/listener/NEUEventListener.java
@@ -37,6 +37,7 @@ import io.github.moulberry.notenoughupdates.miscgui.GuiCustomEnchant;
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.util.Constants;
import io.github.moulberry.notenoughupdates.util.NotificationHandler;
import io.github.moulberry.notenoughupdates.util.ProfileApiSyncer;
@@ -145,6 +146,17 @@ public class NEUEventListener {
}
}
+ //MiningOverlay and TimersOverlay need real tick speed
+ if (neu.hasSkyblockScoreboard()) {
+ for (TextOverlay overlay : OverlayManager.textOverlays) {
+ if (overlay instanceof TextTabOverlay) {
+ TextTabOverlay skillOverlay = (TextTabOverlay) overlay;
+ skillOverlay.realTick();
+ }
+ }
+ }
+
+
if (longUpdate) {
CrystalOverlay.tick();
FairySouls.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 bfe0cfd7..3cd42c4a 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/listener/RenderListener.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/listener/RenderListener.java
@@ -54,6 +54,7 @@ import io.github.moulberry.notenoughupdates.miscgui.minionhelper.MinionHelperMan
import io.github.moulberry.notenoughupdates.mixins.AccessorGuiContainer;
import io.github.moulberry.notenoughupdates.options.NEUConfig;
import io.github.moulberry.notenoughupdates.overlays.AuctionSearchOverlay;
+import io.github.moulberry.notenoughupdates.overlays.BazaarSearchOverlay;
import io.github.moulberry.notenoughupdates.overlays.OverlayManager;
import io.github.moulberry.notenoughupdates.overlays.RancherBootOverlay;
import io.github.moulberry.notenoughupdates.overlays.TextOverlay;
@@ -106,6 +107,8 @@ import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.ConcurrentModificationException;
@@ -117,6 +120,8 @@ import java.util.TreeMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import java.util.stream.Collectors;
import static io.github.moulberry.notenoughupdates.util.GuiTextures.dungeon_chest_worth;
@@ -142,6 +147,9 @@ 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;
@@ -416,6 +424,11 @@ public class RenderListener {
event.setCanceled(true);
return;
}
+ if (BazaarSearchOverlay.shouldReplace()) {
+ BazaarSearchOverlay.render();
+ event.setCanceled(true);
+ return;
+ }
if (RancherBootOverlay.shouldReplace()) {
RancherBootOverlay.render();
event.setCanceled(true);
@@ -744,7 +757,7 @@ public class RenderListener {
StringBuilder cost = new StringBuilder();
for (int i = 0; i < line6.length(); i++) {
char c = line6.charAt(i);
- if ("0123456789".indexOf(c) >= 0) {
+ if (Character.isDigit(c)) {
cost.append(c);
}
}
@@ -755,11 +768,25 @@ public class RenderListener {
}
String missingItem = null;
- int totalValue = 0;
+ double totalValue = 0;
HashMap<String, Double> itemValues = new HashMap<>();
for (int i = 0; i < 5; i++) {
ItemStack item = lower.getStackInSlot(11 + i);
String internal = neu.manager.getInternalNameForItem(item);
+ String displayName = item.getDisplayName();
+ Matcher matcher = ESSENCE_PATTERN.matcher(displayName);
+ if (neu.config.dungeons.useEssenceCostFromBazaar && matcher.matches()) {
+ String type = matcher.group(1).toUpperCase();
+ JsonObject bazaarInfo = neu.manager.auctionManager.getBazaarInfo("ESSENCE_" + type);
+ if (bazaarInfo != null && bazaarInfo.has("curr_sell")) {
+ float bazaarPrice = bazaarInfo.get("curr_sell").getAsFloat();
+ int amount = Integer.parseInt(matcher.group(2));
+ double price = bazaarPrice * amount;
+ itemValues.put(displayName, price);
+ totalValue += price;
+ }
+ continue;
+ }
if (internal != null) {
internal = internal.replace("\u00CD", "I").replace("\u0130", "I");
float bazaarPrice = -1;
@@ -799,9 +826,9 @@ public class RenderListener {
JsonObject auctionInfo = neu.manager.auctionManager.getItemAuctionInfo(internal);
if (auctionInfo != null) {
if (auctionInfo.has("clean_price")) {
- worth = (int) auctionInfo.get("clean_price").getAsFloat();
+ worth = auctionInfo.get("clean_price").getAsFloat();
} else {
- worth = (int) (auctionInfo.get("price").getAsFloat() / auctionInfo.get("count").getAsFloat());
+ worth = (auctionInfo.get("price").getAsFloat() / auctionInfo.get("count").getAsFloat());
}
}
}
@@ -842,18 +869,17 @@ public class RenderListener {
}
}
- NumberFormat format = NumberFormat.getInstance(Locale.US);
String valueStringBIN1;
String valueStringBIN2;
if (totalValue >= 0) {
valueStringBIN1 = EnumChatFormatting.YELLOW + "Value (BIN): ";
- valueStringBIN2 = EnumChatFormatting.GOLD + format.format(totalValue) + " coins";
+ valueStringBIN2 = EnumChatFormatting.GOLD + formatCoins(totalValue) + " coins";
} else {
valueStringBIN1 = EnumChatFormatting.YELLOW + "Can't find BIN: ";
valueStringBIN2 = missingItem;
}
- long profitLossBIN = totalValue - chestCost;
+ double profitLossBIN = totalValue - chestCost;
boolean kismetUsed = false;
// checking for kismet
@@ -867,8 +893,8 @@ public class RenderListener {
}
}
}
- long kismetPrice = neu.manager.auctionManager.getLowestBin("KISMET_FEATHER");
- String kismetStr = EnumChatFormatting.RED + format.format(kismetPrice) + " coins";
+ double kismetPrice = neu.manager.auctionManager.getLowestBin("KISMET_FEATHER");
+ String kismetStr = EnumChatFormatting.RED + formatCoins(kismetPrice) + " coins";
if (neu.config.dungeons.useKismetOnDungeonProfit)
profitLossBIN = kismetUsed ? profitLossBIN - kismetPrice : profitLossBIN;
@@ -878,9 +904,9 @@ public class RenderListener {
String plStringBIN;
if (profitLossBIN >= 0) {
- plStringBIN = prefix + "+" + format.format(profitLossBIN) + " coins";
+ plStringBIN = prefix + "+" + formatCoins(profitLossBIN) + " coins";
} else {
- plStringBIN = prefix + "-" + format.format(-profitLossBIN) + " coins";
+ plStringBIN = prefix + "-" + formatCoins(-profitLossBIN) + " coins";
}
if (NotEnoughUpdates.INSTANCE.config.dungeons.profitDisplayLoc == 1 && !valueStringBIN2.equals(missingItem)) {
@@ -927,7 +953,7 @@ public class RenderListener {
for (Map.Entry<String, Double> entry : itemValues.entrySet()) {
Utils.renderAlignedString(
entry.getKey(),
- prefix + format.format(entry.getValue().longValue()),
+ prefix + formatCoins(entry.getValue().doubleValue()),
guiLeft + xSize + 4 + 10,
guiTop + (neu.config.dungeons.useKismetOnDungeonProfit ? (kismetUsed ? 39 : 29) : 29) + (++index) * 10,
160
@@ -955,6 +981,10 @@ public class RenderListener {
}
}
+ private String formatCoins(double price) {
+ return format.format(price < 5 ? price : (long) price);
+ }
+
/**
* Sends a mouse event to NEUOverlay if the inventory isn't hovered AND focused.
* Will also cancel the event if if NEUOverlay#mouseInput returns true.
@@ -991,6 +1021,11 @@ public class RenderListener {
event.setCanceled(true);
return;
}
+ if (BazaarSearchOverlay.shouldReplace()) {
+ BazaarSearchOverlay.mouseEvent();
+ event.setCanceled(true);
+ return;
+ }
if (RancherBootOverlay.shouldReplace()) {
RancherBootOverlay.mouseEvent();
event.setCanceled(true);
@@ -1471,6 +1506,11 @@ public class RenderListener {
event.setCanceled(true);
return;
}
+ if (BazaarSearchOverlay.shouldReplace()) {
+ BazaarSearchOverlay.keyEvent();
+ event.setCanceled(true);
+ return;
+ }
if (RancherBootOverlay.shouldReplace()) {
RancherBootOverlay.keyEvent();
event.setCanceled(true);
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AuctionProfit.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AuctionProfit.java
index e1024eab..88ca0cc8 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AuctionProfit.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AuctionProfit.java
@@ -20,8 +20,8 @@
package io.github.moulberry.notenoughupdates.miscfeatures;
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.profileviewer.GuiProfileViewer;
import io.github.moulberry.notenoughupdates.util.Utils;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
@@ -145,10 +145,10 @@ public class AuctionProfit {
String coinsToCollectStr =
EnumChatFormatting.BOLD + EnumChatFormatting.DARK_GRAY.toString() + "Coins to collect: " +
EnumChatFormatting.RESET + EnumChatFormatting.DARK_GREEN + "" +
- GuiProfileViewer.shortNumberFormat(coinsToCollect, 0);
+ StringUtils.shortNumberFormat(coinsToCollect);
String valueIfSoldStr = EnumChatFormatting.BOLD + EnumChatFormatting.DARK_GRAY.toString() + "Value if all sold: " +
EnumChatFormatting.RESET + EnumChatFormatting.DARK_GREEN + "" +
- GuiProfileViewer.shortNumberFormat(coinsIfAllSold, 0);
+ StringUtils.shortNumberFormat(coinsIfAllSold);
fontRendererObj.drawString(coinsToCollectStr, a + 6, guiTop + 32, -1, false);
fontRendererObj.drawString(valueIfSoldStr, a + 6, guiTop + 42, -1, false);
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/BazaarSacksProfit.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/BazaarSacksProfit.java
index 084fd03f..7007f39b 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/BazaarSacksProfit.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/BazaarSacksProfit.java
@@ -68,7 +68,7 @@ public class BazaarSacksProfit {
@SubscribeEvent(priority = EventPriority.LOW)
public void onItemTooltipLow(ItemTooltipEvent event) {
- if (!NotEnoughUpdates.INSTANCE.config.tooltipTweaks.bazaarSacksProfit) return;
+ if (!NotEnoughUpdates.INSTANCE.config.bazaarTweaks.bazaarSacksProfit) return;
if (!inBazaar()) return;
ItemStack itemStack = event.itemStack;
@@ -89,6 +89,11 @@ public class BazaarSacksProfit {
out:
for (String line : ItemUtils.getLore(itemStack)) {
+
+ if (line.equals("§8Loading...")) {
+ dirty = true;
+ return;
+ }
if (line.contains("§7x ")) {
String[] split = line.split("§7x ");
String rawAmount = StringUtils.cleanColour(split[0]).replace(",", "").substring(1);
@@ -108,7 +113,7 @@ public class BazaarSacksProfit {
}
}
}
- System.out.println("no bazaar item in repo found for '" + bazaarName + "'");
+ System.err.println("no bazaar item in repo found for '" + bazaarName + "'");
invalidNames.add(bazaarName);
}
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DamageCommas.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DamageCommas.java
index 127edcde..b1ab11c1 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DamageCommas.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DamageCommas.java
@@ -45,15 +45,18 @@ public class DamageCommas {
};
private static final char STAR = '\u2727';
+ private static final char OVERLOAD_STAR = '\u272F';
private static final Pattern PATTERN_CRIT = Pattern.compile(
- "\u00a7f" + STAR + "((?:\u00a7.\\d)+)\u00a7." + STAR + "(.*)");
- private static final Pattern PATTERN_NO_CRIT = Pattern.compile("\u00a77(\\d+)(.*)");
+ "\u00a7f" + STAR + "((?:\u00a7.\\d(?:§.,)?)+)\u00a7." + STAR + "(.*)");
+ private static final Pattern PATTERN_NO_CRIT = Pattern.compile("(\u00a7.)([\\d+,]*)(.*)");
+ private static final Pattern OVERLOAD_PATTERN = Pattern.compile("(\u00a7.)" + OVERLOAD_STAR + "((?:\u00a7.[\\d,])+)(\u00a7.)" + OVERLOAD_STAR + "\u00a7r");
public static IChatComponent replaceName(EntityLivingBase entity) {
if (!entity.hasCustomName()) return entity.getDisplayName();
IChatComponent name = entity.getDisplayName();
- if (NotEnoughUpdates.INSTANCE.config.misc.damageIndicatorStyle == 0) return name;
+ if (!NotEnoughUpdates.INSTANCE.config.misc.damageIndicatorStyle2) return name;
+ if (!NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) return name;
if (replacementMap.containsKey(entity)) {
ChatComponentText component = replacementMap.get(entity);
@@ -69,17 +72,23 @@ public class DamageCommas {
String suffix;
Matcher matcherCrit = PATTERN_CRIT.matcher(formatted);
+ Matcher matcherOverload = OVERLOAD_PATTERN.matcher(formatted);
if (matcherCrit.matches()) {
crit = true;
- numbers = StringUtils.cleanColour(matcherCrit.group(1));
+ numbers = StringUtils.cleanColour(matcherCrit.group(1)).replace(",", "");
prefix = "\u00a7f" + STAR;
suffix = "\u00a7f" + STAR + matcherCrit.group(2);
- } else {
+ } else if (matcherOverload.matches()) {
+ crit = true;
+ numbers = StringUtils.cleanColour(matcherOverload.group(2)).replace(",", "");
+ prefix = matcherOverload.group(1) + OVERLOAD_STAR;
+ suffix = matcherOverload.group(3) + OVERLOAD_STAR + "\u00a7r";
+ } else {
Matcher matcherNoCrit = PATTERN_NO_CRIT.matcher(formatted);
if (matcherNoCrit.matches()) {
- numbers = matcherNoCrit.group(1);
- prefix = "\u00A77";
- suffix = "\u00A7r" + matcherNoCrit.group(2);
+ numbers = matcherNoCrit.group(2).replace(",", "");
+ prefix = matcherNoCrit.group(1);
+ suffix = "\u00A7r" + matcherNoCrit.group(3);
} else {
replacementMap.put(entity, null);
return name;
@@ -91,10 +100,10 @@ public class DamageCommas {
try {
int number = Integer.parseInt(numbers);
- if (number > 999 && NotEnoughUpdates.INSTANCE.config.misc.damageIndicatorStyle == 2) {
+ if (number > 999) {
newFormatted.append(Utils.shortNumberFormat(number, 0));
} else {
- newFormatted.append(NumberFormat.getIntegerInstance().format(number));
+ return name;
}
} catch (NumberFormatException e) {
replacementMap.put(entity, null);
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/EnchantingSolvers.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/EnchantingSolvers.java
index 6b541256..558917fe 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/EnchantingSolvers.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/EnchantingSolvers.java
@@ -45,9 +45,9 @@ import java.util.List;
import java.util.Map;
public class EnchantingSolvers {
- private static SolverType currentSolver = SolverType.NONE;
+ public static SolverType currentSolver = SolverType.NONE;
- private enum SolverType {
+ public enum SolverType {
NONE,
CHRONOMATRON,
ULTRASEQUENCER,
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/AccessoryBagOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/AccessoryBagOverlay.java
index b6c3e763..530dcfd1 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/AccessoryBagOverlay.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/AccessoryBagOverlay.java
@@ -847,7 +847,7 @@ public class AccessoryBagOverlay {
if (info != null)
cost1 = info.craftCost;
else
- cost1 = 0;
+ cost1 = -1;
}
double cost2;
JsonObject o2Auc = NotEnoughUpdates.INSTANCE.manager.auctionManager.getItemAuctionInfo(o2);
@@ -858,7 +858,7 @@ public class AccessoryBagOverlay {
if (info != null)
cost2 = info.craftCost;
else
- cost2 = 0;
+ cost2 = -1;
}
if (cost1 == -1 && cost2 == -1) return o1.compareTo(o2);
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/TrophyRewardOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/TrophyRewardOverlay.java
index 540a6dee..828e50b1 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/TrophyRewardOverlay.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/TrophyRewardOverlay.java
@@ -70,7 +70,7 @@ public class TrophyRewardOverlay {
* This adds support for the /neureloadrepo command
*/
@SubscribeEvent(priority = EventPriority.LOWEST)
- public void reload(RepositoryReloadEvent event) {
+ public void onRepoReload(RepositoryReloadEvent event) {
reloadNeeded = true;
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiContainer.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiContainer.java
index 06512fa8..7c3414fa 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiContainer.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiContainer.java
@@ -125,7 +125,7 @@ public abstract class MixinGuiContainer extends GuiScreen {
else if (!($this instanceof GuiChest))
BetterContainers.profileViewerStackIndex = -1;
- if (slot.getStack() == null && NotEnoughUpdates.INSTANCE.overlay.searchMode && RenderListener.drawingGuiScreen) {
+ if (slot.getStack() == null && NotEnoughUpdates.INSTANCE.overlay.searchMode && RenderListener.drawingGuiScreen && NotEnoughUpdates.INSTANCE.isOnSkyblock()) {
GlStateManager.pushMatrix();
GlStateManager.translate(0, 0, 100 + Minecraft.getMinecraft().getRenderItem().zLevel);
GlStateManager.depthMask(false);
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinRenderItem.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinRenderItem.java
index 4f193c98..dc59c0bb 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinRenderItem.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinRenderItem.java
@@ -195,7 +195,7 @@ public abstract class MixinRenderItem {
@Inject(method = "renderItemIntoGUI", at = @At("HEAD"))
public void renderItemHead(ItemStack stack, int x, int y, CallbackInfo ci) {
- if (NotEnoughUpdates.INSTANCE.overlay.searchMode && RenderListener.drawingGuiScreen) {
+ if (NotEnoughUpdates.INSTANCE.overlay.searchMode && RenderListener.drawingGuiScreen && NotEnoughUpdates.INSTANCE.isOnSkyblock()) {
boolean matches = false;
GuiTextField textField = NotEnoughUpdates.INSTANCE.overlay.getTextField();
@@ -221,7 +221,7 @@ public abstract class MixinRenderItem {
@Inject(method = "renderItemIntoGUI", at = @At("RETURN"))
public void renderItemReturn(ItemStack stack, int x, int y, CallbackInfo ci) {
if (stack != null && stack.stackSize != 1) return;
- if (NotEnoughUpdates.INSTANCE.overlay.searchMode && RenderListener.drawingGuiScreen) {
+ if (NotEnoughUpdates.INSTANCE.overlay.searchMode && RenderListener.drawingGuiScreen && NotEnoughUpdates.INSTANCE.isOnSkyblock()) {
boolean matches = false;
GuiTextField textField = NotEnoughUpdates.INSTANCE.overlay.getTextField();
@@ -252,7 +252,7 @@ public abstract class MixinRenderItem {
CallbackInfo ci
) {
if (stack != null && stack.stackSize != 1) {
- if (NotEnoughUpdates.INSTANCE.overlay.searchMode && RenderListener.drawingGuiScreen) {
+ if (NotEnoughUpdates.INSTANCE.overlay.searchMode && RenderListener.drawingGuiScreen && NotEnoughUpdates.INSTANCE.isOnSkyblock()) {
boolean matches = false;
GuiTextField textField = NotEnoughUpdates.INSTANCE.overlay.getTextField();
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinSkyclientCosmetics.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinSkyclientCosmetics.java
new file mode 100644
index 00000000..32c9f418
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinSkyclientCosmetics.java
@@ -0,0 +1,39 @@
+/*
+ * 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.mixins;
+
+import net.minecraftforge.event.world.WorldEvent;
+import org.spongepowered.asm.mixin.Dynamic;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Pseudo;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+
+@Pseudo
+@Mixin(targets = "co.skyclient.scc.SkyclientCosmetics")
+public class MixinSkyclientCosmetics {
+
+ @Dynamic
+ @Inject(method = "onWorldLoad", at = @At("HEAD"), cancellable = true, remap = false)
+ public void onWorldLoad(WorldEvent.Load event, CallbackInfo ci) {
+ ci.cancel();
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java b/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java
index bb2ae6ba..808de00b 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java
@@ -37,6 +37,7 @@ import io.github.moulberry.notenoughupdates.options.seperateSections.AHGraph;
import io.github.moulberry.notenoughupdates.options.seperateSections.AHTweaks;
import io.github.moulberry.notenoughupdates.options.seperateSections.AccessoryBag;
import io.github.moulberry.notenoughupdates.options.seperateSections.ApiData;
+import io.github.moulberry.notenoughupdates.options.seperateSections.BazaarTweaks;
import io.github.moulberry.notenoughupdates.options.seperateSections.Calendar;
import io.github.moulberry.notenoughupdates.options.seperateSections.CustomArmour;
import io.github.moulberry.notenoughupdates.options.seperateSections.DungeonMapConfig;
@@ -372,6 +373,13 @@ public class NEUConfig extends Config {
@Expose
@Category(
+ name = "Bazaar Tweaks",
+ desc = "Tweaks for the Bazaar"
+ )
+ public BazaarTweaks bazaarTweaks = new BazaarTweaks();
+
+ @Expose
+ @Category(
name = "AH/BZ Graph",
desc = "Graph of auction and bazaar prices"
)
@@ -453,6 +461,8 @@ public class NEUConfig extends Config {
@Expose
public ArrayList<String> previousAuctionSearches = new ArrayList<>();
@Expose
+ public ArrayList<String> previousBazaarSearches = new ArrayList<>();
+ @Expose
public ArrayList<String> eventFavourites = new ArrayList<>();
@Expose
public ArrayList<String> quickCommands = createDefaultQuickCommands();
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/BazaarTweaks.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/BazaarTweaks.java
new file mode 100644
index 00000000..2ba0b718
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/BazaarTweaks.java
@@ -0,0 +1,81 @@
+/*
+ * 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.options.seperateSections;
+
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigAccordionId;
+import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditorAccordion;
+import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditorBoolean;
+import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigOption;
+
+public class BazaarTweaks {
+
+ @ConfigOption(
+ name = "Search GUI",
+ desc = ""
+ )
+ @ConfigEditorAccordion(id = 0)
+ public boolean searchAccordion = false;
+
+ @Expose
+ @ConfigOption(
+ name = "Enable Search GUI",
+ desc = "Use the advanced search GUI with autocomplete and history instead of the normal sign GUI"
+ )
+ @ConfigEditorBoolean
+ @ConfigAccordionId(id = 0)
+ public boolean enableSearchOverlay = true;
+
+ @Expose
+ @ConfigOption(
+ name = "Keep Previous Search",
+ desc = "Don't clear the search bar after closing the GUI"
+ )
+ @ConfigEditorBoolean
+ @ConfigAccordionId(id = 0)
+ public boolean keepPreviousSearch = false;
+
+ @Expose
+ @ConfigOption(
+ name = "Past Searches",
+ desc = "Show past searches below the autocomplete box"
+ )
+ @ConfigEditorBoolean
+ @ConfigAccordionId(id = 0)
+ public boolean showPastSearches = true;
+
+ @Expose
+ @ConfigOption(
+ name = "ESC to Full Close",
+ desc = "Make pressing ESCAPE close the search GUI without opening up the Bazaar again\n" +
+ "ENTER can still be used to search"
+ )
+ @ConfigEditorBoolean
+ @ConfigAccordionId(id = 0)
+ public boolean escFullClose = true;
+
+ @Expose
+ @ConfigOption(
+ name = "Bazaar Sacks Profit",
+ desc = "Orders the items in your sacks in the bazaar inventory and adding buy order toggle"
+ )
+ @ConfigEditorBoolean
+ public boolean bazaarSacksProfit = true;
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Dungeons.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Dungeons.java
index e080db7d..c94bd181 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Dungeons.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Dungeons.java
@@ -116,6 +116,15 @@ public class Dungeons {
@Expose
@ConfigOption(
+ name = "Include Essence Cost",
+ desc = "Include Bazaar Essence Sell Cost in the Profit Calculation for Dungeon Chests"
+ )
+ @ConfigEditorBoolean
+ @ConfigAccordionId(id = 1)
+ public boolean useEssenceCostFromBazaar = true;
+
+ @Expose
+ @ConfigOption(
name = "Warning if Derpy active",
desc = "Shows a warning if the mayor Derpy is active"
)
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Mining.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Mining.java
index 2f31261d..727ad329 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Mining.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Mining.java
@@ -207,6 +207,16 @@ public class Mining {
@ConfigAccordionId(id = 2)
public int forgeDisplayEnabledLocations = 0;
+ @Expose
+ @ConfigOption(
+ name = "Forge Tab",
+ desc = "Only show the forge display when tab list is open\n" +
+ "\u00A7cThis only works outside of Dwarven Caves!"
+ )
+ @ConfigEditorBoolean
+ @ConfigAccordionId(id = 2)
+ public boolean forgeDisplayOnlyShowTab = false;
+
@ConfigOption(
name = "Metal Detector Solver",
desc = ""
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Misc.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Misc.java
index d87082b4..84e2322e 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Misc.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Misc.java
@@ -126,13 +126,11 @@ public class Misc {
@Expose
@ConfigOption(
name = "Damage Indicator Style",
- desc = "Change the style of Skyblock damage indicators to be easier to read\n" +
+ desc = "Change Skyblock damage indicators to use shortened numbers\n" +
"\u00A7cSome old animations mods break this feature"
)
- @ConfigEditorDropdown(
- values = {"Off", "Commas", "Shortened"}
- )
- public int damageIndicatorStyle = 1;
+ @ConfigEditorBoolean
+ public boolean damageIndicatorStyle2 = false;
@Expose
@ConfigOption(
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/MiscOverlays.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/MiscOverlays.java
index d2bfdbd9..18b89733 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/MiscOverlays.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/MiscOverlays.java
@@ -52,6 +52,15 @@ public class MiscOverlays {
@Expose
@ConfigOption(
+ name = "Todo Overlay Tab",
+ desc = "Only show the todo overlay when tab list is open"
+ )
+ @ConfigEditorBoolean
+ @ConfigAccordionId(id = 0)
+ public boolean todoOverlayOnlyShowTab = false;
+
+ @Expose
+ @ConfigOption(
name = "Todo Text",
desc = "\u00a7eDrag text to change the appearance of the overlay\n" +
"\u00a7rIf you want to see the time until something is available, click \"Add\" and then the respective timer"
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 8b7002f9..943417e6 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
@@ -274,7 +274,7 @@ public class SkillOverlays {
@Expose
@ConfigOption(
name = "\u00A7cWarning",
- desc = "The combat display will only show if you have a Book of Stats on the item you are using"
+ desc = "The combat display will only show if you have a Book of Stats or the Champion enchant"
)
@ConfigEditorFSR(
runnableId = 12,
@@ -305,11 +305,12 @@ public class SkillOverlays {
"\u00a7bCurrent XP: \u00a7e6,734",
"\u00a7bRemaining XP: \u00a7e3,265",
"\u00a7bXP/h: \u00a7e238,129",
- "\u00a7bETA: \u00a7e13h12m"
+ "\u00a7bETA: \u00a7e13h12m",
+ "\u00a7bChampion XP: \u00a7e3,523"
}
)
@ConfigAccordionId(id = 4)
- public List<Integer> combatText = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5));
+ public List<Integer> combatText = new ArrayList<>(Arrays.asList(0, 6, 1, 2, 3, 4, 5));
@Expose
@ConfigOption(
@@ -337,7 +338,7 @@ public class SkillOverlays {
@Expose
@ConfigOption(
name = "Always show combat overlay",
- desc = "Shows combat overlay even if you dont have Book of Stats"
+ desc = "Shows combat overlay even if you dont have Book of Stats or the Champion enchant"
)
@ConfigEditorBoolean
@ConfigAccordionId(id = 4)
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/TooltipTweaks.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/TooltipTweaks.java
index 0729df97..1edc0921 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/TooltipTweaks.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/TooltipTweaks.java
@@ -181,11 +181,45 @@ public class TooltipTweaks {
@ConfigEditorBoolean
public boolean powerStoneStats = true;
+ @ConfigOption(
+ name = "RNG Meter",
+ desc = ""
+ )
+ @ConfigEditorAccordion(id = 1)
+ public boolean rngMeter = false;
+
+ @Expose
+ @ConfigOption(
+ name = "Fraction Display",
+ desc = "Show the fraction instead of the percentage in the slayer and dungeon rng meter inventory"
+ )
+ @ConfigEditorBoolean
+ @ConfigAccordionId(id = 1)
+ public boolean rngMeterFractionDisplay = true;
+
+ @Expose
+ @ConfigOption(
+ name = " Profit Per Score/XP",
+ desc = "Show the amount of coins per Score/XP in the rng meter inventory"
+ )
+ @ConfigEditorBoolean
+ @ConfigAccordionId(id = 1)
+ public boolean rngMeterProfitPerUnit = true;
+
+ @Expose
+ @ConfigOption(
+ name = "Dungeon/Slayer Needed Counter",
+ desc = "Show the amount of dungeon runs or slayer bosses needed for the rng meter to fill up"
+ )
+ @ConfigEditorBoolean
+ @ConfigAccordionId(id = 1)
+ public boolean rngMeterRunsNeeded = true;
+
@Expose
@ConfigOption(
- name = "Bazaar Sacks Profit",
- desc = "Orders the items in your sacks in the bazaar inventory and adding buy order toggle"
+ name = "Essence Price In Shop",
+ desc = "Show the essence price in the essence shop in the dungeon hub"
)
@ConfigEditorBoolean
- public boolean bazaarSacksProfit = true;
+ public boolean essencePriceInEssenceShop = true;
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/overlays/AuctionSearchOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/overlays/AuctionSearchOverlay.java
index 8ff3218a..fcea79dd 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/overlays/AuctionSearchOverlay.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/overlays/AuctionSearchOverlay.java
@@ -607,7 +607,7 @@ public class AuctionSearchOverlay {
close();
Minecraft.getMinecraft().thePlayer.sendQueue.addToSendQueue(new C0DPacketCloseWindow(Minecraft.getMinecraft().thePlayer.openContainer.windowId));
NotEnoughUpdates.INSTANCE.openGui = new GuiScreenElementWrapper(new NEUConfigEditor(
- NotEnoughUpdates.INSTANCE.config, "AH Search GUI"));
+ NotEnoughUpdates.INSTANCE.config, "AH Tweaks"));
}
}
} else if (Mouse.getEventButton() == 0) {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/overlays/BazaarSearchOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/overlays/BazaarSearchOverlay.java
new file mode 100644
index 00000000..66dacda3
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/overlays/BazaarSearchOverlay.java
@@ -0,0 +1,572 @@
+/*
+ * 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.overlays;
+
+import com.google.common.base.Splitter;
+import com.google.gson.JsonObject;
+import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.core.GuiElementTextField;
+import io.github.moulberry.notenoughupdates.core.GuiScreenElementWrapper;
+import io.github.moulberry.notenoughupdates.mixins.AccessorGuiEditSign;
+import io.github.moulberry.notenoughupdates.options.NEUConfigEditor;
+import io.github.moulberry.notenoughupdates.util.Utils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.ScaledResolution;
+import net.minecraft.client.gui.inventory.GuiEditSign;
+import net.minecraft.client.renderer.GlStateManager;
+import net.minecraft.item.ItemStack;
+import net.minecraft.network.play.client.C0DPacketCloseWindow;
+import net.minecraft.tileentity.TileEntitySign;
+import net.minecraft.util.ChatComponentText;
+import net.minecraft.util.ResourceLocation;
+import org.lwjgl.input.Keyboard;
+import org.lwjgl.input.Mouse;
+import org.lwjgl.opengl.GL11;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class BazaarSearchOverlay {
+ private static final ResourceLocation SEARCH_OVERLAY_TEXTURE = new ResourceLocation(
+ "notenoughupdates:auc_search/ah_search_overlay.png");
+ private static final ResourceLocation SEARCH_OVERLAY_TEXTURE_TAB_COMPLETED = new ResourceLocation(
+ "notenoughupdates:auc_search/ah_search_overlay_tab_completed.png");
+
+ private static final GuiElementTextField textField = new GuiElementTextField("", 200, 20, 0);
+ private static boolean searchFieldClicked = false;
+ private static String searchString = "";
+ private static String searchStringExtra = "";
+ private static final Splitter SPACE_SPLITTER = Splitter.on(" ").omitEmptyStrings().trimResults();
+ private static boolean tabCompleted = false;
+ private static int tabCompletionIndex = -1;
+
+ private static final int AUTOCOMPLETE_HEIGHT = 118;
+
+ private static final Set<String> autocompletedItems = new LinkedHashSet<>();
+
+ private static final Comparator<String> salesComparator = (o1, o2) -> {
+ JsonObject bazaarInfo1 = NotEnoughUpdates.INSTANCE.manager.auctionManager.getBazaarInfo(o1);
+ JsonObject bazaarInfo2 = NotEnoughUpdates.INSTANCE.manager.auctionManager.getBazaarInfo(o2);
+
+ boolean auc1Invalid = bazaarInfo1 == null || !bazaarInfo1.has("curr_sell");
+ boolean auc2Invalid = bazaarInfo2 == null || !bazaarInfo2.has("curr_sell");
+
+ if (auc1Invalid && auc2Invalid) return o1.compareTo(o2);
+ if (auc1Invalid) return -1;
+ if (auc2Invalid) return 1;
+
+ int sales1 = bazaarInfo1.get("curr_sell").getAsInt();
+ int sales2 = bazaarInfo2.get("curr_sell").getAsInt();
+
+ if (sales1 == sales2) return o1.compareTo(o2);
+ if (sales1 > sales2) return -1;
+ return 1;
+ };
+
+ public static boolean shouldReplace() {
+ if (!NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) return false;
+ if (!NotEnoughUpdates.INSTANCE.config.bazaarTweaks.enableSearchOverlay) return false;
+
+ if (!(Minecraft.getMinecraft().currentScreen instanceof GuiEditSign)) {
+ if (!NotEnoughUpdates.INSTANCE.config.bazaarTweaks.keepPreviousSearch) searchString = "";
+ return false;
+ }
+
+ String lastContainer = Utils.getLastOpenChestName();
+ if (!lastContainer.startsWith("Bazaar ➜ ")) return false;
+
+ TileEntitySign tes = ((AccessorGuiEditSign) Minecraft.getMinecraft().currentScreen).getTileSign();
+
+ if (tes == null) return false;
+ if (tes.getPos().getY() != 0) return false;
+ if (!tes.signText[2].getUnformattedText().equals("^^^^^^^^^^^^^^^")) return false;
+ return tes.signText[3].getUnformattedText().equals("Enter query");
+ }
+
+ public static void render() {
+ ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft());
+ int width = scaledResolution.getScaledWidth();
+ int height = scaledResolution.getScaledHeight();
+ int mouseX = Mouse.getX() * width / Minecraft.getMinecraft().displayWidth;
+ int mouseY = height - Mouse.getY() * height / Minecraft.getMinecraft().displayHeight - 1;
+
+ Utils.drawGradientRect(0, 0, width, height, -1072689136, -804253680);
+
+ int h = NotEnoughUpdates.INSTANCE.config.bazaarTweaks.showPastSearches ? 219 : 145;
+
+ int topY = height / 4;
+ if (scaledResolution.getScaleFactor() >= 4) {
+ topY = height / 2 - h / 2 + 5;
+ }
+
+ Minecraft.getMinecraft().getTextureManager().bindTexture(SEARCH_OVERLAY_TEXTURE);
+ GlStateManager.color(1, 1, 1, 1);
+ Utils.drawTexturedRect(width / 2 - 100, topY - 1, 203, h, 0, 203 / 512f, 0, h / 256f, GL11.GL_NEAREST);
+
+ Minecraft.getMinecraft().fontRendererObj.drawString("Enter Query:", width / 2 - 100, topY - 10, 0xdddddd, true);
+
+ textField.setFocus(true);
+ textField.setText(searchString);
+ textField.setSize(149, 20);
+ textField.setCustomBorderColour(0xffffff);
+ textField.render(width / 2 - 100 + 1, topY + 1);
+
+ if (textField.getText().trim().isEmpty()) autocompletedItems.clear();
+
+ List<String> tooltipToDisplay = null;
+
+ int num = 0;
+ synchronized (autocompletedItems) {
+ String[] autoCompletedItemsArray = autocompletedItems.toArray(new String[0]);
+ for (int i = 0; i < autoCompletedItemsArray.length; i++) {
+ String str = autoCompletedItemsArray[i];
+ JsonObject obj = NotEnoughUpdates.INSTANCE.manager.getItemInformation().get(str);
+ if (obj != null) {
+ ItemStack stack = NotEnoughUpdates.INSTANCE.manager.jsonToStack(obj);
+ if (i == tabCompletionIndex) {
+ Minecraft.getMinecraft().getTextureManager().bindTexture(SEARCH_OVERLAY_TEXTURE_TAB_COMPLETED);
+ GlStateManager.color(1, 1, 1, 1);
+ Utils.drawTexturedRect(
+ width / 2 - 96 + 1,
+ topY + 30 + num * 22 + 1,
+ 193,
+ 21,
+ 0 / 512f,
+ 193 / 512f,
+ 0,
+ 21 / 256f,
+ GL11.GL_NEAREST
+ );
+ } else {
+ Minecraft.getMinecraft().getTextureManager().bindTexture(SEARCH_OVERLAY_TEXTURE);
+ GlStateManager.color(1, 1, 1, 1);
+ Utils.drawTexturedRect(
+ width / 2 - 96 + 1,
+ topY + 30 + num * 22 + 1,
+ 193,
+ 21,
+ 214 / 512f,
+ 407 / 512f,
+ 0,
+ 21 / 256f,
+ GL11.GL_NEAREST
+ );
+
+ }
+ String itemName = Utils.trimIgnoreColour(stack.getDisplayName().replaceAll("\\[.+]", ""));
+ if (itemName.contains("Enchanted Book") && str.contains(";")) {
+ String[] lore = NotEnoughUpdates.INSTANCE.manager.getLoreFromNBT(stack.getTagCompound());
+ itemName = lore[0].trim();
+ }
+
+ Minecraft.getMinecraft().fontRendererObj.drawString(Minecraft.getMinecraft().fontRendererObj.trimStringToWidth(
+ itemName,
+ 165
+ ),
+ width / 2 - 74, topY + 35 + num * 22 + 1, 0xdddddd, true
+ );
+
+ GlStateManager.enableDepth();
+ Utils.drawItemStack(stack, width / 2 - 94 + 2, topY + 32 + num * 22 + 1);
+
+ if (mouseX > width / 2 - 96 && mouseX < width / 2 + 96 && mouseY > topY + 30 + num * 22 &&
+ mouseY < topY + 30 + num * 22 + 20) {
+ tooltipToDisplay = stack.getTooltip(Minecraft.getMinecraft().thePlayer, false);
+ }
+
+ if (++num >= 5) break;
+ }
+ }
+ }
+
+ if (NotEnoughUpdates.INSTANCE.config.bazaarTweaks.showPastSearches) {
+ Minecraft.getMinecraft().fontRendererObj.drawString(
+ "Past Searches:",
+ width / 2 - 100,
+ topY + 25 + AUTOCOMPLETE_HEIGHT + 5,
+ 0xdddddd,
+ true
+ );
+
+ for (int i = 0; i < 5; i++) {
+ if (i >= NotEnoughUpdates.INSTANCE.config.hidden.previousBazaarSearches.size()) break;
+
+ String s = NotEnoughUpdates.INSTANCE.config.hidden.previousBazaarSearches.get(i);
+ Minecraft.getMinecraft().fontRendererObj.drawString(
+ s,
+ width / 2 - 95 + 1,
+ topY + 45 + AUTOCOMPLETE_HEIGHT + i * 10 + 2,
+ 0xdddddd,
+ true
+ );
+ }
+
+ if (tooltipToDisplay != null) {
+ Utils.drawHoveringText(
+ tooltipToDisplay,
+ mouseX,
+ mouseY,
+ width,
+ height,
+ -1,
+ Minecraft.getMinecraft().fontRendererObj
+ );
+ }
+ }
+
+ }
+
+ private static final ExecutorService searchES = Executors.newSingleThreadExecutor();
+ private static final AtomicInteger searchId = new AtomicInteger(0);
+
+ private static String getItemIdAtIndex(int i) {
+ if (!autocompletedItems.isEmpty()) {
+ if ((i > autocompletedItems.size() - 1) || i < 0 || i > 4) {
+ return "";
+ }
+ String searchString = autocompletedItems.toArray()[i].toString();
+ JsonObject repoObject = NotEnoughUpdates.INSTANCE.manager.getItemInformation().get(searchString);
+ if (repoObject != null) {
+ ItemStack stack = NotEnoughUpdates.INSTANCE.manager.jsonToStack(repoObject);
+ return Utils.cleanColour(stack.getDisplayName().replaceAll("\\[.+]", ""));
+ }
+
+ }
+ return null;
+ }
+
+ public static void close() {
+ if (tabCompleted) {
+ tabCompletionIndex = -1;
+ tabCompleted = false;
+ }
+ if (NotEnoughUpdates.INSTANCE.config.bazaarTweaks.keepPreviousSearch) {
+ search();
+ } else {
+ synchronized (autocompletedItems) {
+ autocompletedItems.clear();
+ }
+ }
+
+ TileEntitySign tes = ((AccessorGuiEditSign) Minecraft.getMinecraft().currentScreen).getTileSign();
+
+ StringBuilder stringBuilder = new StringBuilder(searchString.trim());
+ if (!searchStringExtra.isEmpty()) {
+ stringBuilder.append(searchStringExtra);
+ }
+
+ String search = stringBuilder.toString();
+
+ if (search.length() <= 15) {
+ tes.signText[0] = new ChatComponentText(search.substring(0, Math.min(search.length(), 15)));
+ } else {
+ List<String> words = SPACE_SPLITTER.splitToList(search);
+
+ StringBuilder line0 = new StringBuilder();
+ StringBuilder line1 = new StringBuilder();
+
+ int currentLine = 0;
+ for (String word : words) {
+ if (currentLine == 0) {
+ if (line0.length() + word.length() > 15) {
+ currentLine++;
+ } else {
+ line0.append(word);
+ if (line0.length() >= 15) {
+ currentLine++;
+ continue;
+ } else {
+ line0.append(" ");
+ }
+ }
+ }
+ if (currentLine == 1) {
+ if (line1.length() + word.length() > 15) {
+ line1.append(word, 0, 15 - line1.length());
+ break;
+ } else {
+ line1.append(word);
+ if (line1.length() >= 15) {
+ break;
+ } else {
+ line1.append(" ");
+ }
+ }
+ }
+ if (line1.length() >= 15) break;
+ }
+
+ tes.signText[0] = new ChatComponentText(line0.toString().trim());
+ tes.signText[1] = new ChatComponentText(line1.toString().trim());
+ }
+
+ if (!searchString.trim().isEmpty()) {
+ List<String> previousBazaarSearches = NotEnoughUpdates.INSTANCE.config.hidden.previousBazaarSearches;
+ previousBazaarSearches.remove(searchString);
+ previousBazaarSearches.remove(searchString);
+ previousBazaarSearches.add(0, searchString);
+ while (previousBazaarSearches.size() > 5) {
+ previousBazaarSearches.remove(previousBazaarSearches.size() - 1);
+ }
+ }
+
+ Minecraft.getMinecraft().displayGuiScreen(null);
+
+ if (Minecraft.getMinecraft().currentScreen == null) {
+ Minecraft.getMinecraft().setIngameFocus();
+ }
+ }
+
+ private static boolean updateTabCompletedSearch(int key) {
+ String id;
+ if (key == Keyboard.KEY_DOWN || key == Keyboard.KEY_TAB) {
+ id = getItemIdAtIndex(tabCompletionIndex + 1);
+ if (id == null) {
+ textField.setFocus(true);
+ textField.setText(searchString);
+ tabCompleted = false;
+ tabCompletionIndex = -1;
+ return true;
+ } else if (id.equals("")) {
+ tabCompletionIndex = 0;
+ return true;
+ } else {
+ searchString = id;
+ tabCompletionIndex += 1;
+ return true;
+ }
+ } else if (key == Keyboard.KEY_UP) {
+ id = getItemIdAtIndex(tabCompletionIndex - 1);
+ if (id == null) {
+ textField.setFocus(true);
+ textField.setText(searchString);
+ tabCompleted = false;
+ tabCompletionIndex = -1;
+ return true;
+ } else if (id.equals("")) {
+ if (autocompletedItems.size() > 4) tabCompletionIndex = 4;
+ else tabCompletionIndex = autocompletedItems.size() - 1;
+ tabCompletionIndex = autocompletedItems.size() - 1;
+ return true;
+ } else {
+ searchString = id;
+ tabCompletionIndex -= 1;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static void search() {
+ final int thisSearchId = searchId.incrementAndGet();
+
+ searchES.submit(() -> {
+ if (thisSearchId != searchId.get()) return;
+
+ List<String> title = new ArrayList<>(NotEnoughUpdates.INSTANCE.manager.search("title:" + searchString.trim()));
+
+ if (thisSearchId != searchId.get()) return;
+
+ if (!searchString.trim().contains(" ")) {
+ StringBuilder sb = new StringBuilder();
+ for (char c : searchString.toCharArray()) {
+ sb.append(c).append(" ");
+ }
+ title.addAll(NotEnoughUpdates.INSTANCE.manager.search("title:" + sb.toString().trim()));
+ }
+
+ if (thisSearchId != searchId.get()) return;
+
+ List<String> desc = new ArrayList<>(NotEnoughUpdates.INSTANCE.manager.search("desc:" + searchString.trim()));
+ desc.removeAll(title);
+
+ if (thisSearchId != searchId.get()) return;
+
+ Set<String> bazaarItems = NotEnoughUpdates.INSTANCE.manager.auctionManager.getBazaarKeySet();
+ // Amalgamated Crimsonite (Old) // TODO remove from repo
+ bazaarItems.remove("AMALGAMATED_CRIMSONITE");
+
+ title.retainAll(bazaarItems);
+ desc.retainAll(bazaarItems);
+
+ title.sort(salesComparator);
+ desc.sort(salesComparator);
+
+ if (thisSearchId != searchId.get()) return;
+
+ synchronized (autocompletedItems) {
+ autocompletedItems.clear();
+ autocompletedItems.addAll(title);
+ autocompletedItems.addAll(desc);
+ }
+ });
+ }
+
+ public static void keyEvent() {
+ boolean ignoreKey = false;
+
+ if (Keyboard.getEventKey() == Keyboard.KEY_ESCAPE) {
+ searchStringExtra = "";
+ close();
+ if (NotEnoughUpdates.INSTANCE.config.bazaarTweaks.escFullClose) {
+ Minecraft.getMinecraft().thePlayer.sendQueue.addToSendQueue(new C0DPacketCloseWindow(Minecraft.getMinecraft().thePlayer.openContainer.windowId));
+ }
+ return;
+ } else if (Keyboard.getEventKey() == Keyboard.KEY_RETURN) {
+ searchStringExtra = "";
+ close();
+ return;
+ } else if (Keyboard.getEventKey() == Keyboard.KEY_TAB) {
+ //autocomplete to first item in the list
+ if (!tabCompleted) {
+ tabCompleted = true;
+ ignoreKey = true;
+ String id = getItemIdAtIndex(0);
+ if (id == null) {
+ tabCompleted = false;
+ textField.setFocus(true);
+ textField.setText(searchString);
+ } else {
+ tabCompletionIndex = 0;
+ searchString = id;
+ }
+ }
+ }
+
+ if (Keyboard.getEventKeyState()) {
+ if (tabCompleted) {
+ if (!ignoreKey) {
+ boolean success = updateTabCompletedSearch(Keyboard.getEventKey());
+ if (success) return;
+ textField.setFocus(true);
+ textField.setText(searchString);
+ tabCompleted = false;
+ tabCompletionIndex = -1;
+ } else return;
+
+ }
+ textField.setFocus(true);
+ textField.setText(searchString);
+ textField.keyTyped(Keyboard.getEventCharacter(), Keyboard.getEventKey());
+ searchString = textField.getText();
+
+ search();
+ }
+ }
+
+ public static void mouseEvent() {
+ ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft());
+ int width = scaledResolution.getScaledWidth();
+ int height = scaledResolution.getScaledHeight();
+ int mouseX = Mouse.getX() * width / Minecraft.getMinecraft().displayWidth;
+ int mouseY = height - Mouse.getY() * height / Minecraft.getMinecraft().displayHeight - 1;
+
+ int h = NotEnoughUpdates.INSTANCE.config.bazaarTweaks.showPastSearches ? 219 : 145;
+
+ int topY = height / 4;
+ if (scaledResolution.getScaleFactor() >= 4) {
+ topY = height / 2 - h / 2 + 5;
+ }
+
+ if (!Mouse.getEventButtonState() && Mouse.getEventButton() == -1 && searchFieldClicked) {
+ textField.mouseClickMove(mouseX - 2, topY + 10, 0, 0);
+ }
+
+ if (Mouse.getEventButton() != -1) {
+ searchFieldClicked = false;
+ }
+
+ if (Mouse.getEventButtonState()) {
+ if (mouseY > topY && mouseY < topY + 20) {
+ if (mouseX > width / 2 - 100) {
+ if (mouseX < width / 2 + 49) {
+ searchFieldClicked = true;
+ textField.mouseClicked(mouseX - 2, mouseY, Mouse.getEventButton());
+
+ if (Mouse.getEventButton() == 1) {
+ searchString = "";
+ synchronized (autocompletedItems) {
+ autocompletedItems.clear();
+ }
+ }
+ } else if (mouseX < width / 2 + 75) {
+ searchStringExtra = "";
+ close();
+ } else if (mouseX < width / 2 + 100) {
+ searchStringExtra = "";
+ close();
+ Minecraft.getMinecraft().thePlayer.sendQueue.addToSendQueue(new C0DPacketCloseWindow(Minecraft.getMinecraft().thePlayer.openContainer.windowId));
+ NotEnoughUpdates.INSTANCE.openGui = new GuiScreenElementWrapper(new NEUConfigEditor(
+ NotEnoughUpdates.INSTANCE.config, "Bazaar Tweaks"));
+ }
+ }
+ } else if (Mouse.getEventButton() == 0) {
+ int num = 0;
+ synchronized (autocompletedItems) {
+ for (String str : autocompletedItems) {
+ JsonObject obj = NotEnoughUpdates.INSTANCE.manager.getItemInformation().get(str);
+ if (obj != null) {
+ ItemStack stack = NotEnoughUpdates.INSTANCE.manager.jsonToStack(obj);
+ if (mouseX >= width / 2 - 96 && mouseX <= width / 2 + 96 && mouseY >= topY + 30 + num * 22 &&
+ mouseY <= topY + 30 + num * 22 + 20) {
+ searchString = Utils.cleanColour(stack.getDisplayName().replaceAll("\\[.+]", "")).trim();
+ if (searchString.contains("Enchanted Book") && str.contains(";")) {
+ String[] lore = NotEnoughUpdates.INSTANCE.manager.getLoreFromNBT(stack.getTagCompound());
+ if (lore != null) {
+ searchString = Utils.cleanColour(lore[0]);
+ }
+ }
+
+ searchStringExtra = " ";
+
+ close();
+ return;
+ }
+
+ if (++num >= 5) break;
+ }
+ }
+ }
+
+ if (NotEnoughUpdates.INSTANCE.config.bazaarTweaks.showPastSearches) {
+ for (int i = 0; i < 5; i++) {
+ if (i >= NotEnoughUpdates.INSTANCE.config.hidden.previousBazaarSearches.size()) break;
+
+ String s = NotEnoughUpdates.INSTANCE.config.hidden.previousBazaarSearches.get(i);
+ if (mouseX >= width / 2 - 95 && mouseX <= width / 2 + 95 &&
+ mouseY >= topY + 45 + AUTOCOMPLETE_HEIGHT + i * 10 &&
+ mouseY <= topY + 45 + AUTOCOMPLETE_HEIGHT + i * 10 + 10) {
+ searchString = s;
+ searchStringExtra = "";
+ close();
+ return;
+ }
+ }
+ }
+ }
+ }
+ }
+}
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 250be27d..4ad6767d 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/overlays/CombatSkillOverlay.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/overlays/CombatSkillOverlay.java
@@ -41,6 +41,10 @@ public class CombatSkillOverlay
private long lastUpdate = -1;
private int killLast = -1;
private int kill = -1;
+ private int championTier = -1;
+ private String championTierAmount = "1";
+ private int championXp = -1;
+ private int championXpLast = -1;
private final LinkedList<Integer> killQueue = new LinkedList<>();
private XPInformation.SkillInfo skillInfo = null;
@@ -84,6 +88,7 @@ public class CombatSkillOverlay
lastUpdate = System.currentTimeMillis();
killLast = kill;
+ championXpLast = championXp;
xpGainHourLast = xpGainHour;
kill = -1;
@@ -100,9 +105,67 @@ public class CombatSkillOverlay
kill = ea.getInteger("stats_book");
killQueue.add(0, kill);
}
+ if (ea.hasKey("champion_combat_xp", 99)) {
+ championXp = (int) ea.getDouble("champion_combat_xp");
+ }
}
}
+ if (championXp < 50000) {
+ championTier = 1;
+ } else if (championXp < 100000) {
+ championTier = 2;
+ } else if (championXp < 250000) {
+ championTier = 3;
+ } else if (championXp < 500000) {
+ championTier = 4;
+ } else if (championXp < 1000000) {
+ championTier = 5;
+ } else if (championXp < 1500000) {
+ championTier = 6;
+ } else if (championXp < 2000000) {
+ championTier = 7;
+ } else if (championXp < 2500000) {
+ championTier = 8;
+ } else if (championXp < 3000000) {
+ championTier = 9;
+ } else if (championXp > 3000000) {
+ championTier = 10;
+ }
+
+ switch (championTier) {
+ case 1:
+ championTierAmount = "50,000";
+ break;
+ case 2:
+ championTierAmount = "100,000";
+ break;
+ case 3:
+ championTierAmount = "250,000";
+ break;
+ case 4:
+ championTierAmount = "500,000";
+ break;
+ case 5:
+ championTierAmount = "1,000,000";
+ break;
+ case 6:
+ championTierAmount = "1,500,000";
+ break;
+ case 7:
+ championTierAmount = "2,000,000";
+ break;
+ case 8:
+ championTierAmount = "2,500,000";
+ break;
+ case 9:
+ championTierAmount = "3,000,000";
+ break;
+ case 10:
+ championTierAmount = "Maxed";
+ break;
+ }
+
String internalname = NotEnoughUpdates.INSTANCE.manager.getInternalNameForItem(stack);
skillInfoLast = skillInfo;
@@ -165,7 +228,7 @@ public class CombatSkillOverlay
public void updateFrequent() {
super.updateFrequent();
- if (kill < 0 && !NotEnoughUpdates.INSTANCE.config.skillOverlays.alwaysShowCombatOverlay) {
+ if ((kill < 0 || championXp < 0) && !NotEnoughUpdates.INSTANCE.config.skillOverlays.alwaysShowCombatOverlay) {
overlayStrings = null;
} else {
HashMap<Integer, String> lineMap = new HashMap<>();
@@ -180,6 +243,23 @@ public class CombatSkillOverlay
lineMap.put(0, EnumChatFormatting.AQUA + "Kills: " + EnumChatFormatting.YELLOW + format.format(counterInterp));
}
+ if (championTier <= 9) {
+ int counterInterp = (int) interp(championXp, championXpLast);
+ lineMap.put(
+ 6,
+ EnumChatFormatting.AQUA + "Champion: " + EnumChatFormatting.YELLOW + format.format(counterInterp) + "/" +
+ championTierAmount
+ );
+ }
+ if (championTier == 10) {
+ int counterInterp = (int) interp(championXp, championXpLast);
+ lineMap.put(
+ 6,
+ EnumChatFormatting.AQUA + "Champion: " + EnumChatFormatting.YELLOW + format.format(counterInterp) + " " +
+ EnumChatFormatting.RED + championTierAmount
+ );
+ }
+
float xpInterp = xpGainHour;
if (xpGainHourLast == xpGainHour && xpGainHour <= 0) {
lineMap.put(4, EnumChatFormatting.AQUA + "XP/h: " + EnumChatFormatting.YELLOW + "N/A");
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/overlays/MiningOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/overlays/MiningOverlay.java
index 8c87ba4c..5794fd5a 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/overlays/MiningOverlay.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/overlays/MiningOverlay.java
@@ -37,6 +37,10 @@ import net.minecraft.inventory.ContainerChest;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumChatFormatting;
+import net.minecraft.world.WorldSettings;
+import net.minecraftforge.fml.relauncher.Side;
+import net.minecraftforge.fml.relauncher.SideOnly;
+import org.lwjgl.input.Keyboard;
import org.lwjgl.util.vector.Vector2f;
import java.util.ArrayList;
@@ -57,7 +61,7 @@ import static net.minecraft.util.EnumChatFormatting.RED;
import static net.minecraft.util.EnumChatFormatting.RESET;
import static net.minecraft.util.EnumChatFormatting.YELLOW;
-public class MiningOverlay extends TextOverlay {
+public class MiningOverlay extends TextTabOverlay {
public MiningOverlay(
Position position,
Supplier<List<String>> dummyStrings,
@@ -430,11 +434,15 @@ public class MiningOverlay extends TextOverlay {
}
if (forgeDisplay) {
overlayStrings = new ArrayList<>();
- 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 (!NotEnoughUpdates.INSTANCE.config.mining.forgeDisplayOnlyShowTab ||
+ Keyboard.isKeyDown(Minecraft.getMinecraft().gameSettings.keyBindPlayerList.getKeyCode())) {
+ 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));
+ }
}
}
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/overlays/TextTabOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/overlays/TextTabOverlay.java
new file mode 100644
index 00000000..69a0cd00
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/overlays/TextTabOverlay.java
@@ -0,0 +1,47 @@
+/*
+ * 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.overlays;
+
+import io.github.moulberry.notenoughupdates.core.config.Position;
+import net.minecraft.client.Minecraft;
+import org.lwjgl.input.Keyboard;
+
+import java.util.List;
+import java.util.function.Supplier;
+
+public abstract class TextTabOverlay extends TextOverlay {
+ public TextTabOverlay(
+ Position position,
+ Supplier<List<String>> dummyStrings,
+ Supplier<TextOverlayStyle> styleSupplier
+ ) {
+ super(position, dummyStrings, styleSupplier);
+ }
+
+ private boolean lastTabState = false;
+
+ public void realTick() {
+ boolean currentTabState = Keyboard.isKeyDown(Minecraft.getMinecraft().gameSettings.keyBindPlayerList.getKeyCode());
+ if (lastTabState != currentTabState) {
+ lastTabState = currentTabState;
+ update();
+ }
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/overlays/TimersOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/overlays/TimersOverlay.java
index d5d8afd7..86df47ff 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/overlays/TimersOverlay.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/overlays/TimersOverlay.java
@@ -37,6 +37,7 @@ import net.minecraft.util.EnumChatFormatting;
import net.minecraftforge.client.event.ClientChatReceivedEvent;
import net.minecraftforge.fml.common.eventhandler.EventPriority;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+import org.lwjgl.input.Keyboard;
import org.lwjgl.util.vector.Vector2f;
import java.time.ZoneId;
@@ -50,7 +51,7 @@ import java.util.regex.Pattern;
import static net.minecraft.util.EnumChatFormatting.DARK_AQUA;
-public class TimersOverlay extends TextOverlay {
+public class TimersOverlay extends TextTabOverlay {
private static final Pattern PATTERN_ACTIVE_EFFECTS = Pattern.compile(
"\u00a7r\u00a7r\u00a77You have a \u00a7r\u00a7cGod Potion \u00a7r\u00a77active! \u00a7r\u00a7d([0-9]*?:?[0-9]*?:?[0-9]*)\u00a7r");
@@ -234,6 +235,12 @@ public class TimersOverlay extends TextOverlay {
NEUConfig.HiddenProfileSpecific hidden = NotEnoughUpdates.INSTANCE.config.getProfileSpecific();
if (hidden == null) return;
+ if (NotEnoughUpdates.INSTANCE.config.miscOverlays.todoOverlayOnlyShowTab &&
+ !Keyboard.isKeyDown(Minecraft.getMinecraft().gameSettings.keyBindPlayerList.getKeyCode())) {
+ overlayStrings = null;
+ return;
+ }
+
if (Minecraft.getMinecraft().currentScreen instanceof GuiChest) {
GuiChest chest = (GuiChest) Minecraft.getMinecraft().currentScreen;
ContainerChest container = (ContainerChest) chest.inventorySlots;
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/BasicPage.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/BasicPage.java
index dcbcb9e4..a72e0a24 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/BasicPage.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/BasicPage.java
@@ -25,6 +25,7 @@ import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.mojang.authlib.GameProfile;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.core.util.StringUtils;
import io.github.moulberry.notenoughupdates.profileviewer.weight.lily.LilyWeight;
import io.github.moulberry.notenoughupdates.profileviewer.weight.senither.SenitherWeight;
import io.github.moulberry.notenoughupdates.util.Constants;
@@ -617,9 +618,9 @@ public class BasicPage extends GuiProfileViewerPage {
EnumChatFormatting.GRAY +
"Progress: " +
EnumChatFormatting.DARK_PURPLE +
- GuiProfileViewer.shortNumberFormat(Math.round((level % 1) * maxXp), 0) +
+ StringUtils.shortNumberFormat(Math.round((level % 1) * maxXp)) +
"/" +
- GuiProfileViewer.shortNumberFormat(maxXp, 0)
+ StringUtils.shortNumberFormat(maxXp)
);
}
String totalXpS = GuiProfileViewer.numberFormat.format((int) skyblockInfo.get(entry.getKey()).totalXp);
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/CollectionsPage.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/CollectionsPage.java
index 4aff5cdb..554e204c 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/CollectionsPage.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/CollectionsPage.java
@@ -21,6 +21,7 @@ package io.github.moulberry.notenoughupdates.profileviewer;
import com.google.gson.JsonObject;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.core.util.StringUtils;
import io.github.moulberry.notenoughupdates.util.Constants;
import io.github.moulberry.notenoughupdates.util.Utils;
import net.minecraft.client.Minecraft;
@@ -291,7 +292,7 @@ public class CollectionsPage extends GuiProfileViewerPage {
}
Utils.drawStringCentered(
- GuiProfileViewer.shortNumberFormat(amount, 0) + "",
+ StringUtils.shortNumberFormat(amount) + "",
Minecraft.getMinecraft().fontRendererObj,
guiLeft + x + 10,
guiTop + y + 26,
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/DungeonPage.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/DungeonPage.java
index c4608299..c707f7fc 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/DungeonPage.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/DungeonPage.java
@@ -25,6 +25,7 @@ import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.core.util.StringUtils;
import io.github.moulberry.notenoughupdates.itemeditor.GuiElementTextField;
import io.github.moulberry.notenoughupdates.util.Constants;
import io.github.moulberry.notenoughupdates.util.Utils;
@@ -173,7 +174,7 @@ public class DungeonPage extends GuiProfileViewerPage {
Utils.renderAlignedString(
EnumChatFormatting.YELLOW + "Until Cata " + floorLevelTo + ": ",
- EnumChatFormatting.WHITE + GuiProfileViewer.shortNumberFormat(floorLevelToXP, 0),
+ EnumChatFormatting.WHITE + StringUtils.shortNumberFormat((double) floorLevelToXP),
x,
y + 16,
sectionWidth
@@ -223,9 +224,9 @@ public class DungeonPage extends GuiProfileViewerPage {
getInstance().tooltipToDisplay =
Lists.newArrayList(
- String.format("# F5 Runs (%s xp) : %d", GuiProfileViewer.shortNumberFormat(xpF5, 0), runsF5),
- String.format("# F6 Runs (%s xp) : %d", GuiProfileViewer.shortNumberFormat(xpF6, 0), runsF6),
- String.format("# F7 Runs (%s xp) : %d", GuiProfileViewer.shortNumberFormat(xpF7, 0), runsF7),
+ String.format("# F5 Runs (%s xp) : %d", StringUtils.shortNumberFormat(xpF5), runsF5),
+ String.format("# F6 Runs (%s xp) : %d", StringUtils.shortNumberFormat(xpF6), runsF6),
+ String.format("# F7 Runs (%s xp) : %d", StringUtils.shortNumberFormat(xpF7), runsF7),
""
);
boolean hasTime = false;
@@ -353,10 +354,10 @@ public class DungeonPage extends GuiProfileViewerPage {
getInstance().tooltipToDisplay =
Lists.newArrayList(
- String.format("# M3 Runs (%s xp) : %d", GuiProfileViewer.shortNumberFormat(xpM3, 0), runsM3),
- String.format("# M4 Runs (%s xp) : %d", GuiProfileViewer.shortNumberFormat(xpM4, 0), runsM4),
- String.format("# M5 Runs (%s xp) : %d", GuiProfileViewer.shortNumberFormat(xpM5, 0), runsM5),
- String.format("# M6 Runs (%s xp) : %d", GuiProfileViewer.shortNumberFormat(xpM6, 0), runsM6),
+ String.format("# M3 Runs (%s xp) : %d", StringUtils.shortNumberFormat(xpM3), runsM3),
+ String.format("# M4 Runs (%s xp) : %d", StringUtils.shortNumberFormat(xpM4), runsM4),
+ String.format("# M5 Runs (%s xp) : %d", StringUtils.shortNumberFormat(xpM5), runsM5),
+ String.format("# M6 Runs (%s xp) : %d", StringUtils.shortNumberFormat(xpM6), runsM6),
""
);
boolean hasTime = false;
@@ -483,7 +484,7 @@ public class DungeonPage extends GuiProfileViewerPage {
);
Utils.renderAlignedString(
EnumChatFormatting.YELLOW + "Secrets (Total) ",
- EnumChatFormatting.WHITE + GuiProfileViewer.shortNumberFormat(secrets, 0),
+ EnumChatFormatting.WHITE + StringUtils.shortNumberFormat(secrets),
x,
miscTopY + 20,
sectionWidth
@@ -497,7 +498,7 @@ public class DungeonPage extends GuiProfileViewerPage {
);
Utils.renderAlignedString(
EnumChatFormatting.YELLOW + "Mob Kills (Total) ",
- EnumChatFormatting.WHITE + GuiProfileViewer.shortNumberFormat(mobKills, 0),
+ EnumChatFormatting.WHITE + StringUtils.shortNumberFormat(mobKills),
x,
miscTopY + 40,
sectionWidth
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ExtraPage.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ExtraPage.java
index 3a071d47..63a4df2c 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ExtraPage.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ExtraPage.java
@@ -22,6 +22,7 @@ package io.github.moulberry.notenoughupdates.profileviewer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
+import io.github.moulberry.notenoughupdates.core.util.StringUtils;
import io.github.moulberry.notenoughupdates.util.Constants;
import io.github.moulberry.notenoughupdates.util.Utils;
import net.minecraft.client.Minecraft;
@@ -77,14 +78,14 @@ public class ExtraPage extends GuiProfileViewerPage {
Utils.renderAlignedString(
EnumChatFormatting.GOLD + "Bank Balance",
- EnumChatFormatting.WHITE + GuiProfileViewer.shortNumberFormat(bankBalance, 0),
+ EnumChatFormatting.WHITE + StringUtils.shortNumberFormat(bankBalance),
guiLeft + xStart,
guiTop + yStartTop,
76
);
Utils.renderAlignedString(
EnumChatFormatting.GOLD + "Purse",
- EnumChatFormatting.WHITE + GuiProfileViewer.shortNumberFormat(purseBalance, 0),
+ EnumChatFormatting.WHITE + StringUtils.shortNumberFormat(purseBalance),
guiLeft + xStart,
guiTop + yStartTop + yOffset,
76
@@ -159,7 +160,17 @@ public class ExtraPage extends GuiProfileViewerPage {
float totalSlayerCount = 0;
float totalSlayerXP = 0;
- List<String> skills = Arrays.asList("taming", "mining", "foraging", "enchanting", "farming", "combat", "fishing", "alchemy");
+ List<String> skills = Arrays.asList(
+ "taming",
+ "mining",
+ "foraging",
+ "enchanting",
+ "farming",
+ "combat",
+ "fishing",
+ "alchemy",
+ "carpentry"
+ );
List<String> slayers = Arrays.asList("zombie", "spider", "wolf", "enderman", "blaze");
for (Map.Entry<String, ProfileViewer.Level> entry : skyblockInfo.entrySet()) {
@@ -204,7 +215,7 @@ public class ExtraPage extends GuiProfileViewerPage {
Utils.renderAlignedString(
EnumChatFormatting.RED + "Total Slayer XP",
- EnumChatFormatting.WHITE + GuiProfileViewer.shortNumberFormat(totalSlayerXP, 0),
+ EnumChatFormatting.WHITE + StringUtils.shortNumberFormat(totalSlayerXP),
guiLeft + xStart,
guiTop + yStartBottom + yOffset * 4,
76
@@ -212,11 +223,17 @@ public class ExtraPage extends GuiProfileViewerPage {
}
float auctions_bids = Utils.getElementAsFloat(Utils.getElement(profileInfo, "stats.auctions_bids"), 0);
- float auctions_highest_bid = Utils.getElementAsFloat(Utils.getElement(profileInfo, "stats.auctions_highest_bid"), 0);
+ float auctions_highest_bid = Utils.getElementAsFloat(
+ Utils.getElement(profileInfo, "stats.auctions_highest_bid"),
+ 0
+ );
float auctions_won = Utils.getElementAsFloat(Utils.getElement(profileInfo, "stats.auctions_won"), 0);
float auctions_created = Utils.getElementAsFloat(Utils.getElement(profileInfo, "stats.auctions_created"), 0);
float auctions_gold_spent = Utils.getElementAsFloat(Utils.getElement(profileInfo, "stats.auctions_gold_spent"), 0);
- float auctions_gold_earned = Utils.getElementAsFloat(Utils.getElement(profileInfo, "stats.auctions_gold_earned"), 0);
+ float auctions_gold_earned = Utils.getElementAsFloat(
+ Utils.getElement(profileInfo, "stats.auctions_gold_earned"),
+ 0
+ );
Utils.renderAlignedString(
EnumChatFormatting.DARK_PURPLE + "Auction Bids",
@@ -227,7 +244,7 @@ public class ExtraPage extends GuiProfileViewerPage {
);
Utils.renderAlignedString(
EnumChatFormatting.DARK_PURPLE + "Highest Bid",
- EnumChatFormatting.WHITE + GuiProfileViewer.shortNumberFormat(auctions_highest_bid, 0),
+ EnumChatFormatting.WHITE + StringUtils.shortNumberFormat(auctions_highest_bid),
guiLeft + xStart + xOffset,
guiTop + yStartTop + yOffset,
76
@@ -248,14 +265,14 @@ public class ExtraPage extends GuiProfileViewerPage {
);
Utils.renderAlignedString(
EnumChatFormatting.DARK_PURPLE + "Gold Spent",
- EnumChatFormatting.WHITE + GuiProfileViewer.shortNumberFormat(auctions_gold_spent, 0),
+ EnumChatFormatting.WHITE + StringUtils.shortNumberFormat(auctions_gold_spent),
guiLeft + xStart + xOffset,
guiTop + yStartTop + yOffset * 4,
76
);
Utils.renderAlignedString(
EnumChatFormatting.DARK_PURPLE + "Gold Earned",
- EnumChatFormatting.WHITE + GuiProfileViewer.shortNumberFormat(auctions_gold_earned, 0),
+ EnumChatFormatting.WHITE + StringUtils.shortNumberFormat(auctions_gold_earned),
guiLeft + xStart + xOffset,
guiTop + yStartTop + yOffset * 5,
76
@@ -274,8 +291,14 @@ public class ExtraPage extends GuiProfileViewerPage {
Utils.getElement(profileInfo, "slayer_bosses.zombie.boss_kills_tier_4"),
0
);
- float wolf_boss_kills_tier_2 = Utils.getElementAsFloat(Utils.getElement(profileInfo, "slayer_bosses.wolf.boss_kills_tier_2"), 0);
- float wolf_boss_kills_tier_3 = Utils.getElementAsFloat(Utils.getElement(profileInfo, "slayer_bosses.wolf.boss_kills_tier_3"), 0);
+ float wolf_boss_kills_tier_2 = Utils.getElementAsFloat(Utils.getElement(
+ profileInfo,
+ "slayer_bosses.wolf.boss_kills_tier_2"
+ ), 0);
+ float wolf_boss_kills_tier_3 = Utils.getElementAsFloat(Utils.getElement(
+ profileInfo,
+ "slayer_bosses.wolf.boss_kills_tier_3"
+ ), 0);
float spider_boss_kills_tier_2 = Utils.getElementAsFloat(
Utils.getElement(profileInfo, "slayer_bosses.spider.boss_kills_tier_2"),
0
@@ -292,8 +315,14 @@ public class ExtraPage extends GuiProfileViewerPage {
Utils.getElement(profileInfo, "slayer_bosses.enderman.boss_kills_tier_3"),
0
);
- float blaze_boss_kills_tier_2 = Utils.getElementAsFloat(Utils.getElement(profileInfo, "slayer_bosses.blaze.boss_kills_tier_2"), 0);
- float blaze_boss_kills_tier_3 = Utils.getElementAsFloat(Utils.getElement(profileInfo, "slayer_bosses.blaze.boss_kills_tier_3"), 0);
+ float blaze_boss_kills_tier_2 = Utils.getElementAsFloat(Utils.getElement(
+ profileInfo,
+ "slayer_bosses.blaze.boss_kills_tier_2"
+ ), 0);
+ float blaze_boss_kills_tier_3 = Utils.getElementAsFloat(Utils.getElement(
+ profileInfo,
+ "slayer_bosses.blaze.boss_kills_tier_3"
+ ), 0);
Utils.renderAlignedString(
EnumChatFormatting.DARK_AQUA + "Revenant T3",
@@ -374,15 +403,24 @@ public class ExtraPage extends GuiProfileViewerPage {
76
);
- float pet_milestone_ores_mined = Utils.getElementAsFloat(Utils.getElement(profileInfo, "stats.pet_milestone_ores_mined"), 0);
+ float pet_milestone_ores_mined = Utils.getElementAsFloat(Utils.getElement(
+ profileInfo,
+ "stats.pet_milestone_ores_mined"
+ ), 0);
float pet_milestone_sea_creatures_killed = Utils.getElementAsFloat(
Utils.getElement(profileInfo, "stats.pet_milestone_sea_creatures_killed"),
0
);
float items_fished = Utils.getElementAsFloat(Utils.getElement(profileInfo, "stats.items_fished"), 0);
- float items_fished_treasure = Utils.getElementAsFloat(Utils.getElement(profileInfo, "stats.items_fished_treasure"), 0);
- float items_fished_large_treasure = Utils.getElementAsFloat(Utils.getElement(profileInfo, "stats.items_fished_large_treasure"), 0);
+ float items_fished_treasure = Utils.getElementAsFloat(
+ Utils.getElement(profileInfo, "stats.items_fished_treasure"),
+ 0
+ );
+ float items_fished_large_treasure = Utils.getElementAsFloat(Utils.getElement(
+ profileInfo,
+ "stats.items_fished_large_treasure"
+ ), 0);
Utils.renderAlignedString(
EnumChatFormatting.GREEN + "Ores Mined",
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java
index 41396832..dbadaadd 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java
@@ -23,6 +23,7 @@ import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.core.util.StringUtils;
import io.github.moulberry.notenoughupdates.cosmetics.ShaderManager;
import io.github.moulberry.notenoughupdates.itemeditor.GuiElementTextField;
import io.github.moulberry.notenoughupdates.miscfeatures.PetInfoOverlay;
@@ -282,20 +283,9 @@ public class GuiProfileViewer extends GuiScreen {
return levelObj;
}
+ @Deprecated
public static String shortNumberFormat(double n, int iteration) {
- if (n < 1000) {
- if (n % 1 == 0) {
- return Integer.toString((int) n);
- } else {
- return String.format("%.2f", n);
- }
- }
-
- double d = ((long) n / 100) / 10.0;
- boolean isRound = (d * 10) % 10 == 0;
- return d < 1000 ? (isRound || d > 9.99 ? (int) d * 10 / 10 : d + "") + "" + c[iteration] : shortNumberFormat(
- d,
- iteration + 1
+ return StringUtils.shortNumberFormat(n, iteration
);
}
@@ -1012,9 +1002,9 @@ public class GuiProfileViewer extends GuiScreen {
int maxXp = (int) levelObj.maxXpForLevel;
levelStr =
EnumChatFormatting.DARK_PURPLE +
- shortNumberFormat(Math.round((level % 1) * maxXp), 0) +
+ StringUtils.shortNumberFormat(Math.round((level % 1) * maxXp)) +
"/" +
- shortNumberFormat(maxXp, 0);
+ StringUtils.shortNumberFormat(maxXp);
}
if (totalXpStr != null) {
tooltipToDisplay = Utils.createList(levelStr, totalXpStr);
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/InventoriesPage.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/InventoriesPage.java
index 8bba9c76..c98792ee 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/InventoriesPage.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/InventoriesPage.java
@@ -23,6 +23,7 @@ import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.core.util.StringUtils;
import io.github.moulberry.notenoughupdates.profileviewer.info.QuiverInfo;
import io.github.moulberry.notenoughupdates.util.Utils;
import net.minecraft.client.Minecraft;
@@ -57,13 +58,15 @@ import static io.github.moulberry.notenoughupdates.profileviewer.GuiProfileViewe
public class InventoriesPage extends GuiProfileViewerPage {
public static final ResourceLocation pv_invs = new ResourceLocation("notenoughupdates:pv_invs.png");
- private static final Pattern DAMAGE_PATTERN = Pattern.compile("^Damage: \\+(\\d+)");
- private static final ResourceLocation CHEST_GUI_TEXTURE = new ResourceLocation("textures/gui/container/generic_54.png");
- private static final Pattern STRENGTH_PATTERN = Pattern.compile("^Strength: \\+(\\d+)");
- private static final Pattern FISHSPEED_PATTERN = Pattern.compile("^Increases fishing speed by \\+(\\d+)");
+ private static final ResourceLocation CHEST_GUI_TEXTURE =
+ new ResourceLocation("textures/gui/container/generic_54.png");
+ private static final Pattern FISHING_SPEED_PATTERN = Pattern.compile("^Fishing Speed: \\+(\\d+)");
private static final LinkedHashMap<String, ItemStack> invNameToDisplayMap = new LinkedHashMap<String, ItemStack>() {
{
- put("inv_contents", Utils.createItemStack(Item.getItemFromBlock(Blocks.chest), EnumChatFormatting.GRAY + "Inventory"));
+ put(
+ "inv_contents",
+ Utils.createItemStack(Item.getItemFromBlock(Blocks.chest), EnumChatFormatting.GRAY + "Inventory")
+ );
put(
"ender_chest_contents",
Utils.createItemStack(Item.getItemFromBlock(Blocks.ender_chest), EnumChatFormatting.GRAY + "Ender Chest")
@@ -82,7 +85,9 @@ public class InventoriesPage extends GuiProfileViewerPage {
put(
"personal_vault_contents",
Utils.editItemStackInfo(
- NotEnoughUpdates.INSTANCE.manager.jsonToStack(NotEnoughUpdates.INSTANCE.manager.getItemInformation().get("IRON_CHEST")),
+ NotEnoughUpdates.INSTANCE.manager.jsonToStack(NotEnoughUpdates.INSTANCE.manager
+ .getItemInformation()
+ .get("IRON_CHEST")),
EnumChatFormatting.GRAY + "Personal Vault",
true
)
@@ -263,21 +268,18 @@ public class InventoriesPage extends GuiProfileViewerPage {
findBestItems(
inventoryInfo,
6,
- new String[] { "inv_contents", "ender_chest_contents" },
- new String[] { "SWORD", "BOW" },
- DAMAGE_PATTERN,
- STRENGTH_PATTERN
+ new String[]{"inv_contents", "ender_chest_contents"},
+ new String[]{"SWORD", "BOW"}
);
}
if (bestRods == null) {
- bestRods =
- findBestItems(
- inventoryInfo,
- 3,
- new String[] { "inv_contents", "ender_chest_contents" },
- new String[] { "FISHING ROD" },
- FISHSPEED_PATTERN
- );
+ bestRods = findBestItems(
+ inventoryInfo,
+ 3,
+ new String[]{"inv_contents", "ender_chest_contents"},
+ new String[]{"FISHING ROD", "FISHING WEAPON"},
+ FISHING_SPEED_PATTERN
+ );
}
for (int i = 0; i < bestWeapons.length; i++) {
@@ -313,21 +315,27 @@ public class InventoriesPage extends GuiProfileViewerPage {
}
Utils.drawItemStackWithText(
- NotEnoughUpdates.INSTANCE.manager.jsonToStack(NotEnoughUpdates.INSTANCE.manager.getItemInformation().get("ARROW")),
+ NotEnoughUpdates.INSTANCE.manager.jsonToStack(NotEnoughUpdates.INSTANCE.manager
+ .getItemInformation()
+ .get("ARROW")),
guiLeft + 173,
guiTop + 101,
- "" + (arrowCount > 999 ? GuiProfileViewer.shortNumberFormat(arrowCount, 0) : arrowCount),
+ "" + (arrowCount > 999 ? StringUtils.shortNumberFormat(arrowCount) : arrowCount),
true
);
Utils.drawItemStackWithText(
- NotEnoughUpdates.INSTANCE.manager.jsonToStack(NotEnoughUpdates.INSTANCE.manager.getItemInformation().get("GREEN_CANDY")),
+ NotEnoughUpdates.INSTANCE.manager.jsonToStack(NotEnoughUpdates.INSTANCE.manager
+ .getItemInformation()
+ .get("GREEN_CANDY")),
guiLeft + 173,
guiTop + 119,
"" + greenCandyCount,
true
);
Utils.drawItemStackWithText(
- NotEnoughUpdates.INSTANCE.manager.jsonToStack(NotEnoughUpdates.INSTANCE.manager.getItemInformation().get("PURPLE_CANDY")),
+ NotEnoughUpdates.INSTANCE.manager.jsonToStack(NotEnoughUpdates.INSTANCE.manager
+ .getItemInformation()
+ .get("PURPLE_CANDY")),
guiLeft + 173,
guiTop + 137,
"" + purpleCandyCount,
@@ -344,7 +352,8 @@ public class InventoriesPage extends GuiProfileViewerPage {
}
} else if (mouseY < guiTop + 119 + 17) {
getInstance().tooltipToDisplay =
- Utils.createList(EnumChatFormatting.GREEN + "Green Candy " + EnumChatFormatting.GRAY + "x" + greenCandyCount);
+ Utils.createList(
+ EnumChatFormatting.GREEN + "Green Candy " + EnumChatFormatting.GRAY + "x" + greenCandyCount);
} else {
getInstance().tooltipToDisplay =
Utils.createList(
@@ -431,11 +440,14 @@ public class InventoriesPage extends GuiProfileViewerPage {
if (
getInstance().inventoryTextField.getText() != null &&
- !getInstance().inventoryTextField.getText().isEmpty() &&
- (
- stack == null ||
- !NotEnoughUpdates.INSTANCE.manager.doesStackMatchSearch(stack, getInstance().inventoryTextField.getText())
- )
+ !getInstance().inventoryTextField.getText().isEmpty() &&
+ (
+ stack == null ||
+ !NotEnoughUpdates.INSTANCE.manager.doesStackMatchSearch(
+ stack,
+ getInstance().inventoryTextField.getText()
+ )
+ )
) {
GlStateManager.translate(0, 0, 50);
GuiScreen.drawRect(
@@ -585,7 +597,12 @@ public class InventoriesPage extends GuiProfileViewerPage {
purpleCandyCount = -1;
}
- private int countItemsInInventory(String internalname, JsonObject inventoryInfo, boolean specific, String... invsToSearch) {
+ private int countItemsInInventory(
+ String internalname,
+ JsonObject inventoryInfo,
+ boolean specific,
+ String... invsToSearch
+ ) {
int count = 0;
for (String inv : invsToSearch) {
JsonArray invItems = inventoryInfo.get(inv).getAsJsonArray();
@@ -594,7 +611,7 @@ public class InventoriesPage extends GuiProfileViewerPage {
JsonObject item = invItems.get(i).getAsJsonObject();
if (
(specific && item.get("internalname").getAsString().equals(internalname)) ||
- (!specific && item.get("internalname").getAsString().contains(internalname))
+ (!specific && item.get("internalname").getAsString().contains(internalname))
) {
if (item.has("count")) {
count += item.get("count").getAsInt();
@@ -615,7 +632,7 @@ public class InventoriesPage extends GuiProfileViewerPage {
Pattern... importantPatterns
) {
ItemStack[] bestItems = new ItemStack[numItems];
- TreeMap<Integer, Set<ItemStack>> map = new TreeMap<>();
+ TreeMap<Long, Set<ItemStack>> map = new TreeMap<>();
for (String inv : invsToSearch) {
JsonArray invItems = inventoryInfo.get(inv).getAsJsonArray();
for (int i = 0; i < invItems.size(); i++) {
@@ -623,22 +640,33 @@ public class InventoriesPage extends GuiProfileViewerPage {
JsonObject item = invItems.get(i).getAsJsonObject();
JsonArray lore = item.get("lore").getAsJsonArray();
if (Utils.checkItemType(lore, true, typeMatches) >= 0) {
- int importance = 0;
- for (int j = 0; j < lore.size(); j++) {
- String line = lore.get(j).getAsString();
- for (Pattern pattern : importantPatterns) {
- Matcher matcher = pattern.matcher(Utils.cleanColour(line));
- if (matcher.find()) {
- importance += Integer.parseInt(matcher.group(1));
+ long importance = 0;
+ int id = 0;
+ if (importantPatterns.length == 0) {
+ String internalName = item.get("internalname").getAsString();
+ importance += NotEnoughUpdates.INSTANCE.manager.auctionManager.getLowestBin(internalName);
+ importance += ++id;
+ } else {
+ for (int j = 0; j < lore.size(); j++) {
+ String line = lore.get(j).getAsString();
+ for (Pattern pattern : importantPatterns) {
+ Matcher matcher = pattern.matcher(Utils.cleanColour(line));
+ if (matcher.find()) {
+ importance += Integer.parseInt(matcher.group(1));
+ }
}
}
}
- map.computeIfAbsent(importance, k -> new HashSet<>()).add(NotEnoughUpdates.INSTANCE.manager.jsonToStack(item, false));
+ map.computeIfAbsent(importance, k -> new HashSet<>()).add(NotEnoughUpdates.INSTANCE.manager.jsonToStack(
+ item,
+ false
+ ));
}
}
}
int i = 0;
- outer:for (int key : map.descendingKeySet()) {
+ outer:
+ for (long key : map.descendingKeySet()) {
Set<ItemStack> items = map.get(key);
for (ItemStack item : items) {
bestItems[i] = item;
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/MiningPage.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/MiningPage.java
index fc305e94..c32310b7 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/MiningPage.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/MiningPage.java
@@ -22,6 +22,7 @@ package io.github.moulberry.notenoughupdates.profileviewer;
import com.google.common.collect.Lists;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
+import io.github.moulberry.notenoughupdates.core.util.StringUtils;
import io.github.moulberry.notenoughupdates.util.Constants;
import io.github.moulberry.notenoughupdates.util.Utils;
import net.minecraft.client.Minecraft;
@@ -223,28 +224,28 @@ public class MiningPage extends GuiProfileViewerPage {
//Powder
Utils.renderAlignedString(
EnumChatFormatting.DARK_GREEN + "Mithril Powder",
- EnumChatFormatting.WHITE + GuiProfileViewer.shortNumberFormat(mithrilPowder, 0),
+ EnumChatFormatting.WHITE + StringUtils.shortNumberFormat(mithrilPowder),
guiLeft + xStart,
guiTop + yStartTop + 24,
115
);
Utils.renderAlignedString(
EnumChatFormatting.LIGHT_PURPLE + "Gemstone Powder",
- EnumChatFormatting.WHITE + GuiProfileViewer.shortNumberFormat(gemstonePowder, 0),
+ EnumChatFormatting.WHITE + StringUtils.shortNumberFormat(gemstonePowder),
guiLeft + xStart,
guiTop + yStartTop + 44,
115
);
Utils.renderAlignedString(
EnumChatFormatting.DARK_GREEN + "Total Mithril Powder",
- EnumChatFormatting.WHITE + GuiProfileViewer.shortNumberFormat(mithrilPowderTotal + mithrilPowder, 0),
+ EnumChatFormatting.WHITE + StringUtils.shortNumberFormat(mithrilPowderTotal + mithrilPowder),
guiLeft + xStart,
guiTop + yStartTop + 34,
115
);
Utils.renderAlignedString(
EnumChatFormatting.LIGHT_PURPLE + "Total Gemstone Powder",
- EnumChatFormatting.WHITE + GuiProfileViewer.shortNumberFormat(gemstonePowderTotal + gemstonePowder, 0),
+ EnumChatFormatting.WHITE + StringUtils.shortNumberFormat(gemstonePowderTotal + gemstonePowder),
guiLeft + xStart,
guiTop + yStartTop + 54,
115
@@ -301,7 +302,7 @@ public class MiningPage extends GuiProfileViewerPage {
);
Utils.renderAlignedString(
EnumChatFormatting.BLUE + "Total Placed Crystals:",
- EnumChatFormatting.WHITE + GuiProfileViewer.shortNumberFormat(crystalPlacedAmount, 0),
+ EnumChatFormatting.WHITE + StringUtils.shortNumberFormat(crystalPlacedAmount),
guiLeft + xStart,
guiTop + yStartTop + 149,
110
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/PetsPage.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/PetsPage.java
index 22d86424..25751ab8 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/PetsPage.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/PetsPage.java
@@ -24,6 +24,7 @@ import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.core.util.StringUtils;
import io.github.moulberry.notenoughupdates.util.Constants;
import io.github.moulberry.notenoughupdates.util.SBInfo;
import io.github.moulberry.notenoughupdates.util.Utils;
@@ -498,21 +499,21 @@ public class PetsPage extends GuiProfileViewerPage {
Utils.renderAlignedString(
EnumChatFormatting.YELLOW + "Total XP",
- EnumChatFormatting.WHITE + GuiProfileViewer.shortNumberFormat(exp, 0),
+ EnumChatFormatting.WHITE + StringUtils.shortNumberFormat(exp),
guiLeft + 319,
guiTop + 125,
98
);
Utils.renderAlignedString(
EnumChatFormatting.YELLOW + "Current LVL XP",
- EnumChatFormatting.WHITE + GuiProfileViewer.shortNumberFormat((level % 1) * currentLevelRequirement, 0),
+ EnumChatFormatting.WHITE + StringUtils.shortNumberFormat((level % 1) * currentLevelRequirement),
guiLeft + 319,
guiTop + 143,
98
);
Utils.renderAlignedString(
EnumChatFormatting.YELLOW + "Required LVL XP",
- EnumChatFormatting.WHITE + GuiProfileViewer.shortNumberFormat(currentLevelRequirement, 0),
+ EnumChatFormatting.WHITE + StringUtils.shortNumberFormat(currentLevelRequirement),
guiLeft + 319,
guiTop + 161,
98
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewer.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewer.java
index e89cbe8a..ea42c7f0 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewer.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewer.java
@@ -1415,6 +1415,8 @@ public class ProfileViewer {
collectionInfo.add("total_amounts", totalAmounts);
collectionInfo.add("collection_tiers", collectionTiers);
+ collectionInfoMap.put(profileName, collectionInfo);
+
return collectionInfo;
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/bestiary/BestiaryPage.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/bestiary/BestiaryPage.java
index 1aebb290..efa94ee5 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/bestiary/BestiaryPage.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/bestiary/BestiaryPage.java
@@ -21,6 +21,7 @@ package io.github.moulberry.notenoughupdates.profileviewer.bestiary;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
+import io.github.moulberry.notenoughupdates.core.util.StringUtils;
import io.github.moulberry.notenoughupdates.profileviewer.GuiProfileViewer;
import io.github.moulberry.notenoughupdates.profileviewer.GuiProfileViewerPage;
import io.github.moulberry.notenoughupdates.profileviewer.ProfileViewer;
@@ -201,10 +202,10 @@ public class BestiaryPage extends GuiProfileViewerPage {
if (level.maxed) {
progressStr = EnumChatFormatting.GOLD + "MAXED!";
} else {
- progressStr = EnumChatFormatting.AQUA +
- GuiProfileViewer.shortNumberFormat(Math.round((levelNum % 1) * level.maxXpForLevel), 0) +
+ progressStr =EnumChatFormatting.AQUA +
+ StringUtils.shortNumberFormat(Math.round((levelNum % 1) * level.maxXpForLevel)) +
"/" +
- GuiProfileViewer.shortNumberFormat(level.maxXpForLevel, 0);
+ StringUtils.shortNumberFormat(level.maxXpForLevel);
}
tooltipToDisplay.add(EnumChatFormatting.GRAY + "Progress: " + progressStr);
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/Calculator.java b/src/main/java/io/github/moulberry/notenoughupdates/util/Calculator.java
index 7d378a03..10bfa6a9 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/util/Calculator.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/util/Calculator.java
@@ -25,10 +25,12 @@ import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.List;
+import java.util.Locale;
import java.util.NoSuchElementException;
public class Calculator {
public static BigDecimal calculate(String source) throws CalculatorException {
+ source = source.toLowerCase(Locale.ROOT);
return evaluate(shuntingYard(lex(source)));
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/ItemResolutionQuery.java b/src/main/java/io/github/moulberry/notenoughupdates/util/ItemResolutionQuery.java
new file mode 100644
index 00000000..1ff659ac
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/util/ItemResolutionQuery.java
@@ -0,0 +1,239 @@
+/*
+ * 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.util;
+
+import com.google.common.collect.Iterables;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParseException;
+import io.github.moulberry.notenoughupdates.NEUManager;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.Gui;
+import net.minecraft.client.gui.inventory.GuiChest;
+import net.minecraft.init.Items;
+import net.minecraft.inventory.ContainerChest;
+import net.minecraft.inventory.IInventory;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+
+import javax.annotation.Nullable;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Locale;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class ItemResolutionQuery {
+
+ private static final Pattern ENCHANTED_BOOK_NAME_PATTERN = Pattern.compile("^((?:§.)+)([^§]+) ([IVXL]+)$");
+ private static final String EXTRA_ATTRIBUTES = "ExtraAttributes";
+ private static final List<String> PET_RARITIES = Arrays.asList(
+ "COMMON",
+ "UNCOMMON",
+ "RARE",
+ "EPIC",
+ "LEGENDARY",
+ "MYTHIC"
+ );
+ private final NEUManager manager;
+ private NBTTagCompound compound;
+ private Item itemType;
+ private int stackSize = -1;
+ private Gui guiContext;
+ private String knownInternalName;
+
+ public ItemResolutionQuery(NEUManager manager) {
+ this.manager = manager;
+ }
+
+ public ItemResolutionQuery withItemNBT(NBTTagCompound compound) {
+ this.compound = compound;
+ return this;
+ }
+
+ public ItemResolutionQuery withItemStack(ItemStack stack) {
+ if (stack == null) return this;
+ this.itemType = stack.getItem();
+ this.compound = stack.getTagCompound();
+ this.stackSize = stack.stackSize;
+ return this;
+ }
+
+ public ItemResolutionQuery withGuiContext(Gui gui) {
+ this.guiContext = gui;
+ return this;
+ }
+
+ public ItemResolutionQuery withCurrentGuiContext() {
+ this.guiContext = Minecraft.getMinecraft().currentScreen;
+ return this;
+ }
+
+ public ItemResolutionQuery withKnownInternalName(String knownInternalName) {
+ this.knownInternalName = knownInternalName;
+ return this;
+ }
+
+ @Nullable
+ public String resolveInternalName() {
+ if (knownInternalName != null) {
+ return knownInternalName;
+ }
+ String resolvedName = resolveFromSkyblock();
+ if (resolvedName == null) {
+ resolvedName = resolveContextualName();
+ } else {
+ switch (resolvedName.intern()) {
+ case "PET":
+ resolvedName = resolvePetName();
+ break;
+ case "RUNE":
+ resolvedName = resolveRuneName();
+ break;
+ case "ENCHANTED_BOOK":
+ resolvedName = resolveEnchantedBookNameFromNBT();
+ break;
+ case "PARTY_HAT_CRAB":
+ case "PARTY_HAT_CRAB_ANIMATED":
+ resolvedName = resolveCrabHatName();
+ break;
+ }
+ }
+
+ return resolvedName;
+ }
+
+ @Nullable
+ public JsonObject resolveToItemListJson() {
+ String internalName = resolveInternalName();
+ if (internalName == null) {
+ return null;
+ }
+ return manager.getItemInformation().get(internalName);
+ }
+
+ @Nullable
+ public ItemStack resolveToItemStack() {
+ JsonObject jsonObject = resolveToItemListJson();
+ if (jsonObject == null) return null;
+ return manager.jsonToStack(jsonObject);
+ }
+
+ // <editor-fold desc="Resolution Helpers">
+ private boolean isBazaar(IInventory chest) {
+ if (chest.getDisplayName().getFormattedText().startsWith("Bazaar ➜ ")) {
+ return true;
+ }
+ int bazaarSlot = chest.getSizeInventory() - 5;
+ if (bazaarSlot < 0) return false;
+ ItemStack stackInSlot = chest.getStackInSlot(bazaarSlot);
+ if (stackInSlot == null || stackInSlot.stackSize == 0) return false;
+ // NBT lore, we do not care about rendered lore
+ List<String> lore = ItemUtils.getLore(stackInSlot);
+ return lore.contains("§7To Bazaar");
+ }
+
+ private String resolveContextualName() {
+ if (!(guiContext instanceof GuiChest)) {
+ return null;
+ }
+ GuiChest chest = (GuiChest) guiContext;
+ ContainerChest inventorySlots = (ContainerChest) chest.inventorySlots;
+ String guiName = inventorySlots.getLowerChestInventory().getDisplayName().getUnformattedText();
+ boolean isOnBazaar = isBazaar(inventorySlots.getLowerChestInventory());
+ String displayName = ItemUtils.getDisplayName(compound);
+ if (displayName == null) return null;
+ if (itemType == Items.enchanted_book && isOnBazaar && compound != null) {
+ return resolveEnchantmentByName(displayName);
+ }
+ if (displayName.endsWith("Enchanted Book") && guiName.startsWith("Superpairs")) {
+ for (String loreLine : ItemUtils.getLore(compound)) {
+ String enchantmentIdCandidate = resolveEnchantmentByName(loreLine);
+ if (enchantmentIdCandidate != null) return enchantmentIdCandidate;
+ }
+ return null;
+ }
+ return null;
+ }
+
+ private String resolveEnchantmentByName(String name) {
+ Matcher matcher = ENCHANTED_BOOK_NAME_PATTERN.matcher(name);
+ if (!matcher.matches()) return null;
+ String format = matcher.group(1).toLowerCase(Locale.ROOT);
+ String enchantmentName = matcher.group(2).trim();
+ String romanLevel = matcher.group(3);
+ boolean ultimate = (format.contains("§l"));
+
+ return (ultimate ? "ULTIMATE_" : "")
+ + enchantmentName.replace(" ", "_").toUpperCase(Locale.ROOT)
+ + ";" + Utils.parseRomanNumeral(romanLevel);
+ }
+
+ private String resolveCrabHatName() {
+ int crabHatYear = getExtraAttributes().getInteger("party_hat_year");
+ String color = getExtraAttributes().getString("party_hat_color");
+ return "PARTY_HAT_CRAB_" + color.toUpperCase(Locale.ROOT) + (crabHatYear == 2022 ? "_ANIMATED" : "");
+ }
+
+ private String resolveEnchantedBookNameFromNBT() {
+ NBTTagCompound enchantments = getExtraAttributes().getCompoundTag("enchantments");
+ String enchantName = Iterables.getOnlyElement(enchantments.getKeySet(), null);
+ if (enchantName == null || enchantName.isEmpty()) return null;
+ return enchantName.toUpperCase(Locale.ROOT) + ";" + enchantments.getInteger(enchantName);
+ }
+
+ private String resolveRuneName() {
+ NBTTagCompound runes = getExtraAttributes().getCompoundTag("runes");
+ String runeName = Iterables.getOnlyElement(runes.getKeySet(), null);
+ if (runeName == null || runeName.isEmpty()) return null;
+ return runeName.toUpperCase(Locale.ROOT) + "_RUNE;" + runes.getInteger(runeName);
+ }
+
+ private String resolvePetName() {
+ String petInfo = getExtraAttributes().getString("petInfo");
+ if (petInfo == null || petInfo.isEmpty()) return null;
+ try {
+ JsonObject petInfoObject = manager.gson.fromJson(petInfo, JsonObject.class);
+ String petId = petInfoObject.get("type").getAsString();
+ String petTier = petInfoObject.get("tier").getAsString();
+ int rarityIndex = PET_RARITIES.indexOf(petTier);
+ return petId.toUpperCase(Locale.ROOT) + ";" + rarityIndex;
+ } catch (JsonParseException | ClassCastException ex) {
+ /* This happens if Hypixel changed the pet json format;
+ I still log this exception, since this case *is* exceptional and cannot easily be recovered from */
+ ex.printStackTrace();
+ return null;
+ }
+ }
+
+ private NBTTagCompound getExtraAttributes() {
+ if (compound == null) return new NBTTagCompound();
+ return compound.getCompoundTag(EXTRA_ATTRIBUTES);
+ }
+
+ private String resolveFromSkyblock() {
+ String internalName = getExtraAttributes().getString("id");
+ if (internalName == null || internalName.isEmpty()) return null;
+ return internalName.toUpperCase(Locale.ROOT);
+ }
+
+ // </editor-fold>
+
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/ItemUtils.java b/src/main/java/io/github/moulberry/notenoughupdates/util/ItemUtils.java
index 3a2db0fb..cffdd164 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/util/ItemUtils.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/util/ItemUtils.java
@@ -73,7 +73,10 @@ public class ItemUtils {
}
public static List<String> getLore(ItemStack is) {
- NBTTagCompound tagCompound = is.getTagCompound();
+ return getLore(is.getTagCompound());
+ }
+
+ public static List<String> getLore(NBTTagCompound tagCompound) {
if (tagCompound == null) {
return Collections.emptyList();
}
@@ -84,4 +87,13 @@ public class ItemUtils {
}
return list;
}
+
+ public static String getDisplayName(NBTTagCompound compound) {
+ if (compound == null) return null;
+ String string = compound.getCompoundTag("display").getString("Name");
+ if (string == null || string.isEmpty())
+ return null;
+ return string;
+ }
+
}