diff options
39 files changed, 1576 insertions, 179 deletions
| diff --git a/Update Notes/2.1.md b/Update Notes/2.1.md index b5853248..050eaa93 100644 --- a/Update Notes/2.1.md +++ b/Update Notes/2.1.md @@ -37,6 +37,9 @@    - Added senither and lily weight - CrypticPlasma    - Added the Quiver Info when hovering in inventory tab over Arrows display - Lulonaut    - Added the Magical Power Info when hovering in inventory tab over Accessory Bag display - Lulonaut +  - Added carpentry skill to skill average - hannibal2 +  - Fixed sort order of fishing rods in profile viewer page - hannibal2 +  - Changing sort logic from strength plus damage to bin price for best weapons in pv inventory page - hannibal2  ### **Minor Changes:** @@ -106,9 +109,13 @@  - Add Auto-Updater (linux only) - nea89  - Added power stone feature - hannibal2  - Added abiphone warning - hannibal2 -- Added blur limit to map at 100 - nopo +- Added blur limit at 100 - nopo  - Added bazaar sacks profit feature - hannibal2  - Added an option to disable etherwarp overlay when TP is denied - hannibal2 +- Added bazaar search overlay - hannibal2 +- Added fraction display instead of percentage in slayer and dungeon RNG meter inventory - hannibal2 +- Added profit per score/XP to RNG meter - hannibal2 +- Added showing the amount of dungeon runs or slayer bosses needed for the rng meter to fill up - hannibal2  - Added bazaar prices to enchants in the enchantment table - hannibal2 / nea89 @@ -137,6 +144,9 @@  - Fixed crash with spamming remove enchant in /neuec - nopo  - Fixed missing enchants not working with shiny items - nopo  - Fixed golden dragon not working in pet overlay - CrypticPlasma +- Fixed shortened damage - nopo +- Fixed bazaar prices sorting order in neu item list - hannibal2 +- Fixed priceless items showing first in the missing tab of the accessory bag overlay - nopo  ### **Other:** @@ -155,6 +165,7 @@    - NeucrystalHollowsJungle    - NeucrystalHollowsMagmaFields    - NeucrystalHollowsCrystalNucleus +- Disabled Skyclient cosmetics disabling neu map - nopo  ### **Previous change log** 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 dd4c01af..6732336c 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; @@ -283,6 +285,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 74ef2483..2dc02b7e 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java @@ -807,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 6143085c..a4f814d1 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()); 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/listener/ChatListener.java b/src/main/java/io/github/moulberry/notenoughupdates/listener/ChatListener.java index 5bd47f3a..b59eaf17 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/listener/ChatListener.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/listener/ChatListener.java @@ -198,8 +198,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 e5c3324f..3936ad74 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/listener/ItemTooltipListener.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/listener/ItemTooltipListener.java @@ -266,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(); 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/RenderListener.java b/src/main/java/io/github/moulberry/notenoughupdates/listener/RenderListener.java index 54b647e9..166e46d0 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/listener/RenderListener.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/listener/RenderListener.java @@ -53,6 +53,7 @@ import io.github.moulberry.notenoughupdates.miscgui.TrophyRewardOverlay;  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; @@ -119,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; @@ -146,6 +149,8 @@ public class RenderListener {  	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;  	} @@ -420,6 +425,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); @@ -736,7 +746,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);  							}  						} @@ -752,6 +762,20 @@ public class RenderListener {  					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; @@ -986,6 +1010,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); @@ -1466,6 +1495,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/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 2b600d2e..e6c4dc74 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 ade9edfe..4d04bfbc 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; @@ -371,6 +372,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"  	) @@ -445,6 +453,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/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/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/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 b227c815..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,15 +21,9 @@ 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 java.awt.*; -import java.io.IOException; -import java.text.NumberFormat; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Locale;  import net.minecraft.client.Minecraft;  import net.minecraft.client.renderer.GlStateManager;  import net.minecraft.item.ItemStack; @@ -39,6 +33,14 @@ import org.lwjgl.input.Keyboard;  import org.lwjgl.input.Mouse;  import org.lwjgl.opengl.GL11; +import java.awt.*; +import java.io.IOException; +import java.text.NumberFormat; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +  public class CollectionsPage extends GuiProfileViewerPage {  	public static final ResourceLocation pv_cols = new ResourceLocation("notenoughupdates:pv_cols.png"); @@ -290,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 73bbd295..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,14 +25,10 @@ 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; -import java.io.IOException; -import java.util.Base64; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.UUID;  import net.minecraft.client.Minecraft;  import net.minecraft.client.gui.FontRenderer;  import net.minecraft.client.renderer.GlStateManager; @@ -48,6 +44,12 @@ import org.lwjgl.input.Keyboard;  import org.lwjgl.opengl.GL11;  import org.lwjgl.opengl.GL14; +import java.io.IOException; +import java.util.Base64; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.UUID; +  public class DungeonPage extends GuiProfileViewerPage {  	private static final ResourceLocation pv_dung = new ResourceLocation("notenoughupdates:pv_dung.png"); @@ -172,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 @@ -222,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; @@ -352,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; @@ -482,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 @@ -496,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 3cbd944d..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,10 +22,15 @@ 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.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.core.util.StringUtils;  import io.github.moulberry.notenoughupdates.util.Constants; -import io.github.moulberry.notenoughupdates.util.PronounDB;  import io.github.moulberry.notenoughupdates.util.Utils; +import net.minecraft.client.Minecraft; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.ResourceLocation; +import org.apache.commons.lang3.text.WordUtils; +import org.lwjgl.opengl.GL11; +  import java.time.Instant;  import java.time.LocalDateTime;  import java.time.ZoneId; @@ -34,15 +39,9 @@ import java.util.Arrays;  import java.util.HashSet;  import java.util.List;  import java.util.Map; -import java.util.Optional;  import java.util.Set;  import java.util.TimeZone;  import java.util.TreeMap; -import net.minecraft.client.Minecraft; -import net.minecraft.util.EnumChatFormatting; -import net.minecraft.util.ResourceLocation; -import org.apache.commons.lang3.text.WordUtils; -import org.lwjgl.opengl.GL11;  public class ExtraPage extends GuiProfileViewerPage { @@ -79,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 @@ -161,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()) { @@ -206,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 @@ -214,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", @@ -229,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 @@ -250,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 @@ -276,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 @@ -294,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", @@ -376,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 59373952..0f9d1b4a 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; @@ -283,20 +284,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  		);  	} @@ -1013,9 +1003,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 c4c788e7..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,12 +22,9 @@ 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 java.util.ArrayList; -import java.util.HashMap; -import java.util.Objects; -import java.util.function.Supplier;  import net.minecraft.client.Minecraft;  import net.minecraft.client.renderer.GlStateManager;  import net.minecraft.client.renderer.RenderHelper; @@ -39,6 +36,11 @@ import net.minecraft.util.EnumChatFormatting;  import net.minecraft.util.ResourceLocation;  import org.lwjgl.opengl.GL11; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Objects; +import java.util.function.Supplier; +  public class MiningPage extends GuiProfileViewerPage {  	public static final ResourceLocation pv_mining = new ResourceLocation("notenoughupdates:pv_mining.png"); @@ -222,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 @@ -300,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 4214371c..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,17 +24,10 @@ 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; -import java.awt.*; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Base64; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID;  import net.minecraft.client.Minecraft;  import net.minecraft.client.gui.GuiScreen;  import net.minecraft.client.renderer.GlStateManager; @@ -50,6 +43,15 @@ import net.minecraft.util.ResourceLocation;  import org.lwjgl.input.Mouse;  import org.lwjgl.opengl.GL11; +import java.awt.*; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Base64; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; +  public class PetsPage extends GuiProfileViewerPage {  	public static final ResourceLocation pv_pets = new ResourceLocation("notenoughupdates:pv_pets.png"); @@ -497,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/bestiary/BestiaryPage.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/bestiary/BestiaryPage.java index 3dc97a85..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,16 +21,12 @@ 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;  import io.github.moulberry.notenoughupdates.util.Constants;  import io.github.moulberry.notenoughupdates.util.Utils; -import java.awt.*; -import java.text.NumberFormat; -import java.util.ArrayList; -import java.util.List; -import java.util.Locale;  import net.minecraft.client.Minecraft;  import net.minecraft.client.gui.ScaledResolution;  import net.minecraft.client.renderer.GlStateManager; @@ -40,6 +36,12 @@ import net.minecraft.util.EnumChatFormatting;  import net.minecraft.util.ResourceLocation;  import org.lwjgl.opengl.GL11; +import java.awt.*; +import java.text.NumberFormat; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +  public class BestiaryPage extends GuiProfileViewerPage {  	public static final ResourceLocation pv_elements = new ResourceLocation("notenoughupdates:pv_elements.png"); @@ -200,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/resources/mixins.notenoughupdates.json b/src/main/resources/mixins.notenoughupdates.json index ed1ba55a..0a547b4b 100644 --- a/src/main/resources/mixins.notenoughupdates.json +++ b/src/main/resources/mixins.notenoughupdates.json @@ -40,6 +40,7 @@      "MixinRenderGlobal",      "MixinRenderItem",      "MixinRenderList", +    "MixinSkyclientCosmetics",      "MixinTextureManager",      "MixinTileEntitySkullRenderer",      "MixinTileEntitySpecialRenderer", | 
