diff options
Diffstat (limited to 'src/main/java')
63 files changed, 3237 insertions, 393 deletions
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java index cd0d08b5..f1220b34 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java @@ -29,6 +29,7 @@ import io.github.moulberry.notenoughupdates.auction.APIManager; import io.github.moulberry.notenoughupdates.events.RepositoryReloadEvent; import io.github.moulberry.notenoughupdates.miscgui.GuiItemRecipe; import io.github.moulberry.notenoughupdates.miscgui.KatSitterOverlay; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.MinionHelperManager; import io.github.moulberry.notenoughupdates.recipes.CraftingOverlay; import io.github.moulberry.notenoughupdates.recipes.CraftingRecipe; import io.github.moulberry.notenoughupdates.recipes.Ingredient; @@ -156,10 +157,6 @@ public class NEUManager { repoLocation.mkdir(); } - public void setCurrentProfile(String currentProfile) { - SBInfo.getInstance().currentProfile = currentProfile; - } - public String getCurrentProfile() { return SBInfo.getInstance().currentProfile; } @@ -207,7 +204,7 @@ public class NEUManager { } public CompletableFuture<Boolean> fetchRepository() { - return CompletableFuture.<Boolean>supplyAsync(() -> { + return CompletableFuture.supplyAsync(() -> { try { JsonObject currentCommitJSON = getJsonFromFile(new File(configLocation, "currentCommit.json")); @@ -672,7 +669,8 @@ public class NEUManager { ea = ea.getCompoundTag("Properties"); ea = ea.getTagList("textures", 10).getCompoundTagAt(0); String name = ea3.getString("Name").replaceAll(" M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$", ""); - return "put(\"ID\", Utils.createSkull(EnumChatFormatting.AQUA + \"" + name + "\" ,\"" + ea2.getString("Id") + "\", \"" + ea.getString("Value") +"\"));"; + return "put(\"ID\", Utils.createSkull(EnumChatFormatting.AQUA + \"" + name + "\" ,\"" + ea2.getString("Id") + + "\", \"" + ea.getString("Value") + "\"));"; } } return null; @@ -912,6 +910,7 @@ public class NEUManager { NBTTagCompound tag = stack.getTagCompound(); return getSkullValueFromNBT(tag); } + public String getInternalNameForItem(ItemStack stack) { if (stack == null) return null; NBTTagCompound tag = stack.getTagCompound(); @@ -1519,7 +1518,7 @@ public class NEUManager { return NotEnoughUpdates.INSTANCE.manager .fetchRepository() .thenCompose(ignored -> NotEnoughUpdates.INSTANCE.manager.reloadRepository()) - .<List<String>>thenApply(ignored -> { + .thenApply(ignored -> { String newCommitHash = NotEnoughUpdates.INSTANCE.manager.latestRepoCommit; String newCommitShortHash = (newCommitHash == null ? "MISSING" : newCommitHash.substring(0, 7)); return Arrays.asList( diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java index a1eb03d1..c604fd86 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java @@ -61,6 +61,7 @@ import io.github.moulberry.notenoughupdates.miscgui.CalendarOverlay; import io.github.moulberry.notenoughupdates.miscgui.InventoryStorageSelector; import io.github.moulberry.notenoughupdates.miscgui.SignCalculator; import io.github.moulberry.notenoughupdates.miscgui.TrophyRewardOverlay; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.MinionHelperManager; import io.github.moulberry.notenoughupdates.mixins.AccessorMinecraft; import io.github.moulberry.notenoughupdates.options.NEUConfig; import io.github.moulberry.notenoughupdates.overlays.FuelBar; @@ -291,6 +292,7 @@ public class NotEnoughUpdates { MinecraftForge.EVENT_BUS.register(TrophyRewardOverlay.getInstance()); MinecraftForge.EVENT_BUS.register(PowerStoneStatsDisplay.getInstance()); MinecraftForge.EVENT_BUS.register(BazaarSacksProfit.getInstance()); + MinecraftForge.EVENT_BUS.register(MinionHelperManager.getInstance()); MinecraftForge.EVENT_BUS.register(navigation); if (Minecraft.getMinecraft().getResourceManager() instanceof IReloadableResourceManager) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DevTestCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DevTestCommand.java index 7cca9d3b..ca4d3080 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DevTestCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DevTestCommand.java @@ -27,7 +27,9 @@ import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.Custom import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.LocationChangeEvent; import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.SpecialBlockZone; import io.github.moulberry.notenoughupdates.miscgui.GuiPriceGraph; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.MinionHelperManager; import io.github.moulberry.notenoughupdates.util.SBInfo; +import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiScreen; import net.minecraft.command.CommandException; @@ -54,7 +56,8 @@ public class DevTestCommand extends ClientCommandBase { "dediamondpro", "lulonaut", "craftyoldminer", - "eisengolem" + "eisengolem", + "hannibal2" ); private static final String[] DEV_FAIL_STRINGS = { @@ -105,8 +108,7 @@ public class DevTestCommand extends ClientCommandBase { Minecraft.getMinecraft().getNetHandler().getNetworkManager().closeChannel(component); return; } - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + - DEV_FAIL_STRINGS[devFailIndex++])); + Utils.addChatMessage(EnumChatFormatting.RED + DEV_FAIL_STRINGS[devFailIndex++]); return; } if (args.length >= 1 && args[0].equalsIgnoreCase("profileinfo")) { @@ -150,7 +152,8 @@ public class DevTestCommand extends ClientCommandBase { return; } if (args.length == 1 && args[0].equalsIgnoreCase("dev")) { - NotEnoughUpdates.INSTANCE.config.hidden.dev = true; + NotEnoughUpdates.INSTANCE.config.hidden.dev = !NotEnoughUpdates.INSTANCE.config.hidden.dev; + Utils.addChatMessage("§e[NEU] Dev mode " + (NotEnoughUpdates.INSTANCE.config.hidden.dev ? "§aenabled": "§cdisabled")); return; } if (args.length == 1 && args[0].equalsIgnoreCase("saveconfig")) { @@ -159,18 +162,16 @@ public class DevTestCommand extends ClientCommandBase { } if (args.length == 1 && args[0].equalsIgnoreCase("searchmode")) { NotEnoughUpdates.INSTANCE.config.hidden.firstTimeSearchFocus = true; - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.AQUA + - "I would never search")); + Utils.addChatMessage(EnumChatFormatting.AQUA + "I would never search"); return; } if (args.length == 2 && args[0].equalsIgnoreCase("openGui")) { try { NotEnoughUpdates.INSTANCE.openGui = (GuiScreen) Class.forName(args[1]).newInstance(); - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( - "Opening gui: " + NotEnoughUpdates.INSTANCE.openGui)); + Utils.addChatMessage("Opening gui: " + NotEnoughUpdates.INSTANCE.openGui); } catch (InstantiationException | IllegalAccessException | ClassNotFoundException | ClassCastException e) { e.printStackTrace(); - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("Failed to open this gui.")); + Utils.addChatMessage("Failed to open this gui."); } } if (args.length == 1 && args[0].equalsIgnoreCase("center")) { @@ -178,5 +179,8 @@ public class DevTestCommand extends ClientCommandBase { double z = Math.floor(Minecraft.getMinecraft().thePlayer.posZ) + 0.5f; Minecraft.getMinecraft().thePlayer.setPosition(x, Minecraft.getMinecraft().thePlayer.posY, z); } + if (args.length >= 1 && args[0].equalsIgnoreCase("minion")) { + MinionHelperManager.getInstance().handleCommand(args); + } } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/PackDevCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/PackDevCommand.java index e1504472..1d30a15f 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/PackDevCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/PackDevCommand.java @@ -22,6 +22,7 @@ package io.github.moulberry.notenoughupdates.commands.dev; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.commands.ClientCommandBase; import io.github.moulberry.notenoughupdates.core.util.MiscUtils; +import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; import net.minecraft.client.entity.AbstractClientPlayer; import net.minecraft.command.CommandException; @@ -290,11 +291,10 @@ public class PackDevCommand extends ClientCommandBase { } if ((single && closest == null) || (!single && result.length() == 0)) { - mc.thePlayer.addChatMessage(new ChatComponentText( - EnumChatFormatting.RED + "No " + typeFriendlyName + "s found within " + dist + " blocks.")); + Utils.addChatMessage(EnumChatFormatting.RED + "No " + typeFriendlyName + "s found within " + dist + " blocks."); } else { - mc.thePlayer.addChatMessage(new ChatComponentText( - EnumChatFormatting.GREEN + "Copied " + typeFriendlyName + " data to clipboard")); + Utils.addChatMessage( + EnumChatFormatting.GREEN + "Copied " + typeFriendlyName + " data to clipboard"); return single ? livingBaseDataBuilder(closest, clazz) : result; } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/StatsCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/StatsCommand.java index 756afc88..b03e7f05 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/StatsCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/StatsCommand.java @@ -24,11 +24,11 @@ import io.github.moulberry.notenoughupdates.commands.ClientCommandBase; import io.github.moulberry.notenoughupdates.util.DiscordMarkdownBuilder; import io.github.moulberry.notenoughupdates.util.HastebinUploader; import io.github.moulberry.notenoughupdates.util.SBInfo; +import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.command.ICommandSender; import net.minecraft.util.BlockPos; -import net.minecraft.util.ChatComponentText; import net.minecraft.util.EnumChatFormatting; import net.minecraftforge.common.ForgeVersion; import net.minecraftforge.fml.common.Loader; @@ -118,10 +118,8 @@ public class StatsCommand extends ClientCommandBase { } private static void modPrefixedMessage(String message) { - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( - EnumChatFormatting.GOLD + "[" + EnumChatFormatting.RED + "NotEnoughUpdates" + EnumChatFormatting.GOLD + "]: " + - message)); - + Utils.addChatMessage( + EnumChatFormatting.GOLD + "[" + EnumChatFormatting.RED + "NotEnoughUpdates" + EnumChatFormatting.GOLD + "]: " + message); } private static String createStats() { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/dungeon/DnCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/dungeon/DnCommand.java index a5a7bcca..3b697905 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/dungeon/DnCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/dungeon/DnCommand.java @@ -20,10 +20,10 @@ package io.github.moulberry.notenoughupdates.commands.dungeon; import io.github.moulberry.notenoughupdates.commands.ClientCommandBase; +import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; import net.minecraft.command.CommandException; import net.minecraft.command.ICommandSender; -import net.minecraft.util.ChatComponentText; import net.minecraft.util.EnumChatFormatting; public class DnCommand extends ClientCommandBase { @@ -35,7 +35,6 @@ public class DnCommand extends ClientCommandBase { @Override public void processCommand(ICommandSender sender, String[] args) throws CommandException { Minecraft.getMinecraft().thePlayer.sendChatMessage("/warp dungeon_hub"); - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( - EnumChatFormatting.AQUA + "Warping to:" + EnumChatFormatting.YELLOW + " Deez Nuts lmao")); + Utils.addChatMessage(EnumChatFormatting.AQUA + "Warping to:" + EnumChatFormatting.YELLOW + " Deez Nuts lmao"); } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/dungeon/JoinDungeonCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/dungeon/JoinDungeonCommand.java index d69f86f3..5916bb61 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/dungeon/JoinDungeonCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/dungeon/JoinDungeonCommand.java @@ -21,10 +21,10 @@ package io.github.moulberry.notenoughupdates.commands.dungeon; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.commands.ClientCommandBase; +import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; import net.minecraft.command.CommandException; import net.minecraft.command.ICommandSender; -import net.minecraft.util.ChatComponentText; import net.minecraft.util.EnumChatFormatting; import org.apache.commons.lang3.StringUtils; @@ -40,19 +40,16 @@ public class JoinDungeonCommand extends ClientCommandBase { Minecraft.getMinecraft().thePlayer.sendChatMessage("/join " + StringUtils.join(args, " ")); } else { if (args.length != 1) { - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( - EnumChatFormatting.RED + "Example Usage: /join f7, /join m6 or /join 7")); + Utils.addChatMessage(EnumChatFormatting.RED + "Example Usage: /join f7, /join m6 or /join 7"); } else { String cataPrefix = "catacombs"; if (args[0].startsWith("m")) { cataPrefix = "master_catacombs"; } String cmd = "/joindungeon " + cataPrefix + " " + args[0].charAt(args[0].length() - 1); - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( - EnumChatFormatting.YELLOW + "Running command: " + cmd)); - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( - EnumChatFormatting.YELLOW + - "The dungeon should start soon. If it doesn't, make sure you have a party of 5 people")); + Utils.addChatMessage(EnumChatFormatting.YELLOW + "Running command: " + cmd); + Utils.addChatMessage(EnumChatFormatting.YELLOW + + "The dungeon should start soon. If it doesn't, make sure you have a party of 5 people"); Minecraft.getMinecraft().thePlayer.sendChatMessage(cmd); } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/dungeon/MapCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/dungeon/MapCommand.java index f5381adb..3967edb4 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/dungeon/MapCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/dungeon/MapCommand.java @@ -24,6 +24,7 @@ import com.google.gson.JsonObject; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.commands.ClientCommandBase; import io.github.moulberry.notenoughupdates.dungeons.GuiDungeonMapEditor; +import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.block.material.MapColor; import net.minecraft.client.Minecraft; import net.minecraft.command.CommandException; @@ -128,8 +129,7 @@ public class MapCommand extends ClientCommandBase { e.printStackTrace(); } - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.GREEN + - "Saved to file.")); + Utils.addChatMessage(EnumChatFormatting.GREEN + "Saved to file."); } return; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/help/FeaturesCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/help/FeaturesCommand.java index 5f709c4f..bc389ad4 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/help/FeaturesCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/help/FeaturesCommand.java @@ -41,18 +41,9 @@ public class FeaturesCommand extends ClientCommandBase { @Override public void processCommand(ICommandSender sender, String[] args) throws CommandException { - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("")); + Utils.addChatMessage(""); if (Constants.MISC == null || !Constants.MISC.has("featureslist")) { - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( - "" + EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + "WARNING: " + EnumChatFormatting.RESET + - EnumChatFormatting.RED + "Could not load URL from repo.")); - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( - "" + EnumChatFormatting.RED + "Please run " + EnumChatFormatting.BOLD + "/neuresetrepo" + - EnumChatFormatting.RESET + EnumChatFormatting.RED + " and " + EnumChatFormatting.BOLD + "restart your game" + - EnumChatFormatting.RESET + EnumChatFormatting.RED + " in order to fix. " + EnumChatFormatting.DARK_RED + - EnumChatFormatting.BOLD + "If that doesn't fix it" + EnumChatFormatting.RESET + EnumChatFormatting.RED + - ", please join discord.gg/moulberry and post in #neu-support")); - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("")); + Utils.showOutdatedRepoNotification(); return; } String url = Constants.MISC.get("featureslist").getAsString(); @@ -60,9 +51,8 @@ public class FeaturesCommand extends ClientCommandBase { Desktop desk = Desktop.getDesktop(); try { desk.browse(new URI(url)); - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( - EnumChatFormatting.DARK_PURPLE + "" + EnumChatFormatting.BOLD + "NEU" + EnumChatFormatting.RESET + - EnumChatFormatting.GOLD + "> Opening Feature List in browser.")); + Utils.addChatMessage( EnumChatFormatting.DARK_PURPLE + "" + EnumChatFormatting.BOLD + "NEU" + EnumChatFormatting.RESET + + EnumChatFormatting.GOLD + "> Opening Feature List in browser."); } catch (URISyntaxException | IOException ignored) { ChatComponentText clickTextFeatures = new ChatComponentText( @@ -72,6 +62,6 @@ public class FeaturesCommand extends ClientCommandBase { Minecraft.getMinecraft().thePlayer.addChatMessage(clickTextFeatures); } - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("")); + Utils.addChatMessage(""); } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/help/HelpCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/help/HelpCommand.java index 7655f561..86699b79 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/help/HelpCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/help/HelpCommand.java @@ -22,9 +22,8 @@ package io.github.moulberry.notenoughupdates.commands.help; import com.google.common.collect.Lists; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.commands.ClientCommandBase; -import net.minecraft.client.Minecraft; +import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.command.ICommandSender; -import net.minecraft.util.ChatComponentText; import java.util.ArrayList; @@ -66,7 +65,7 @@ public class HelpCommand extends ClientCommandBase { "\u00a76/neupackdev \u00a7r\u00a77- pack creator command - getnpc, getmob(s), getarmorstand(s), getall. Optional radius argument for all." ); for (String neuHelpMessage : neuHelpMessages) { - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(neuHelpMessage)); + Utils.addChatMessage(neuHelpMessage); } if (NotEnoughUpdates.INSTANCE.config.hidden.dev) { ArrayList<String> neuDevHelpMessages = Lists.newArrayList( @@ -76,7 +75,7 @@ public class HelpCommand extends ClientCommandBase { ); for (String neuDevHelpMessage : neuDevHelpMessages) { - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(neuDevHelpMessage)); + Utils.addChatMessage(neuDevHelpMessage); } } String[] helpInfo = { @@ -89,8 +88,7 @@ public class HelpCommand extends ClientCommandBase { }; for (String message : helpInfo) { - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(message)); + Utils.addChatMessage(message); } - } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/help/LinksCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/help/LinksCommand.java index 9938403c..793e652e 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/help/LinksCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/help/LinksCommand.java @@ -22,10 +22,9 @@ package io.github.moulberry.notenoughupdates.commands.help; import com.google.gson.JsonObject; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.commands.ClientCommandBase; -import net.minecraft.client.Minecraft; +import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.command.CommandException; import net.minecraft.command.ICommandSender; -import net.minecraft.util.ChatComponentText; import java.io.File; @@ -43,9 +42,9 @@ public class LinksCommand extends ClientCommandBase { try { JsonObject update = NotEnoughUpdates.INSTANCE.manager.getJsonFromFile(updateJson); - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("")); + Utils.addChatMessage(""); NotEnoughUpdates.INSTANCE.displayLinks(update,0 ); - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("")); + Utils.addChatMessage(""); } catch (Exception ignored) { } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/AhCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/AhCommand.java index 1cd6bcce..5e3bd9b1 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/AhCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/AhCommand.java @@ -22,10 +22,9 @@ package io.github.moulberry.notenoughupdates.commands.misc; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.auction.CustomAHGui; import io.github.moulberry.notenoughupdates.commands.ClientCommandBase; -import net.minecraft.client.Minecraft; +import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.command.CommandException; import net.minecraft.command.ICommandSender; -import net.minecraft.util.ChatComponentText; import net.minecraft.util.EnumChatFormatting; import org.apache.commons.lang3.StringUtils; @@ -38,12 +37,11 @@ public class AhCommand extends ClientCommandBase { @Override public void processCommand(ICommandSender sender, String[] args) throws CommandException { if (!NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) { - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + - "You must be on Skyblock to use this feature.")); + Utils.addChatMessage(EnumChatFormatting.RED + "You must be on Skyblock to use this feature."); } else if (NotEnoughUpdates.INSTANCE.config.apiData.apiKey == null || NotEnoughUpdates.INSTANCE.config.apiData.apiKey.trim().isEmpty()) { - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + - "Can't open NeuAH, apikey is not set. Run /api new and put the result in settings.")); + Utils.addChatMessage( + EnumChatFormatting.RED + "Can't open NeuAH, apikey is not set. Run /api new and put the result in settings."); } else { NotEnoughUpdates.INSTANCE.openGui = new CustomAHGui(); NotEnoughUpdates.INSTANCE.manager.auctionManager.customAH.lastOpen = System.currentTimeMillis(); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/CosmeticsCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/CosmeticsCommand.java index f74b5813..762f18bd 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/CosmeticsCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/CosmeticsCommand.java @@ -22,11 +22,10 @@ package io.github.moulberry.notenoughupdates.commands.misc; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.commands.ClientCommandBase; import io.github.moulberry.notenoughupdates.cosmetics.GuiCosmetics; -import net.minecraft.client.Minecraft; +import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.command.CommandException; import net.minecraft.command.ICommandSender; -import net.minecraft.util.ChatComponentText; import net.minecraft.util.EnumChatFormatting; public class CosmeticsCommand extends ClientCommandBase { @@ -38,8 +37,8 @@ public class CosmeticsCommand extends ClientCommandBase { @Override public void processCommand(ICommandSender sender, String[] args) throws CommandException { if (!OpenGlHelper.isFramebufferEnabled() && NotEnoughUpdates.INSTANCE.config.notifications.doFastRenderNotif) { - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + - "NEU cosmetics do not work with OF Fast Render. Go to ESC > Options > Video Settings > Performance > Fast Render to disable it.")); + Utils.addChatMessage(EnumChatFormatting.RED + + "NEU cosmetics do not work with OF Fast Render. Go to ESC > Options > Video Settings > Performance > Fast Render to disable it."); } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/profile/PeekCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/profile/PeekCommand.java index 21afff87..2336eea2 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/profile/PeekCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/profile/PeekCommand.java @@ -72,8 +72,8 @@ public class PeekCommand extends ClientCommandBase { if (peekCommandExecutorService == null || peekCommandExecutorService.isShutdown()) { peekCommandExecutorService = Executors.newSingleThreadScheduledExecutor(); } else { - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( - EnumChatFormatting.RED + "[PEEK] New peek command run, cancelling old one.")); + Utils.addChatMessage( + EnumChatFormatting.RED + "[PEEK] New peek command run, cancelling old one."); peekCommandExecutorService.shutdownNow(); peekCommandExecutorService = Executors.newSingleThreadScheduledExecutor(); } @@ -113,8 +113,7 @@ public class PeekCommand extends ClientCommandBase { EnumChatFormatting.STRIKETHROUGH + "-=-"), id); if (skill == null) { - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( - EnumChatFormatting.YELLOW + "Skills api disabled!")); + Utils.addChatMessage(EnumChatFormatting.YELLOW + "Skills api disabled!"); } else { float totalSkillLVL = 0; float totalSkillCount = 0; @@ -180,19 +179,16 @@ public class PeekCommand extends ClientCommandBase { overallScore += cata * cata / 2000f; - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( - g + "Combat: " + combatPrefix + (int) Math.floor(combat) + + Utils.addChatMessage(g + "Combat: " + combatPrefix + (int) Math.floor(combat) + (cata > 0 ? g + " - Cata: " + cataPrefix + cata : "") + - g + " - AVG: " + avgPrefix + (int) Math.floor(avgSkillLVL))); - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( - g + "Slayer: " + zombiePrefix + (int) Math.floor(zombie) + g + "-" + + g + " - AVG: " + avgPrefix + (int) Math.floor(avgSkillLVL)); + Utils.addChatMessage(g + "Slayer: " + zombiePrefix + (int) Math.floor(zombie) + g + "-" + spiderPrefix + (int) Math.floor(spider) + g + "-" + wolfPrefix + (int) Math.floor(wolf) + "-" + - endermanPrefix + (int) Math.floor(enderman))); + endermanPrefix + (int) Math.floor(enderman)); } if (stats == null) { - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( - EnumChatFormatting.YELLOW + "Skills, collection and/or inventory apis disabled!")); + Utils.addChatMessage(EnumChatFormatting.YELLOW + "Skills, collection and/or inventory apis disabled!"); } else { int health = (int) stats.get("health"); int defence = (int) stats.get("defence"); @@ -220,11 +216,10 @@ public class PeekCommand extends ClientCommandBase { : EnumChatFormatting.YELLOW) : EnumChatFormatting.RED; - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( - g + "Stats : " + healthPrefix + health + EnumChatFormatting.RED + "\u2764 " + - defencePrefix + defence + EnumChatFormatting.GREEN + "\u2748 " + - strengthPrefix + strength + EnumChatFormatting.RED + "\u2741 " + - intelligencePrefix + intelligence + EnumChatFormatting.AQUA + "\u270e ")); + Utils.addChatMessage( g + "Stats : " + healthPrefix + health + EnumChatFormatting.RED + "\u2764 " + + defencePrefix + defence + EnumChatFormatting.GREEN + "\u2748 " + + strengthPrefix + strength + EnumChatFormatting.RED + "\u2741 " + + intelligencePrefix + intelligence + EnumChatFormatting.AQUA + "\u270e "); } float bankBalance = Utils.getElementAsFloat(Utils.getElement(profileInfo, "banking.balance"), -1); float purseBalance = Utils.getElementAsFloat(Utils.getElement(profileInfo, "coin_purse"), 0); @@ -235,11 +230,10 @@ public class PeekCommand extends ClientCommandBase { (money > 200 * 1000 * 1000 ? EnumChatFormatting.GREEN : EnumChatFormatting.YELLOW) : EnumChatFormatting.RED; - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( - g + "Purse: " + moneyPrefix + Utils.shortNumberFormat(purseBalance, 0) + g + " - Bank: " + - (bankBalance == -1 ? EnumChatFormatting.YELLOW + "N/A" : moneyPrefix + - (isMe ? "4.8b" : Utils.shortNumberFormat(bankBalance, 0))) + - (networth > 0 ? g + " - Net: " + moneyPrefix + Utils.shortNumberFormat(networth, 0) : ""))); + Utils.addChatMessage( g + "Purse: " + moneyPrefix + Utils.shortNumberFormat(purseBalance, 0) + g + " - Bank: " + + (bankBalance == -1 ? EnumChatFormatting.YELLOW + "N/A" : moneyPrefix + + (isMe ? "4.8b" : Utils.shortNumberFormat(bankBalance, 0))) + + (networth > 0 ? g + " - Net: " + moneyPrefix + Utils.shortNumberFormat(networth, 0) : "")); overallScore += Math.min(2, money / (100f * 1000 * 1000)); @@ -255,8 +249,7 @@ public class PeekCommand extends ClientCommandBase { String col = NotEnoughUpdates.petRarityToColourMap.get(activePetTier); if (col == null) col = EnumChatFormatting.LIGHT_PURPLE.toString(); - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(g + "Pet : " + - col + WordUtils.capitalizeFully(activePet.replace("_", " ")))); + Utils.addChatMessage(g + "Pet : " + col + WordUtils.capitalizeFully(activePet.replace("_", " "))); String overall = "Skywars Main"; if (isMe) { @@ -281,8 +274,7 @@ public class PeekCommand extends ClientCommandBase { overall = EnumChatFormatting.RED + "Played Skyblock"; } - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(g + "Overall score: " + - overall + g + " (" + Math.round(overallScore * 10) / 10f + ")")); + Utils.addChatMessage(g + "Overall score: " + overall + g + " (" + Math.round(overallScore * 10) / 10f + ")"); peekCommandExecutorService.shutdownNow(); } else { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/profile/ViewProfileCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/profile/ViewProfileCommand.java index e4ca497c..b5a3549c 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/profile/ViewProfileCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/profile/ViewProfileCommand.java @@ -22,6 +22,7 @@ package io.github.moulberry.notenoughupdates.commands.profile; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.commands.ClientCommandBase; import io.github.moulberry.notenoughupdates.profileviewer.GuiProfileViewer; +import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.command.ICommandSender; @@ -38,32 +39,31 @@ public class ViewProfileCommand extends ClientCommandBase { public static final Consumer<String[]> RUNNABLE = (args) -> { if (!OpenGlHelper.isFramebufferEnabled()) { - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + - "Some parts of the profile viewer do not work with OF Fast Render. Go to ESC > Options > Video Settings > Performance > Fast Render to disable it.")); + Utils.addChatMessage(EnumChatFormatting.RED + + "Some parts of the profile viewer do not work with OF Fast Render. Go to ESC > Options > Video Settings > Performance > Fast Render to disable it."); } if (NotEnoughUpdates.INSTANCE.config.apiData.apiKey == null || NotEnoughUpdates.INSTANCE.config.apiData.apiKey.trim().isEmpty()) { - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + - "Can't view profile, apikey is not set. Run /api new and put the result in settings.")); + Utils.addChatMessage(EnumChatFormatting.RED + + "Can't view profile, apikey is not set. Run /api new and put the result in settings."); } else if (args.length == 0) { NotEnoughUpdates.profileViewer.getProfileByName(Minecraft.getMinecraft().thePlayer.getName(), profile -> { if (profile == null) { - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + - "Invalid player name/api key. Maybe api is down? Try /api new.")); + Utils.addChatMessage(EnumChatFormatting.RED + + "Invalid player name/api key. Maybe api is down? Try /api new."); } else { profile.resetCache(); NotEnoughUpdates.INSTANCE.openGui = new GuiProfileViewer(profile); } }); } else if (args.length > 1) { - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + - "Too many arguments. Usage: /neuprofile [name]")); + Utils.addChatMessage(EnumChatFormatting.RED + + "Too many arguments. Usage: /neuprofile [name]"); } else { NotEnoughUpdates.profileViewer.getProfileByName(args[0], profile -> { if (profile == null) { - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + - "Invalid player name/api key. Maybe api is down? Try /api new.")); + Utils.addChatMessage(EnumChatFormatting.RED + "Invalid player name/api key. Maybe api is down? Try /api new."); } else { profile.resetCache(); NotEnoughUpdates.INSTANCE.openGui = new GuiProfileViewer(profile); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/util/PageArrowsUtils.java b/src/main/java/io/github/moulberry/notenoughupdates/core/util/PageArrowsUtils.java new file mode 100644 index 00000000..1207cfa9 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/util/PageArrowsUtils.java @@ -0,0 +1,155 @@ +/* + * 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.core.util; + +import io.github.moulberry.notenoughupdates.util.Utils; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.gui.ScaledResolution; +import net.minecraft.util.MathHelper; +import net.minecraft.util.ResourceLocation; +import org.lwjgl.input.Mouse; +import org.lwjgl.opengl.GL11; + +import java.awt.*; +import java.util.function.Consumer; + +public class PageArrowsUtils { + + public static final int BUTTON_POSITION_RIGHT_OFFSET_X = 37; + public static final int PAGE_STRING_OFFSET_X = 22; + public static final int PAGE_STRING_OFFSET_Y = 6; + + public static final int BUTTON_WIDTH = 7; + public static final int BUTTON_HEIGHT = 11; + + public static final ResourceLocation resourcePacksTexture = new ResourceLocation("textures/gui/resource_packs.png"); + + public static void onDraw(int guiLeft, int guiTop, int[] topLeftButton, int currentPage, int totalPages) { + if (totalPages < 2) return; + + final ScaledResolution scaledresolution = new ScaledResolution(Minecraft.getMinecraft()); + final int scaledWidth = scaledresolution.getScaledWidth(); + final int scaledHeight = scaledresolution.getScaledHeight(); + int mouseX = Mouse.getX() * scaledWidth / Minecraft.getMinecraft().displayWidth; + int mouseY = scaledHeight - Mouse.getY() * scaledHeight / Minecraft.getMinecraft().displayHeight - 1; + + int buttonPositionLeftX = topLeftButton[0]; + int buttonPositionRightX = buttonPositionLeftX + BUTTON_POSITION_RIGHT_OFFSET_X; + int pageStringX = buttonPositionLeftX + PAGE_STRING_OFFSET_X; + int buttonPositionY = topLeftButton[1]; + int pageStringY = buttonPositionY + PAGE_STRING_OFFSET_Y; + + boolean leftSelected = isWithinRect( + mouseX - guiLeft, + mouseY - guiTop, + buttonPositionLeftX, + buttonPositionY, + BUTTON_WIDTH, + BUTTON_HEIGHT + ); + boolean rightSelected = isWithinRect( + mouseX - guiLeft, + mouseY - guiTop, + buttonPositionRightX, + buttonPositionY, + BUTTON_WIDTH, + BUTTON_HEIGHT + ); + Minecraft.getMinecraft().getTextureManager().bindTexture(resourcePacksTexture); + + if (currentPage != 0) + Utils.drawTexturedRect( + guiLeft + buttonPositionLeftX, guiTop + buttonPositionY, BUTTON_WIDTH, BUTTON_HEIGHT, + 34 / 256f, 48 / 256f, + leftSelected ? 37 / 256f : 5 / 256f, leftSelected ? 59 / 256f : 27 / 256f + ); + if (currentPage != totalPages - 1) + Utils.drawTexturedRect( + guiLeft + buttonPositionRightX, guiTop + buttonPositionY, BUTTON_WIDTH, BUTTON_HEIGHT, + 10 / 256f, 24 / 256f, + rightSelected ? 37 / 256f : 5 / 256f, rightSelected ? 59 / 256f : 27 / 256f + ); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0); + + String selectedPage = (currentPage + 1) + "/" + totalPages; + + FontRenderer fontRendererObj = Minecraft.getMinecraft().fontRendererObj; + Utils.drawStringCenteredScaledMaxWidth(selectedPage, fontRendererObj, + guiLeft + pageStringX, guiTop + pageStringY, false, 24, Color.BLACK.getRGB() + ); + } + + public static boolean onPageSwitch( + int guiLeft, + int guiTop, + int[] topLeft, + int currentPage, + int totalPages, + Consumer<Integer> pageChange + ) { + final ScaledResolution scaledresolution = new ScaledResolution(Minecraft.getMinecraft()); + final int scaledWidth = scaledresolution.getScaledWidth(); + final int scaledHeight = scaledresolution.getScaledHeight(); + int mouseX = Mouse.getX() * scaledWidth / Minecraft.getMinecraft().displayWidth; + int mouseY = scaledHeight - Mouse.getY() * scaledHeight / Minecraft.getMinecraft().displayHeight - 1; + + int buttonPositionLeftX = topLeft[0]; + int buttonPositionRightX = buttonPositionLeftX + BUTTON_POSITION_RIGHT_OFFSET_X; + int buttonPositionY = topLeft[1]; + + if (isWithinRect( + mouseX - guiLeft, + mouseY - guiTop, + buttonPositionLeftX, + buttonPositionY, + BUTTON_WIDTH, + BUTTON_HEIGHT + ) && + currentPage > 0) { + int newPage = currentPage - 1; + pageChange.accept(MathHelper.clamp_int(newPage, 0, totalPages - 1)); + Utils.playPressSound(); + return true; + } + + if (isWithinRect( + mouseX - guiLeft, + mouseY - guiTop, + buttonPositionRightX, + buttonPositionY, + BUTTON_WIDTH, + BUTTON_HEIGHT + ) && + currentPage < totalPages) { + int newPage = currentPage + 1; + pageChange.accept(MathHelper.clamp_int(newPage, 0, totalPages - 1)); + Utils.playPressSound(); + return true; + } + + return false; + } + + private static boolean isWithinRect(int x, int y, int topLeftX, int topLeftY, int width, int height) { + return topLeftX <= x && x < topLeftX + width + && topLeftY <= y && y < topLeftY + height; + } +} 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 d52f9ba1..b0b6e2db 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 @@ -63,4 +63,20 @@ public class StringUtils { str = str.replace(",", ""); return Integer.parseInt(str); } + + public static String removeLastWord(String string, String splitString) { + try { + String[] split = string.split(splitString); + String rawTier = split[split.length - 1]; + return string.substring(0, string.length() - rawTier.length() - 1); + } catch (StringIndexOutOfBoundsException e) { + throw new RuntimeException("removeLastWord: '" + string + "'", e); + } + } + + public static String firstUpperLetter(String text) { + if (text.isEmpty()) return text; + String firstLetter = ("" + text.charAt(0)).toUpperCase(); + return firstLetter + text.substring(1); + } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/infopanes/DevInfoPane.java b/src/main/java/io/github/moulberry/notenoughupdates/infopanes/DevInfoPane.java index a449919e..3c815016 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/infopanes/DevInfoPane.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/infopanes/DevInfoPane.java @@ -25,7 +25,6 @@ import io.github.moulberry.notenoughupdates.NEUOverlay; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.block.Block; -import net.minecraft.client.Minecraft; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.CraftingManager; @@ -33,7 +32,6 @@ import net.minecraft.item.crafting.IRecipe; import net.minecraft.item.crafting.ShapedRecipes; import net.minecraft.item.crafting.ShapelessRecipes; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.ChatComponentText; import net.minecraft.util.EnumChatFormatting; import net.minecraft.util.ResourceLocation; import net.minecraftforge.oredict.ShapedOreRecipe; @@ -688,7 +686,7 @@ public class DevInfoPane extends TextInfoPane { json.addProperty("modver", NotEnoughUpdates.VERSION); try { - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("Added: " + internalname)); + Utils.addChatMessage("Added: " + internalname); manager.writeJsonDefaultDir(json, internalname + ".json"); manager.loadItem(internalname); } catch (IOException ignored) { @@ -918,7 +916,7 @@ public class DevInfoPane extends TextInfoPane { json.addProperty("clickcommand", ""); try { - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("Added: " + internalname)); + Utils.addChatMessage("Added: " + internalname); manager.writeJsonDefaultDir(json, internalname + ".json"); manager.loadItem(internalname); } catch (IOException ignored) { @@ -951,7 +949,7 @@ public class DevInfoPane extends TextInfoPane { json.addProperty("clickcommand", "viewrecipe"); json.add("recipe", entry.getValue()); try { - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("Added: " + internalname)); + Utils.addChatMessage("Added: " + internalname); if (entry.getKey() != 0 && entry.getKey() < 32000) { manager.writeJsonDefaultDir(json, internalname + "-" + entry.getKey() + ".json"); } else { 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..ea7f2f5b 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/listener/ChatListener.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/listener/ChatListener.java @@ -160,11 +160,11 @@ public class ChatListener { String unformatted = Utils.cleanColour(e.message.getUnformattedText()); Matcher matcher = SLAYER_XP.matcher(unformatted); if (unformatted.startsWith("You are playing on profile: ")) { - neu.manager.setCurrentProfile(unformatted + SBInfo.getInstance().setCurrentProfile(unformatted .substring("You are playing on profile: ".length()) .split(" ")[0].trim()); } else if (unformatted.startsWith("Your profile was changed to: ")) {//Your profile was changed to: - neu.manager.setCurrentProfile(unformatted + SBInfo.getInstance().setCurrentProfile(unformatted .substring("Your profile was changed to: ".length()) .split(" ")[0].trim()); } else if (unformatted.startsWith("Your new API key is ")) { @@ -173,8 +173,7 @@ public class ChatListener { 0, 36 ); - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( - EnumChatFormatting.YELLOW + "[NEU] API Key automatically configured")); + Utils.addChatMessage(EnumChatFormatting.YELLOW + "[NEU] API Key automatically configured"); NotEnoughUpdates.INSTANCE.saveConfig(); } else if (unformatted.startsWith("Player List Info is now disabled!")) { SBInfo.getInstance().hasNewTab = false; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/listener/NEUEventListener.java b/src/main/java/io/github/moulberry/notenoughupdates/listener/NEUEventListener.java index 26c2d1f9..0add19f5 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/listener/NEUEventListener.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/listener/NEUEventListener.java @@ -290,35 +290,24 @@ public class NEUEventListener { if (!NotEnoughUpdates.INSTANCE.config.hidden.loadedModBefore) { NotEnoughUpdates.INSTANCE.config.hidden.loadedModBefore = true; if (Constants.MISC == null || !Constants.MISC.has("featureslist")) { - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( - "" + EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + "WARNING: " + EnumChatFormatting.RESET + - EnumChatFormatting.RED + "Could not load Feature List URL from repo.")); - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( - "" + EnumChatFormatting.RED + "Please run " + EnumChatFormatting.BOLD + "/neuresetrepo" + - EnumChatFormatting.RESET + EnumChatFormatting.RED + " and " + EnumChatFormatting.BOLD + - "restart your game" + EnumChatFormatting.RESET + EnumChatFormatting.RED + " in order to fix. " + - EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + "If that doesn't fix it" + - EnumChatFormatting.RESET + EnumChatFormatting.RED + - ", please join discord.gg/moulberry and post in #neu-support")); - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("")); - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( - "" + EnumChatFormatting.GOLD + "To view the feature list after restarting type /neufeatures")); + Utils.showOutdatedRepoNotification(); + Utils.addChatMessage( + "" + EnumChatFormatting.GOLD + "To view the feature list after restarting type /neufeatures"); } else { String url = Constants.MISC.get("featureslist").getAsString(); - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("")); - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( - EnumChatFormatting.BLUE + "It seems this is your first time using NotEnoughUpdates.")); + Utils.addChatMessage(""); + Utils.addChatMessage(EnumChatFormatting.BLUE + "It seems this is your first time using NotEnoughUpdates."); ChatComponentText clickTextFeatures = new ChatComponentText(EnumChatFormatting.YELLOW + "Click this message if you would like to view a list of NotEnoughUpdate's Features."); clickTextFeatures.setChatStyle(Utils.createClickStyle(ClickEvent.Action.OPEN_URL, url)); Minecraft.getMinecraft().thePlayer.addChatMessage(clickTextFeatures); } - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("")); + Utils.addChatMessage(""); ChatComponentText clickTextHelp = new ChatComponentText(EnumChatFormatting.YELLOW + "Click this message if you would like to view a list of NotEnoughUpdate's commands."); clickTextHelp.setChatStyle(Utils.createClickStyle(ClickEvent.Action.RUN_COMMAND, "/neuhelp")); Minecraft.getMinecraft().thePlayer.addChatMessage(clickTextHelp); - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("")); + Utils.addChatMessage(""); } } } 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 72a385f1..98207feb 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/listener/RenderListener.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/listener/RenderListener.java @@ -49,6 +49,7 @@ import io.github.moulberry.notenoughupdates.miscgui.GuiItemRecipe; import io.github.moulberry.notenoughupdates.miscgui.StorageOverlay; import io.github.moulberry.notenoughupdates.miscgui.TradeWindow; import io.github.moulberry.notenoughupdates.miscgui.TrophyRewardOverlay; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.MinionHelperManager; import io.github.moulberry.notenoughupdates.mixins.AccessorGuiContainer; import io.github.moulberry.notenoughupdates.options.NEUConfig; import io.github.moulberry.notenoughupdates.overlays.AuctionSearchOverlay; @@ -314,8 +315,7 @@ public class RenderListener { JsonObject json = neu.manager.getItemInformation().get(resInternalname); json.addProperty("crafttext", "Requires: " + col); - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( - "Added: " + resInternalname)); + Utils.addChatMessage("Added: " + resInternalname); neu.manager.writeJsonDefaultDir(json, resInternalname + ".json"); neu.manager.loadItem(resInternalname); } @@ -510,11 +510,17 @@ public class RenderListener { int diffX = 162; if (x > guiLeft + xSize && x < guiLeft + xSize + diffX + 5 && y > guiTop - 18 && y < guiTop + 120) { x += diffX; + } + } + if (MinionHelperManager.getInstance().inCraftedMinionsInventory()) { + int diffX = 172; + if (x > guiLeft + xSize && x < guiLeft + xSize + diffX + 5 && y > guiTop - 18 && y < guiTop + 128) { + x += diffX; } } if (AuctionProfit.inAuctionPage()) { - if (x + 18 > guiLeft + xSize && x + 18 < guiLeft + xSize + 4 + 28 + 20 && y > guiTop - 180 && - y < guiTop + 56) { + if (x + 18 > guiLeft + xSize && x + 18 < guiLeft + xSize + 4 + 28 + 20 && y > guiTop - 180 && + y < guiTop + 56) { x -= 68 - 200; } } @@ -633,9 +639,15 @@ public class RenderListener { x += diffX; } } + if (MinionHelperManager.getInstance().inCraftedMinionsInventory()) { + int diffX = 172; + if (x > guiLeft + xSize && x < guiLeft + xSize + diffX + 5 && y > guiTop - 18 && y < guiTop + 128) { + x += diffX; + } + } if (AuctionProfit.inAuctionPage()) { - if (x + 18 > guiLeft + xSize && x + 18 < guiLeft + xSize + 4 + 28 + 20 && y > guiTop - 180 && - y < guiTop + 56) { + if (x + 18 > guiLeft + xSize && x + 18 < guiLeft + xSize + 4 + 28 + 20 && y > guiTop - 180 && + y < guiTop + 56) { x -= 68 - 200; } } @@ -1054,9 +1066,15 @@ public class RenderListener { x += diffX; } } + if (MinionHelperManager.getInstance().inCraftedMinionsInventory()) { + int diffX = 172; + if (x > guiLeft + xSize && x < guiLeft + xSize + diffX + 5 && y > guiTop - 18 && y < guiTop + 128) { + x += diffX; + } + } if (AuctionProfit.inAuctionPage()) { - if (x + 18 > guiLeft + xSize && x + 18 < guiLeft + xSize + 4 + 28 + 20 && y > guiTop - 180 && - y < guiTop + 56) { + if (x + 18 > guiLeft + xSize && x + 18 < guiLeft + xSize + 4 + 28 + 20 && y > guiTop - 180 && + y < guiTop + 56) { x -= 68 - 200; } } @@ -1209,17 +1227,15 @@ public class RenderListener { )) ) { writer.write(gson.toJson(jsonObject)); - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( - EnumChatFormatting.AQUA + "Parsed and saved: " + EnumChatFormatting.WHITE + id)); + Utils.addChatMessage(EnumChatFormatting.AQUA + "Parsed and saved: " + EnumChatFormatting.WHITE + id); } } catch (IOException ignored) { - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( - EnumChatFormatting.RED + "Error while writing file.")); + Utils.addChatMessage(EnumChatFormatting.RED + "Error while writing file."); } } catch (Exception e) { e.printStackTrace(); - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( - EnumChatFormatting.RED + "Error while parsing inventory. Try again or check logs for details.")); + Utils.addChatMessage( + EnumChatFormatting.RED + "Error while parsing inventory. Try again or check logs for details."); } } } else if (Keyboard.isKeyDown(Keyboard.KEY_RETURN) && NotEnoughUpdates.INSTANCE.config.hidden.dev) { @@ -1314,8 +1330,7 @@ public class RenderListener { } else if (cachedDefinitions.containsKey(item)) { costArray.add(new JsonPrimitive(cachedDefinitions.get(item) + ":" + amountString)); } else { - mc.thePlayer.addChatMessage(new ChatComponentText( - "Change the item ID of " + item + " to the correct one and press Enter.")); + Utils.addChatMessage("Change the item ID of " + item + " to the correct one and press Enter."); NEUOverlay.getTextField().setText(item); event.setCanceled(true); typing = true; @@ -1344,17 +1359,16 @@ public class RenderListener { )) ) { writer.write(gson.toJson(newNPC)); - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( - EnumChatFormatting.AQUA + "Parsed and saved: " + EnumChatFormatting.WHITE + displayname)); + Utils.addChatMessage( + EnumChatFormatting.AQUA + "Parsed and saved: " + EnumChatFormatting.WHITE + displayname); } } catch (IOException ignored) { - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( - EnumChatFormatting.RED + "Error while writing file.")); + Utils.addChatMessage(EnumChatFormatting.RED + "Error while writing file."); } } catch (Exception e) { e.printStackTrace(); - mc.thePlayer.addChatMessage(new ChatComponentText( - EnumChatFormatting.RED + "Error while parsing inventory. Try again or check logs for details")); + Utils.addChatMessage( + EnumChatFormatting.RED + "Error while parsing inventory. Try again or check logs for details"); } } } else if (NotEnoughUpdates.INSTANCE.config.hidden.dev && Keyboard.isKeyDown(Keyboard.KEY_B) && @@ -1374,9 +1388,9 @@ public class RenderListener { if (stack.getDisplayName().isEmpty() || stack.getDisplayName().equals(" ")) continue; String internalName = NotEnoughUpdates.INSTANCE.manager.getInternalNameForItem(stack); if (internalName == null) { - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( + Utils.addChatMessage( EnumChatFormatting.RED + "ERROR: Could not get internal name for: " + EnumChatFormatting.AQUA + - stack.getDisplayName())); + stack.getDisplayName()); continue; } JsonObject itemObject = NotEnoughUpdates.INSTANCE.manager.getJsonForItem(stack); @@ -1396,13 +1410,11 @@ public class RenderListener { itemObject.add("lore", newLore); if (!NEUItemEditor.saveOnly(internalName, itemObject)) { - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( - EnumChatFormatting.RED + "ERROR: Failed to save item: " + EnumChatFormatting.AQUA + - stack.getDisplayName())); + Utils.addChatMessage( + EnumChatFormatting.RED + "ERROR: Failed to save item: " + EnumChatFormatting.AQUA + stack.getDisplayName()); } } - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( - EnumChatFormatting.AQUA + "Parsed page: " + lower.getDisplayName().getUnformattedText())); + Utils.addChatMessage(EnumChatFormatting.AQUA + "Parsed page: " + lower.getDisplayName().getUnformattedText()); event.setCanceled(true); return; } @@ -1594,7 +1606,7 @@ public class RenderListener { json.addProperty("clickcommand", "viewrecipe"); json.addProperty("modver", NotEnoughUpdates.VERSION); try { - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("Added: " + resInternalname)); + Utils.addChatMessage("Added: " + resInternalname); neu.manager.writeJsonDefaultDir(json, resInternalname + ".json"); neu.manager.loadItem(resInternalname); } catch (IOException ignored) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/listener/ScoreboardLocationChangeListener.java b/src/main/java/io/github/moulberry/notenoughupdates/listener/ScoreboardLocationChangeListener.java index 622b2088..3727a441 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/listener/ScoreboardLocationChangeListener.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/listener/ScoreboardLocationChangeListener.java @@ -31,10 +31,10 @@ public class ScoreboardLocationChangeListener { try { Thread.sleep(3000); TimersOverlay.afterPearls = TimersOverlay.heavyPearlCount(); - //Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW+"You exited the beast with ["+EnumChatFormatting.AQUA+(TimersOverlay.afterPearls-TimersOverlay.beforePearls)+EnumChatFormatting.YELLOW+"/"+EnumChatFormatting.AQUA+TimersOverlay.availablePearls+EnumChatFormatting.YELLOW+"] Heavy Pearls!")); + //Utils.sendMessageToPlayer(EnumChatFormatting.YELLOW+"You exited the beast with ["+EnumChatFormatting.AQUA+(TimersOverlay.afterPearls-TimersOverlay.beforePearls)+EnumChatFormatting.YELLOW+"/"+EnumChatFormatting.AQUA+TimersOverlay.availablePearls+EnumChatFormatting.YELLOW+"] Heavy Pearls!"); if (TimersOverlay.afterPearls - TimersOverlay.beforePearls == TimersOverlay.availablePearls) { NotEnoughUpdates.INSTANCE.config.getProfileSpecific().dailyHeavyPearlCompleted = System.currentTimeMillis(); - //Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.GREEN+"Daily "+EnumChatFormatting.DARK_AQUA+"Heavy Pearls"+EnumChatFormatting.GREEN+" Complete!")); + //Utils.sendMessageToPlayer(EnumChatFormatting.GREEN+"Daily "+EnumChatFormatting.DARK_AQUA+"Heavy Pearls"+EnumChatFormatting.GREEN+" Complete!"); } } catch (InterruptedException e) { e.printStackTrace(); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CookieWarning.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CookieWarning.java index f21d0c50..fede9bdf 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CookieWarning.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CookieWarning.java @@ -23,8 +23,8 @@ import com.google.common.collect.Lists; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.mixins.AccessorGuiPlayerTabOverlay; import io.github.moulberry.notenoughupdates.util.NotificationHandler; +import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; -import net.minecraft.util.ChatComponentText; import net.minecraft.util.EnumChatFormatting; public class CookieWarning { @@ -94,9 +94,8 @@ public class CookieWarning { } } catch (NumberFormatException e) { e.printStackTrace(); - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( - EnumChatFormatting.RED + - "NEU ran into an issue when retrieving the Booster Cookie Timer. Check the logs for details.")); + Utils.addChatMessage(EnumChatFormatting.RED + + "NEU ran into an issue when retrieving the Booster Cookie Timer. Check the logs for details."); hasNotified = true; } if (minutes < NotEnoughUpdates.INSTANCE.config.notifications.boosterCookieWarningMins && !hasNotified) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalMetalDetectorSolver.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalMetalDetectorSolver.java index 167b6a2f..93a80866 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalMetalDetectorSolver.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalMetalDetectorSolver.java @@ -25,10 +25,10 @@ import io.github.moulberry.notenoughupdates.core.util.render.RenderUtils; import io.github.moulberry.notenoughupdates.options.customtypes.NEUDebugFlag; import io.github.moulberry.notenoughupdates.util.NEUDebugLogger; import io.github.moulberry.notenoughupdates.util.SBInfo; +import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; import net.minecraft.entity.item.EntityArmorStand; import net.minecraft.util.BlockPos; -import net.minecraft.util.ChatComponentText; import net.minecraft.util.EnumChatFormatting; import net.minecraft.util.IChatComponent; import net.minecraft.util.Vec3i; @@ -169,7 +169,7 @@ public class CrystalMetalDetectorSolver { NEUDebugLogger.log(NEUDebugFlag.METAL, "Known location identified."); // falls through case FOUND: - mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "[NEU] Found solution.")); + Utils.addChatMessage(EnumChatFormatting.YELLOW + "[NEU] Found solution."); if (NotEnoughUpdates.INSTANCE.config.hidden.debugFlags.contains(NEUDebugFlag.METAL) && (previousState == SolutionState.INVALID || previousState == SolutionState.FAILED)) { NEUDebugLogger.log( @@ -180,14 +180,12 @@ public class CrystalMetalDetectorSolver { } break; case INVALID: - mc.thePlayer.addChatMessage(new ChatComponentText( - EnumChatFormatting.RED + "[NEU] Previous solution is invalid.")); + Utils.addChatMessage(EnumChatFormatting.RED + "[NEU] Previous solution is invalid."); logDiagnosticData(false); resetSolution(false); break; case FAILED: - mc.thePlayer.addChatMessage(new ChatComponentText( - EnumChatFormatting.RED + "[NEU] Failed to find a solution.")); + Utils.addChatMessage(EnumChatFormatting.RED + "[NEU] Failed to find a solution."); logDiagnosticData(false); resetSolution(false); break; @@ -195,8 +193,9 @@ public class CrystalMetalDetectorSolver { NEUDebugLogger.log(NEUDebugFlag.METAL, "Multiple known locations identified:"); // falls through case MULTIPLE: - mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + - "[NEU] Need another position to find solution. Possible blocks: " + possibleBlocks.size())); + Utils.addChatMessage( + EnumChatFormatting.YELLOW + "[NEU] Need another position to find solution. Possible blocks: " + + possibleBlocks.size()); break; default: throw new IllegalStateException("Metal detector is in invalid state"); @@ -372,8 +371,8 @@ public class CrystalMetalDetectorSolver { if (keeperEntities.size() == 0) { if (!visitKeeperMessagePrinted) { - mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + - "[NEU] Approach a Keeper while holding the metal detector to enable faster treasure hunting.")); + Utils.addChatMessage(EnumChatFormatting.YELLOW + + "[NEU] Approach a Keeper while holding the metal detector to enable faster treasure hunting."); visitKeeperMessagePrinted = true; } return false; @@ -387,8 +386,8 @@ public class CrystalMetalDetectorSolver { minesCenter = keeperEntity.getPosition().add(keeperOffsets.get(keeperType.toLowerCase())); NEUDebugLogger.log(NEUDebugFlag.METAL, "Mines center: " + EnumChatFormatting.WHITE + minesCenter.toString()); - mc.thePlayer.addChatMessage(new ChatComponentText( - EnumChatFormatting.YELLOW + "[NEU] Faster treasure hunting is now enabled based on Keeper location.")); + Utils.addChatMessage( + EnumChatFormatting.YELLOW + "[NEU] Faster treasure hunting is now enabled based on Keeper location."); return true; } @@ -560,8 +559,7 @@ public class CrystalMetalDetectorSolver { } if (!NotEnoughUpdates.INSTANCE.config.mining.metalDetectorEnabled) { - mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + - "[NEU] Metal Detector Solver is not enabled.")); + Utils.addChatMessage(EnumChatFormatting.RED + "[NEU] Metal Detector Solver is not enabled."); return; } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalWishingCompassSolver.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalWishingCompassSolver.java index 19cf9c09..9715e34b 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalWishingCompassSolver.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalWishingCompassSolver.java @@ -232,35 +232,35 @@ public class CrystalWishingCompassSolver { case SUCCESS: return; case STILL_PROCESSING_PRIOR_USE: - mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + - "[NEU] Wait a little longer before using the wishing compass again.")); + Utils.addChatMessage( + EnumChatFormatting.YELLOW + "[NEU] Wait a little longer before using the wishing compass again."); event.setCanceled(true); break; case LOCATION_TOO_CLOSE: - mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + - "[NEU] Move a little further before using the wishing compass again.")); + Utils.addChatMessage( + EnumChatFormatting.YELLOW + "[NEU] Move a little further before using the wishing compass again."); event.setCanceled(true); break; case POSSIBLE_TARGETS_CHANGED: - mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + - "[NEU] Possible wishing compass targets have changed. Solver has been reset.")); + Utils.addChatMessage( + EnumChatFormatting.YELLOW + "[NEU] Possible wishing compass targets have changed. Solver has been reset."); event.setCanceled(true); break; case NO_PARTICLES_FOR_PREVIOUS_COMPASS: - mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + - "[NEU] No particles detected for prior compass use. Need another position to solve.")); + Utils.addChatMessage(EnumChatFormatting.YELLOW + + "[NEU] No particles detected for prior compass use. Need another position to solve."); break; case PLAYER_IN_NUCLEUS: - mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + - "[NEU] Wishing compass must be used outside the nucleus for accurate results.")); + Utils.addChatMessage( + EnumChatFormatting.YELLOW + "[NEU] Wishing compass must be used outside the nucleus for accurate results."); event.setCanceled(true); break; default: throw new IllegalStateException("Unexpected wishing compass solver state: \n" + getDiagnosticMessage()); } } catch (Exception e) { - mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + - "[NEU] Error processing wishing compass action - see log for details")); + Utils.addChatMessage(EnumChatFormatting.RED + + "[NEU] Error processing wishing compass action - see log for details"); e.printStackTrace(); event.setCanceled(true); solverState = SolverState.FAILED_EXCEPTION; @@ -373,39 +373,36 @@ public class CrystalWishingCompassSolver { showSolution(); break; case FAILED_EXCEPTION: - mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + - "[NEU] Unable to determine wishing compass target.")); + Utils.addChatMessage(EnumChatFormatting.RED + "[NEU] Unable to determine wishing compass target."); logDiagnosticData(false); break; case FAILED_TIMEOUT_NO_REPEATING: - mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + - "[NEU] Timed out waiting for repeat set of compass particles.")); + Utils.addChatMessage( + EnumChatFormatting.RED + "[NEU] Timed out waiting for repeat set of compass particles."); logDiagnosticData(false); break; case FAILED_TIMEOUT_NO_PARTICLES: - mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + - "[NEU] Timed out waiting for compass particles.")); + Utils.addChatMessage(EnumChatFormatting.RED + "[NEU] Timed out waiting for compass particles."); logDiagnosticData(false); break; case FAILED_INTERSECTION_CALCULATION: - mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + - "[NEU] Unable to determine intersection of wishing compasses.")); + Utils.addChatMessage( + EnumChatFormatting.RED + "[NEU] Unable to determine intersection of wishing compasses."); logDiagnosticData(false); break; case FAILED_INVALID_SOLUTION: - mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + - "[NEU] Failed to find solution.")); + Utils.addChatMessage(EnumChatFormatting.RED + "[NEU] Failed to find solution."); logDiagnosticData(false); break; case NEED_SECOND_COMPASS: - mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + - "[NEU] Need another position to determine wishing compass target.")); + Utils.addChatMessage( + EnumChatFormatting.YELLOW + "[NEU] Need another position to determine wishing compass target."); break; } } } catch (Exception e) { - mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + - "[NEU] Exception while calculating wishing compass solution - see log for details")); + Utils.addChatMessage( + EnumChatFormatting.RED + "[NEU] Exception while calculating wishing compass solution - see log for details"); e.printStackTrace(); } } @@ -779,15 +776,14 @@ public class CrystalWishingCompassSolver { if (solution == null) return; if (NUCLEUS_BB.isVecInside(solution)) { - mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "[NEU] " + - EnumChatFormatting.AQUA + "Wishing compass target is the Crystal Nucleus")); + Utils.addChatMessage(EnumChatFormatting.YELLOW + "[NEU] " + EnumChatFormatting.AQUA + "Wishing compass target is the Crystal Nucleus"); return; } String destinationMessage = getWishingCompassDestinationsMessage(); if (!isSkytilsPresent) { - mc.thePlayer.addChatMessage(new ChatComponentText(destinationMessage)); + Utils.addChatMessage(destinationMessage); return; } @@ -797,13 +793,13 @@ public class CrystalWishingCompassSolver { String skytilsCommand = String.format("/sthw add %s %s", getSolutionCoordsText(), targetNameForSkytils); if (NotEnoughUpdates.INSTANCE.config.mining.wishingCompassAutocreateKnownWaypoints && solutionPossibleTargets.size() == 1) { - mc.thePlayer.addChatMessage(new ChatComponentText(destinationMessage)); + Utils.addChatMessage(destinationMessage); int commandResult = ClientCommandHandler.instance.executeCommand(mc.thePlayer, skytilsCommand); if (commandResult == 1) { return; } - mc.thePlayer.addChatMessage(new ChatComponentText( - EnumChatFormatting.RED + "[NEU] Failed to automatically run /sthw")); + Utils.addChatMessage( + EnumChatFormatting.RED + "[NEU] Failed to automatically run /sthw"); } destinationMessage += EnumChatFormatting.YELLOW + " [Add Skytils Waypoint]"; @@ -918,8 +914,8 @@ public class CrystalWishingCompassSolver { } if (!NotEnoughUpdates.INSTANCE.config.mining.wishingCompassSolver) { - mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + - "[NEU] Wishing Compass Solver is not enabled.")); + Utils.addChatMessage(EnumChatFormatting.RED + + "[NEU] Wishing Compass Solver is not enabled."); return; } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/FairySouls.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/FairySouls.java index 75f1b427..4cdb1557 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/FairySouls.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/FairySouls.java @@ -29,11 +29,11 @@ import io.github.moulberry.notenoughupdates.commands.ClientCommandBase; import io.github.moulberry.notenoughupdates.core.util.render.RenderUtils; import io.github.moulberry.notenoughupdates.util.Constants; import io.github.moulberry.notenoughupdates.util.SBInfo; +import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; import net.minecraft.command.CommandException; import net.minecraft.command.ICommandSender; import net.minecraft.util.BlockPos; -import net.minecraft.util.ChatComponentText; import net.minecraft.util.EnumChatFormatting; import net.minecraftforge.client.event.ClientChatReceivedEvent; import net.minecraftforge.client.event.RenderWorldLastEvent; @@ -370,7 +370,7 @@ public class FairySouls { } private static void print(String s) { - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(s)); + Utils.addChatMessage(s); } private static void printHelp() { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/Navigation.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/Navigation.java index 9cc872b7..3e37b522 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/Navigation.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/Navigation.java @@ -93,7 +93,7 @@ public class Navigation { } } - private NotEnoughUpdates neu; + private final NotEnoughUpdates neu; public Navigation(NotEnoughUpdates notEnoughUpdates) { neu = notEnoughUpdates; @@ -378,8 +378,7 @@ public class Navigation { private void showError(String message, boolean log) { EntityPlayerSP player = Minecraft.getMinecraft().thePlayer; if (player != null) - player.addChatMessage(new ChatComponentText(EnumChatFormatting.DARK_RED + - "[NEU-Waypoint] " + message)); + Utils.addChatMessage(EnumChatFormatting.DARK_RED + "[NEU-Waypoint] " + message); if (log) new RuntimeException("[NEU-Waypoint] " + message).printStackTrace(); } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/PetInfoOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/PetInfoOverlay.java index fa20b48a..344f21aa 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/PetInfoOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/PetInfoOverlay.java @@ -50,7 +50,6 @@ import net.minecraft.inventory.ContainerChest; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.ChatComponentText; import net.minecraft.util.EnumChatFormatting; import net.minecraftforge.client.event.ClientChatReceivedEvent; import net.minecraftforge.event.entity.player.ItemTooltipEvent; @@ -1290,9 +1289,9 @@ public class PetInfoOverlay extends TextOverlay { setCurrentPet(getClosestPetIndex(pet, rarity.petId, "", lastLevelHovered)); if (PetInfoOverlay.config.selectedPet == -1) { - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( + Utils.addChatMessage( EnumChatFormatting.RED + "[NEU] Can't find pet \u00a7" + petStringMatch + - EnumChatFormatting.RED + " try revisiting all pages of /pets.")); + EnumChatFormatting.RED + " try revisiting all pages of /pets."); } } else if ((chatMessage.toLowerCase().startsWith("you despawned your")) || (chatMessage.toLowerCase().contains( "switching to profile")) diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiItemRecipe.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiItemRecipe.java index 69343e99..8d075bd4 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiItemRecipe.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiItemRecipe.java @@ -21,6 +21,7 @@ package io.github.moulberry.notenoughupdates.miscgui; import com.google.common.collect.ImmutableList; import io.github.moulberry.notenoughupdates.NEUManager; +import io.github.moulberry.notenoughupdates.core.util.PageArrowsUtils; import io.github.moulberry.notenoughupdates.recipes.NeuRecipe; import io.github.moulberry.notenoughupdates.recipes.RecipeSlot; import io.github.moulberry.notenoughupdates.recipes.RecipeType; @@ -38,9 +39,7 @@ import net.minecraft.util.MathHelper; import net.minecraft.util.ResourceLocation; import org.lwjgl.input.Keyboard; import org.lwjgl.input.Mouse; -import org.lwjgl.opengl.GL11; -import java.awt.*; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; @@ -49,13 +48,10 @@ import java.util.List; import java.util.Map; public class GuiItemRecipe extends GuiScreen { - public static final ResourceLocation resourcePacksTexture = new ResourceLocation("textures/gui/resource_packs.png"); public static final ResourceLocation tabsTexture = new ResourceLocation("notenoughupdates", "textures/gui/tab.png"); public static final int SLOT_SIZE = 16; public static final int SLOT_SPACING = SLOT_SIZE + 2; - public static final int BUTTON_WIDTH = 7; - public static final int BUTTON_HEIGHT = 11; public static final int TITLE_X = 28; public static final int TITLE_Y = 6; public static final int HOTBAR_SLOT_X = 8; @@ -145,7 +141,8 @@ public class GuiItemRecipe extends GuiScreen { Utils.drawItemStack(slot.getItemStack(), slot.getX(this), slot.getY(this), true); } - drawArrows(currentRecipe, mouseX, mouseY); + int[] topLeft = currentRecipe.getPageFlipPositionLeftTopCorner(); + PageArrowsUtils.onDraw(guiLeft, guiTop, topLeft, currentIndex, getCurrentRecipeList().size()); Utils.drawStringScaledMaxWidth( currentRecipe.getTitle(), @@ -220,61 +217,6 @@ public class GuiItemRecipe extends GuiScreen { } } - public static final int BUTTON_POSITION_RIGHT_OFFSET_X = 37; - public static final int PAGE_STRING_OFFSET_X = 22; - public static final int PAGE_STRING_OFFSET_Y = 6; - - private void drawArrows( - NeuRecipe currentRecipe, - int mouseX, - int mouseY - ) { - int recipeCount = getCurrentRecipeList().size(); - if (recipeCount < 2) return; - int[] topLeft = currentRecipe.getPageFlipPositionLeftTopCorner(); - int buttonPositionLeftX = topLeft[0]; - int buttonPositionRightX = buttonPositionLeftX + BUTTON_POSITION_RIGHT_OFFSET_X; - int pageStringX = buttonPositionLeftX + PAGE_STRING_OFFSET_X; - int buttonPositionY = topLeft[1]; - int pageStringY = buttonPositionY + PAGE_STRING_OFFSET_Y; - - boolean leftSelected = isWithinRect( - mouseX - guiLeft, - mouseY - guiTop, - buttonPositionLeftX, - buttonPositionY, - BUTTON_WIDTH, - BUTTON_HEIGHT - ); - boolean rightSelected = isWithinRect( - mouseX - guiLeft, - mouseY - guiTop, - buttonPositionRightX, - buttonPositionY, - BUTTON_WIDTH, - BUTTON_HEIGHT - ); - Minecraft.getMinecraft().getTextureManager().bindTexture(resourcePacksTexture); - - if (currentIndex != 0) - Utils.drawTexturedRect(guiLeft + buttonPositionLeftX, guiTop + buttonPositionY, BUTTON_WIDTH, BUTTON_HEIGHT, - 34 / 256f, 48 / 256f, - leftSelected ? 37 / 256f : 5 / 256f, leftSelected ? 59 / 256f : 27 / 256f - ); - if (currentIndex != recipeCount - 1) - Utils.drawTexturedRect(guiLeft + buttonPositionRightX, guiTop + buttonPositionY, BUTTON_WIDTH, BUTTON_HEIGHT, - 10 / 256f, 24 / 256f, - rightSelected ? 37 / 256f : 5 / 256f, rightSelected ? 59 / 256f : 27 / 256f - ); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0); - - String selectedPage = (currentIndex + 1) + "/" + recipeCount; - - Utils.drawStringCenteredScaledMaxWidth(selectedPage, fontRendererObj, - guiLeft + pageStringX, guiTop + pageStringY, false, 24, Color.BLACK.getRGB() - ); - } - public List<RecipeSlot> getPlayerInventory() { List<RecipeSlot> slots = new ArrayList<>(); ItemStack[] inventory = Minecraft.getMinecraft().thePlayer.inventory.mainInventory; @@ -327,7 +269,7 @@ public class GuiItemRecipe extends GuiScreen { } @Override - protected void actionPerformed(GuiButton p_actionPerformed_1_) throws IOException { + protected void actionPerformed(GuiButton p_actionPerformed_1_) { getCurrentRecipe().actionPerformed(p_actionPerformed_1_); } @@ -336,52 +278,8 @@ public class GuiItemRecipe extends GuiScreen { super.mouseClicked(mouseX, mouseY, mouseButton); NeuRecipe currentRecipe = getCurrentRecipe(); int[] topLeft = currentRecipe.getPageFlipPositionLeftTopCorner(); - int buttonPositionLeftX = topLeft[0]; - int buttonPositionRightX = buttonPositionLeftX + BUTTON_POSITION_RIGHT_OFFSET_X; - int buttonPositionY = topLeft[1]; - - if (isWithinRect( - mouseX - guiLeft, - mouseY - guiTop, - buttonPositionLeftX, - buttonPositionY, - BUTTON_WIDTH, - BUTTON_HEIGHT - ) && - currentIndex > 0) { - changeRecipe(currentTab, currentIndex - 1); - Utils.playPressSound(); - return; - } - - if (isWithinRect( - mouseX - guiLeft, - mouseY - guiTop, - buttonPositionRightX, - buttonPositionY, - BUTTON_WIDTH, - BUTTON_HEIGHT - ) && - currentIndex < getCurrentRecipeList().size()) { - changeRecipe(currentTab, currentIndex + 1); - Utils.playPressSound(); - return; - } - - for (int i = 0; i < tabs.size(); i++) { - if (isWithinRect( - mouseX - guiLeft, - mouseY - guiTop, - TAB_POS_X, - TAB_POS_Y + TAB_OFFSET_Y * i, - TAB_SIZE_X, - TAB_SIZE_Y - )) { - changeRecipe(i, currentIndex); - Utils.playPressSound(); - return; - } - } + PageArrowsUtils.onPageSwitch(guiLeft, guiTop, topLeft, currentIndex, getCurrentRecipeList().size(), pageChange -> + changeRecipe(currentTab, pageChange)); for (RecipeSlot slot : getAllRenderedSlots()) { if (isWithinRect(mouseX, mouseY, slot.getX(this), slot.getY(this), SLOT_SIZE, SLOT_SIZE)) { 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 df635d5c..a3a65dce 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/TrophyRewardOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/TrophyRewardOverlay.java @@ -163,7 +163,7 @@ public class TrophyRewardOverlay { texts.add("Trophy Fish Exchange"); texts.add("Magma Fish: §e" + total); - for (Map.Entry<String, Integer> entry : sortByValue(totalExchange).entrySet()) { + for (Map.Entry<String, Integer> entry : sortByValueReverse(totalExchange).entrySet()) { String name = entry.getKey(); int amount = totalAmount.get(name); String[] split = name.split(" "); @@ -209,6 +209,19 @@ public class TrophyRewardOverlay { public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map) { List<Map.Entry<K, V>> list = new ArrayList<>(map.entrySet()); list.sort(Map.Entry.comparingByValue()); + + Map<K, V> result = new LinkedHashMap<>(); + for (Map.Entry<K, V> entry : list) { + result.put(entry.getKey(), entry.getValue()); + } + + return result; + } + + //TODO move into utils class maybe? + public static <K, V extends Comparable<? super V>> Map<K, V> sortByValueReverse(Map<K, V> map) { + List<Map.Entry<K, V>> list = new ArrayList<>(map.entrySet()); + list.sort(Map.Entry.comparingByValue()); Collections.reverse(list); Map<K, V> result = new LinkedHashMap<>(); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/ApiData.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/ApiData.java new file mode 100644 index 00000000..1155884b --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/ApiData.java @@ -0,0 +1,73 @@ +/* + * 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.miscgui.minionhelper; + +import java.util.List; +import java.util.Map; + +public class ApiData { + + private final Map<String, Integer> highestCollectionTier; + private final Map<String, Integer> slayerTiers; + private final int magesReputation; + private final int barbariansReputation; + private final boolean collectionApiDisabled; + private final List<String> craftedMinions; + + public ApiData( + Map<String, Integer> highestCollectionTier, + Map<String, Integer> slayerTiers, + int magesReputation, + int barbariansReputation, + boolean collectionApiDisabled, + List<String> craftedMinions + ) { + this.highestCollectionTier = highestCollectionTier; + this.slayerTiers = slayerTiers; + this.magesReputation = magesReputation; + this.barbariansReputation = barbariansReputation; + this.collectionApiDisabled = collectionApiDisabled; + this.craftedMinions = craftedMinions; + } + + public Map<String, Integer> getHighestCollectionTier() { + return highestCollectionTier; + } + + public Map<String, Integer> getSlayerTiers() { + return slayerTiers; + } + + public int getMagesReputation() { + return magesReputation; + } + + public int getBarbariansReputation() { + return barbariansReputation; + } + + public boolean isCollectionApiDisabled() { + return collectionApiDisabled; + } + + public List<String> getCraftedMinions() { + return craftedMinions; + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/Minion.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/Minion.java new file mode 100644 index 00000000..ba38b01d --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/Minion.java @@ -0,0 +1,112 @@ +/* + * 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.miscgui.minionhelper; + +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.render.renderables.OverviewLine; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.requirements.MinionRequirement; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.sources.CustomSource; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.sources.MinionSource; + +import java.util.ArrayList; +import java.util.List; + +public class Minion extends OverviewLine { + private final String internalName; + private final int tier; + private String displayName; + private MinionSource minionSource; + private CustomSource customSource; + private Minion parent; + private final List<MinionRequirement> requirements = new ArrayList<>(); + + private boolean crafted = false; + private boolean meetRequirements = false; + + public Minion(String internalName, int tier) { + this.internalName = internalName; + this.tier = tier; + } + + public MinionSource getMinionSource() { + return minionSource; + } + + public void setMinionSource(MinionSource minionSource) { + this.minionSource = minionSource; + } + + public String getDisplayName() { + return displayName; + } + + public void setDisplayName(String displayName) { + this.displayName = displayName; + } + + public boolean isCrafted() { + return crafted; + } + + public void setCrafted(boolean crafted) { + this.crafted = crafted; + } + + public String getInternalName() { + return internalName; + } + + public void setParent(Minion parent) { + this.parent = parent; + } + + public Minion getParent() { + return parent; + } + + public int getTier() { + return tier; + } + + public List<MinionRequirement> getRequirements() { + return requirements; + } + + public boolean doesMeetRequirements() { + return meetRequirements; + } + + public void setMeetRequirements(boolean meetRequirements) { + this.meetRequirements = meetRequirements; + } + + @Override + public void onClick() { + NotEnoughUpdates.INSTANCE.manager.displayGuiItemRecipe(internalName); + } + + public void setCustomSource(CustomSource customSource) { + this.customSource = customSource; + } + + public CustomSource getCustomSource() { + return customSource; + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/MinionHelperManager.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/MinionHelperManager.java new file mode 100644 index 00000000..6d7c9daa --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/MinionHelperManager.java @@ -0,0 +1,261 @@ +/* + * 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.miscgui.minionhelper; + +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.loaders.MinionHelperApiLoader; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.loaders.MinionHelperChatLoader; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.loaders.MinionHelperInventoryLoader; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.loaders.repo.MinionHelperRepoLoader; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.render.MinionHelperOverlay; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.render.MinionHelperTooltips; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.sources.CustomSource; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.sources.MinionSource; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.util.MinionHelperPriceCalculation; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.util.MinionHelperRequirementsManager; +import io.github.moulberry.notenoughupdates.util.Utils; +import net.minecraft.client.Minecraft; +import net.minecraft.inventory.Container; +import net.minecraft.inventory.ContainerChest; +import net.minecraftforge.common.MinecraftForge; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class MinionHelperManager { + private static MinionHelperManager instance = null; + private final Map<String, Minion> minions = new HashMap<>(); + private int needForNextSlot = -1; + + private final MinionHelperPriceCalculation priceCalculation = new MinionHelperPriceCalculation(this); + private final MinionHelperRequirementsManager requirementsManager = new MinionHelperRequirementsManager(this); + private final MinionHelperApiLoader api = new MinionHelperApiLoader(this); + private final MinionHelperRepoLoader repo = new MinionHelperRepoLoader(this); + private final MinionHelperOverlay overlay = new MinionHelperOverlay(this); + private final MinionHelperTooltips tooltips = new MinionHelperTooltips(this); + private final MinionHelperChatLoader chatLoader = new MinionHelperChatLoader(this); + private final MinionHelperInventoryLoader inventoryLoader = new MinionHelperInventoryLoader(this); + + public static MinionHelperManager getInstance() { + if (instance == null) { + instance = new MinionHelperManager(); + } + return instance; + } + + private MinionHelperManager() { + MinecraftForge.EVENT_BUS.register(priceCalculation); + MinecraftForge.EVENT_BUS.register(api); + MinecraftForge.EVENT_BUS.register(repo); + MinecraftForge.EVENT_BUS.register(overlay); + MinecraftForge.EVENT_BUS.register(tooltips); + MinecraftForge.EVENT_BUS.register(chatLoader); + MinecraftForge.EVENT_BUS.register(inventoryLoader); + } + + public boolean inCraftedMinionsInventory() { + if (!NotEnoughUpdates.INSTANCE.isOnSkyblock()) return false; + + Minecraft minecraft = Minecraft.getMinecraft(); + if (minecraft == null || minecraft.thePlayer == null) return false; + + Container inventoryContainer = minecraft.thePlayer.openContainer; + if (!(inventoryContainer instanceof ContainerChest)) return false; + ContainerChest containerChest = (ContainerChest) inventoryContainer; + return containerChest.getLowerChestInventory().getDisplayName() + .getUnformattedText().equalsIgnoreCase("Crafted Minions"); + } + + public boolean isReadyToUse() { + return repo.isRepoReadyToUse() && api.isApiReadyToUse(); + } + + public Minion getMinionById(String internalName) { + if (minions.containsKey(internalName)) { + return minions.get(internalName); + } else { + System.err.println("Cannot get minion for id '" + internalName + "'!"); + return null; + } + } + + public Minion getMinionByName(String displayName, int tier) { + for (Minion minion : minions.values()) { + if (displayName.equals(minion.getDisplayName())) { + if (minion.getTier() == tier) { + return minion; + } + } + } + System.err.println("Cannot get minion for display name '" + displayName + "'!"); + return null; + } + + public void createMinion(String internalName, int tier) { + minions.put(internalName, new Minion(internalName, tier)); + } + + public String formatInternalName(String minionName) { + return minionName.toUpperCase().replace(" ", "_"); + } + + public List<Minion> getChildren(Minion minion) { + List<Minion> list = new ArrayList<>(); + for (Minion other : minions.values()) { + if (minion == other.getParent()) { + list.add(other); + list.addAll(getChildren(other)); + break; + } + } + return list; + } + + public void onProfileSwitch() { + for (Minion minion : minions.values()) { + minion.setCrafted(false); + minion.setMeetRequirements(false); + } + + needForNextSlot = -1; + api.onProfileSwitch(); + overlay.onProfileSwitch(); + inventoryLoader.onProfileSwitch(); + } + + public void reloadData() { + requirementsManager.reloadRequirements(); + + ApiData apiData = api.getApiData(); + if (apiData != null) { + for (String minion : apiData.getCraftedMinions()) { + getMinionById(minion).setCrafted(true); + } + } + } + + public void handleCommand(String[] args) { + if (!NotEnoughUpdates.INSTANCE.config.minionHelper.gui) { + Utils.addChatMessage("§e[NEU] Minion Helper gui is disabled!"); + return; + } + + if (args.length > 1) { + String parameter = args[1]; + + if (args.length == 2) { + if (parameter.equals("clearminion")) { + minions.clear(); + Utils.addChatMessage("minion map cleared"); + return; + } + if (parameter.equals("reloadrepo")) { + repo.setDirty(); + Utils.addChatMessage("repo reload requested"); + return; + } + if (parameter.equals("reloadapi")) { + api.resetData(); + api.setDirty(); + Utils.addChatMessage("api reload requested"); + return; + } + if (parameter.equals("clearapi")) { + api.resetData(); + Utils.addChatMessage("api data cleared"); + return; + } + } + + if (args.length == 3) { + if (parameter.equals("maxperpage")) { + api.resetData(); + int maxPerPage = Integer.parseInt(args[2]); + Utils.addChatMessage("set max per page to " + maxPerPage); + overlay.setMaxPerPage(maxPerPage); + return; + } + } + + if (args.length == 4) { + if (parameter.equals("arrowpos")) { + int x = Integer.parseInt(args[2]); + int y = Integer.parseInt(args[3]); + Utils.addChatMessage("set page pos to " + x + ";" + y); + overlay.setTopLeft(new int[]{x, y}); + return; + } + } + } + + Utils.addChatMessage(""); + Utils.addChatMessage("§3NEU Minion Helper commands: §c(for testing only!)"); + Utils.addChatMessage("§6/neudevtest minion clearminion §7Clears the minion map"); + Utils.addChatMessage("§6/neudevtest minion reloadrepo §7Manually loading the data from repo"); + Utils.addChatMessage("§6/neudevtest minion reloadapi §7Manually loading the data from api"); + Utils.addChatMessage("§6/neudevtest minion clearapi §7Clears the api data"); + Utils.addChatMessage("§6/neudevtest minion maxperpage <number> §7Changes the max minions per page number"); + Utils.addChatMessage("§6/neudevtest minion arrowpos <x, y> §7Changes the position of the page numbers"); + Utils.addChatMessage(""); + } + + public MinionHelperPriceCalculation getPriceCalculation() { + return priceCalculation; + } + + public MinionHelperRequirementsManager getRequirementsManager() { + return requirementsManager; + } + + public MinionHelperApiLoader getApi() { + return api; + } + + public MinionHelperRepoLoader getRepo() { + return repo; + } + + public MinionHelperOverlay getOverlay() { + return overlay; + } + + public Map<String, Minion> getAllMinions() { + return minions; + } + + public void setNeedForNextSlot(int needForNextSlot) { + this.needForNextSlot = needForNextSlot; + overlay.resetCache(); + } + + public int getNeedForNextSlot() { + return needForNextSlot; + } + + public void setCustomSource(Minion minion, CustomSource customSource) { + MinionSource minionSource = minion.getMinionSource(); + if (minionSource == null) { + minion.setMinionSource(customSource); + } + minion.setCustomSource(customSource); + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/MinionHelperApiLoader.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/MinionHelperApiLoader.java new file mode 100644 index 00000000..b1a4ba06 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/MinionHelperApiLoader.java @@ -0,0 +1,269 @@ +/* + * 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.miscgui.minionhelper.loaders; + +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.miscgui.minionhelper.ApiData; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.MinionHelperManager; +import io.github.moulberry.notenoughupdates.profileviewer.ProfileViewer; +import io.github.moulberry.notenoughupdates.util.Constants; +import io.github.moulberry.notenoughupdates.util.SBInfo; +import io.github.moulberry.notenoughupdates.util.Utils; +import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.EntityPlayerSP; +import net.minecraft.item.ItemStack; +import net.minecraftforge.event.world.WorldEvent; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.gameevent.TickEvent; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +public class MinionHelperApiLoader { + private final MinionHelperManager manager; + private boolean dirty = true; + private int ticks = 0; + private boolean collectionApiEnabled = true; + private boolean ignoreWorldSwitches = false; + private boolean apiReadyToUse = false; + private ApiData apiData = null; + private boolean notifyNoCollectionApi = false; + + public MinionHelperApiLoader(MinionHelperManager manager) { + this.manager = manager; + } + + @SubscribeEvent + public void onWorldLoad(WorldEvent.Load event) { + if (ignoreWorldSwitches) return; + + setDirty(); + } + + @SubscribeEvent + public void onTick(TickEvent.ClientTickEvent event) { + if (Minecraft.getMinecraft().thePlayer == null) return; + if (!NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) return; + if (!NotEnoughUpdates.INSTANCE.config.minionHelper.gui) return; + ticks++; + + if (ticks % 20 != 0) return; + + if (dirty) { + load(); + } + } + + private void load() { + EntityPlayerSP thePlayer = Minecraft.getMinecraft().thePlayer; + if (thePlayer == null) return; + + dirty = false; + String uuid = thePlayer.getUniqueID().toString().replace("-", ""); + HashMap<String, String> map = new HashMap<String, String>() {{ + put("uuid", uuid); + }}; + + NotEnoughUpdates neu = NotEnoughUpdates.INSTANCE; + neu.manager.hypixelApi.getHypixelApiAsync( + neu.config.apiData.apiKey, + "skyblock/profiles", + map + ).thenAccept(this::updateInformation); + } + + private void updateInformation(JsonObject entireApiResponse) { + if (!entireApiResponse.has("success") || !entireApiResponse.get("success").getAsBoolean()) return; + JsonArray profiles = entireApiResponse.getAsJsonArray("profiles"); + for (JsonElement element : profiles) { + JsonObject profile = element.getAsJsonObject(); + String profileName = profile.get("cute_name").getAsString(); + JsonObject members = profile.getAsJsonObject("members"); + JsonObject player = members.getAsJsonObject(Minecraft.getMinecraft().thePlayer + .getUniqueID() + .toString() + .replace("-", "")); + + if (profileName.equals(SBInfo.getInstance().currentProfile)) { + readData(player, members); + return; + } + } + } + + private void readData(JsonObject player, JsonObject members) { + int magesReputation = 0; + int barbariansReputation = 0; + if (player.has("nether_island_player_data")) { + JsonObject netherData = player.getAsJsonObject("nether_island_player_data"); + if (netherData.has("mages_reputation")) { + magesReputation = netherData.get("mages_reputation").getAsInt(); + } + if (netherData.has("barbarians_reputation")) { + barbariansReputation = netherData.get("barbarians_reputation").getAsInt(); + } + } + + apiData = new ApiData( + getCollections(player), + getSlayers(player), + magesReputation, + barbariansReputation, + !collectionApiEnabled, + loadCraftedMinions(members) + ); + + manager.reloadData(); + apiReadyToUse = true; + } + + private Map<String, Integer> getSlayers(JsonObject player) { + JsonObject slayerLeveling = Constants.LEVELING.getAsJsonObject("slayer_xp"); + + Map<String, Integer> slayerTier = new HashMap<>(); + if (player.has("slayer_bosses")) { + JsonObject slayerBosses = player.getAsJsonObject("slayer_bosses"); + for (Map.Entry<String, JsonElement> entry : slayerBosses.entrySet()) { + String name = entry.getKey(); + JsonObject slayerEntry = entry.getValue().getAsJsonObject(); + if (slayerEntry.has("xp")) { + long xp = slayerEntry.get("xp").getAsLong(); + + int tier = 0; + for (JsonElement element : slayerLeveling.getAsJsonArray(name)) { + int needForLevel = element.getAsInt(); + if (xp >= needForLevel) { + tier++; + } else { + break; + } + } + slayerTier.put(name, tier); + } + } + } + return slayerTier; + } + + private Map<String, Integer> getCollections(JsonObject player) { + Map<String, Integer> highestCollectionTier = new HashMap<>(); + if (player.has("unlocked_coll_tiers")) { + for (JsonElement element : player.get("unlocked_coll_tiers").getAsJsonArray()) { + String text = element.getAsString(); + String[] split = text.split("_"); + int level = Integer.parseInt(split[split.length - 1]); + String name = StringUtils.removeLastWord(text, "_"); + + //Because skyblock is good in naming things + LinkedHashMap<String, ItemStack> collectionMap = ProfileViewer.getCollectionToCollectionDisplayMap(); + if (collectionMap.containsKey(name)) { + ItemStack itemStack = collectionMap.get(name); + String displayName = itemStack.getDisplayName(); + name = Utils.cleanColour(displayName); + name = manager.formatInternalName(name); + } else { + //Doing this since there is no space in the profile viewer gui for more entries in collectionToCollectionDisplayMap + if (name.equals("SAND:1")) name = "RED_SAND"; + if (name.equals("MYCEL")) name = "MYCELIUM"; + } + + level = Math.max(highestCollectionTier.getOrDefault(name, 0), level); + highestCollectionTier.put(name, level); + } + if (!collectionApiEnabled) { + Utils.addChatMessage("§e[NEU] Collection API detected!"); + } + collectionApiEnabled = true; + } else { + if (collectionApiEnabled) { + notifyNoCollectionApi = true; + } + collectionApiEnabled = false; + } + return highestCollectionTier; + } + + private List<String> loadCraftedMinions(JsonObject members) { + List<String> craftedMinions = new ArrayList<>(); + for (Map.Entry<String, JsonElement> entry : members.entrySet()) { + JsonObject value = entry.getValue().getAsJsonObject(); + if (value.has("crafted_generators")) { + for (JsonElement e : value.get("crafted_generators").getAsJsonArray()) { + String rawGenerator = e.getAsString(); + String[] split = rawGenerator.split("_"); + String tier = split[split.length - 1]; + String name = rawGenerator.substring(0, rawGenerator.length() - tier.length() - 1); + String internalName = name + "_GENERATOR_" + tier; + craftedMinions.add(internalName); + } + } + } + + return craftedMinions; + } + + public void setDirty() { + dirty = true; + apiReadyToUse = false; + } + + public void prepareProfileSwitch() { + ignoreWorldSwitches = true; + apiReadyToUse = false; + } + + public void onProfileSwitch() { + apiData = null; + setDirty(); + ignoreWorldSwitches = false; + collectionApiEnabled = true; + } + + public boolean isApiReadyToUse() { + return apiReadyToUse; + } + + public ApiData getApiData() { + return apiData; + } + + public boolean isCollectionApiDisabled() { + return apiData != null && apiData.isCollectionApiDisabled(); + } + + public void resetData() { + apiData = null; + } + + public void setNotifyNoCollectionApi(boolean notifyNoCollectionApi) { + this.notifyNoCollectionApi = notifyNoCollectionApi; + } + + public boolean isNotifyNoCollectionApi() { + return notifyNoCollectionApi; + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/MinionHelperChatLoader.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/MinionHelperChatLoader.java new file mode 100644 index 00000000..592ebc0e --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/MinionHelperChatLoader.java @@ -0,0 +1,87 @@ +/* + * 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.miscgui.minionhelper.loaders; + +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.core.util.StringUtils; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.Minion; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.MinionHelperManager; +import io.github.moulberry.notenoughupdates.util.Utils; +import net.minecraftforge.client.event.ClientChatReceivedEvent; +import net.minecraftforge.fml.common.eventhandler.EventPriority; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; + +public class MinionHelperChatLoader { + + private final MinionHelperManager manager; + + public MinionHelperChatLoader(MinionHelperManager manager) { + this.manager = manager; + } + + @SubscribeEvent(priority = EventPriority.LOW, receiveCanceled = true) + public void onChat(ClientChatReceivedEvent event) { + if (event.type != 0) return; + String message = event.message.getFormattedText(); + if (!NotEnoughUpdates.INSTANCE.config.minionHelper.gui) return; + + try { + if (message.startsWith("§r§aYou crafted a §eTier ") && message.contains("§a! That's a new one!")) { + String text = StringUtils.substringBetween(message, "§eTier ", "§a! That's"); + String rawTier = text.split(" ")[0]; + int tier = Utils.parseRomanNumeral(rawTier); + String name = text.substring(rawTier.length() + 1); + + setCrafted(manager.getMinionByName(name, tier)); + } + + if (message.contains("§f §acrafted a §eTier ") && message.contains(" Minion§a!")) { + String text = StringUtils.substringBetween(message, "§eTier ", "§a!"); + String rawTier = text.split(" ")[0]; + int tier = Utils.parseRomanNumeral(rawTier); + String name = text.substring(rawTier.length() + 1); + + setCrafted(manager.getMinionByName(name, tier)); + manager.getOverlay().resetCache(); + } + + if (message.startsWith("§r§7Switching to profile ")) { + manager.getApi().prepareProfileSwitch(); + } + + } catch (Exception e) { + Utils.addChatMessage( + "[NEU] §cMinion Helper failed reading the minion upgrade message. See the logs for more info!"); + e.printStackTrace(); + } + } + + private void setCrafted(Minion minion) { + minion.setCrafted(true); + + if (!minion.doesMeetRequirements()) { + minion.setMeetRequirements(true); + + for (Minion child : manager.getChildren(minion)) { + child.setMeetRequirements(true); + } + } + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/MinionHelperInventoryLoader.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/MinionHelperInventoryLoader.java new file mode 100644 index 00000000..3ff5a9c8 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/MinionHelperInventoryLoader.java @@ -0,0 +1,146 @@ +/* + * 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.miscgui.minionhelper.loaders; + +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.core.util.StringUtils; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.Minion; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.MinionHelperManager; +import io.github.moulberry.notenoughupdates.util.ItemUtils; +import net.minecraft.client.Minecraft; +import net.minecraft.inventory.Container; +import net.minecraft.inventory.ContainerChest; +import net.minecraft.inventory.Slot; +import net.minecraft.item.ItemStack; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.gameevent.TickEvent; + +import java.util.ArrayList; +import java.util.List; + +public class MinionHelperInventoryLoader { + private final MinionHelperManager manager; + private final List<String> pagesSeenAlready = new ArrayList<>(); + private boolean shouldCheckNextSlot = true; + + private int ticks = 0; + + public MinionHelperInventoryLoader(MinionHelperManager manager) { + this.manager = manager; + } + + @SubscribeEvent + public void onTick(TickEvent.ClientTickEvent event) { + if (!NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) return; + if (!NotEnoughUpdates.INSTANCE.config.minionHelper.gui) return; + if (!manager.isReadyToUse()) return; + ticks++; + + if (ticks % 5 != 0) return; + + if (manager.inCraftedMinionsInventory()) { + checkInventory(); + } else { + pagesSeenAlready.clear(); + if (shouldCheckNextSlot) { + shouldCheckNextSlot = true; + } + } + } + + private void checkInventory() { + Container openContainer = Minecraft.getMinecraft().thePlayer.openContainer; + if (openContainer instanceof ContainerChest) { + + if (shouldCheckNextSlot) { + shouldCheckNextSlot = false; + checkNextSlot(openContainer); + } + + loadMinionData(openContainer); + } + } + + private void checkNextSlot(Container openContainer) { + Slot informationSlot = openContainer.inventorySlots.get(50); + if (informationSlot.getHasStack()) { + ItemStack informationStack = informationSlot.getStack(); + for (String line : ItemUtils.getLore(informationStack)) { + if (line.contains("§aunique")) { + String[] split = line.split(" "); + int needForNextSlot = Integer.parseInt(StringUtils.cleanColour(split[1])); + manager.setNeedForNextSlot(needForNextSlot); + return; + } + } + } + } + + private void loadMinionData(Container openContainer) { + Slot firstSlot = openContainer.inventorySlots.get(10); + boolean shouldLoad = false; + if (firstSlot != null) { + if (firstSlot.getHasStack()) { + ItemStack stack = firstSlot.getStack(); + String displayName = stack.getDisplayName(); + if (!pagesSeenAlready.contains(displayName)) { + pagesSeenAlready.add(displayName); + shouldLoad = true; + } + } + } + + if (!shouldLoad) return; + + int crafted = 0; + for (Slot slot : openContainer.inventorySlots) { + if (!slot.getHasStack()) continue; + ItemStack stack = slot.getStack(); + if (stack == null) continue; + if (slot.slotNumber != slot.getSlotIndex()) continue; + + String displayName = stack.getDisplayName(); + if (!displayName.contains(" Minion")) continue; + + displayName = StringUtils.cleanColour(displayName); + int index = 0; + for (String line : ItemUtils.getLore(stack)) { + index++; + if (!line.contains("Tier")) { + continue; + } + if (line.contains("§a")) { + Minion minion = manager.getMinionByName(displayName, index); + if (!minion.isCrafted()) { + minion.setCrafted(true); + crafted++; + } + } + } + } + if (crafted > 0) { + manager.getOverlay().resetCache(); + } + } + + public void onProfileSwitch() { + shouldCheckNextSlot = true; + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/repo/MinionHelperRepoLoader.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/repo/MinionHelperRepoLoader.java new file mode 100644 index 00000000..2eed2958 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/repo/MinionHelperRepoLoader.java @@ -0,0 +1,247 @@ +/* + * 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.miscgui.minionhelper.loaders.repo; + +import com.google.common.collect.ArrayListMultimap; +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.miscgui.minionhelper.Minion; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.MinionHelperManager; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.requirements.CustomRequirement; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.sources.CustomSource; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.sources.NpcSource; +import io.github.moulberry.notenoughupdates.util.Constants; +import io.github.moulberry.notenoughupdates.util.Utils; +import net.minecraft.client.Minecraft; +import net.minecraftforge.fml.common.eventhandler.EventPriority; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.gameevent.TickEvent; + +import java.util.HashMap; +import java.util.Map; +import java.util.TreeMap; + +public class MinionHelperRepoLoader { + private final MinionHelperManager manager; + private boolean dirty = true; + private int ticks = 0; + private final Map<String, String> displayNameCache = new HashMap<>(); + private boolean repoReadyToUse = false; + private final MinionHelperRepoMinionLoader minionLoader; + boolean errorWhileLoading = false; + + public MinionHelperRepoLoader(MinionHelperManager manager) { + this.manager = manager; + minionLoader = new MinionHelperRepoMinionLoader(this, manager); + } + + /** + * This adds support for the /neureloadrepo command + */ + @SubscribeEvent(priority = EventPriority.LOWEST) + public void onRepoReload(RepositoryReloadEvent event) { + setDirty(); + } + + @SubscribeEvent + public void onTick(TickEvent.ClientTickEvent event) { + if (Minecraft.getMinecraft().thePlayer == null) return; + if (!NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) return; + if (!NotEnoughUpdates.INSTANCE.config.minionHelper.gui) return; + ticks++; + + if (ticks % 5 != 0) return; + + if (dirty) { + dirty = false; + load(); + } + } + + void load() { + errorWhileLoading = false; + + createMinions(); + + loadNpcData(); + minionLoader.loadMinionData(); + loadCustomSources(); + + testForMissingData(); + + manager.reloadData(); + repoReadyToUse = true; + + if (errorWhileLoading) { + Utils.showOutdatedRepoNotification(); + } + } + + private void loadCustomSources() { + Map<String, String> customSource = new HashMap<>(); + + customSource.put("SNOW_GENERATOR_1", "Gifts"); + + customSource.put("FLOWER_GENERATOR_1", "Dark Auction"); + + customSource.put("REVENANT_GENERATOR_1", "Zombie Slayer"); + customSource.put("TARANTULA_GENERATOR_1", "Spider Slayer"); + + for (Map.Entry<String, String> entry : customSource.entrySet()) { + String internalName = entry.getKey(); + String sourceName = entry.getValue(); + Minion minion = manager.getMinionById(internalName); + if (minion == null) continue; + manager.setCustomSource(minion, new CustomSource(sourceName)); + } + + manager.getMinionById("FLOWER_GENERATOR_1").getRequirements().add(new CustomRequirement( + "Buy a Flower Minion 1 from Dark Auction")); + manager.getMinionById("SNOW_GENERATOR_1").getRequirements().add(new CustomRequirement( + "Get a Snow Minion 1 from opening gifts")); + + } + + private void loadNpcData() { + TreeMap<String, JsonObject> itemInformation = NotEnoughUpdates.INSTANCE.manager.getItemInformation(); + for (Map.Entry<String, JsonObject> entry : itemInformation.entrySet()) { + String internalName = entry.getKey(); + if (!internalName.endsWith("_NPC")) continue; + JsonObject jsonObject = entry.getValue(); + if (!jsonObject.has("recipes")) continue; + + if (!jsonObject.has("displayname")) continue; + String npcName = jsonObject.get("displayname").getAsString(); + npcName = StringUtils.cleanColour(npcName); + if (npcName.contains(" (")) { + npcName = npcName.split(" \\(")[0]; + } + + for (JsonElement element : jsonObject.get("recipes").getAsJsonArray()) { + JsonObject object = element.getAsJsonObject(); + if (!object.has("type")) continue; + if (!object.get("type").getAsString().equals("npc_shop")) continue; + if (!object.has("result")) continue; + + String result = object.get("result").getAsString(); + if (!result.contains("_GENERATOR_")) continue; + Minion minion = manager.getMinionById(result); + if (!object.has("cost")) continue; + + RecipeBuilder builder = new RecipeBuilder(manager); + + for (JsonElement costEntry : object.get("cost").getAsJsonArray()) { + String price = costEntry.getAsString(); + builder.addLine(minion, price); + } + + ArrayListMultimap<String, Integer> map = builder.getItems(); + int coins = 0; + if (map.containsKey("SKYBLOCK_COIN")) { + coins = map.get("SKYBLOCK_COIN").get(0); + map.removeAll("SKYBLOCK_COIN"); + } + + minion.setMinionSource(new NpcSource(npcName, coins, builder.getItems())); + minion.setParent(builder.getParent()); + } + } + } + + private void createMinions() { + for (Map.Entry<String, JsonElement> entry : Constants.MISC.get("minions").getAsJsonObject().entrySet()) { + String internalName = entry.getKey(); + int maxTier = entry.getValue().getAsInt(); + for (int i = 0; i < maxTier; i++) { + int tier = i + 1; + manager.createMinion(internalName + "_" + tier, tier); + } + } + } + + private void testForMissingData() { + for (Minion minion : manager.getAllMinions().values()) { + if (minion.getMinionSource() == null) { + errorWhileLoading = true; + if (NotEnoughUpdates.INSTANCE.config.hidden.dev) { + Utils.addChatMessage("§c[NEU] The Minion '" + minion.getInternalName() + " has no source!"); + } + } + if (minion.getDisplayName() == null) { + errorWhileLoading = true; + if (NotEnoughUpdates.INSTANCE.config.hidden.dev) { + Utils.addChatMessage("§c[NEU] The Minion '" + minion.getInternalName() + " has no display name!"); + } + } + if (manager.getRequirementsManager().getRequirements(minion).isEmpty()) { + errorWhileLoading = true; + if (NotEnoughUpdates.INSTANCE.config.hidden.dev) { + Utils.addChatMessage("§c[NEU] The Minion '" + minion.getInternalName() + " has no requirements!"); + } + } + if (minion.getTier() > 1 && minion.getParent() == null) { + errorWhileLoading = true; + if (NotEnoughUpdates.INSTANCE.config.hidden.dev) { + Utils.addChatMessage("§c[NEU] The Minion '" + minion.getInternalName() + " has parent!"); + } + } + } + } + + //TODO move into utils class or somewhere + public String getDisplayName(String internalName) { + if (displayNameCache.containsKey(internalName)) { + return displayNameCache.get(internalName); + } + + String displayName = null; + TreeMap<String, JsonObject> itemInformation = NotEnoughUpdates.INSTANCE.manager.getItemInformation(); + if (itemInformation.containsKey(internalName)) { + JsonObject jsonObject = itemInformation.get(internalName); + if (jsonObject.has("displayname")) { + displayName = jsonObject.get("displayname").getAsString(); + } + } + + if (displayName == null) { + displayName = internalName; + Utils.showOutdatedRepoNotification(); + if (NotEnoughUpdates.INSTANCE.config.hidden.dev) { + Utils.addChatMessage("§c[NEU] Found no display name in repo for '" + internalName + "'!"); + } + } + + displayNameCache.put(internalName, displayName); + return displayName; + } + + public void setDirty() { + dirty = true; + displayNameCache.clear(); + repoReadyToUse = false; + } + + public boolean isRepoReadyToUse() { + return repoReadyToUse; + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/repo/MinionHelperRepoMinionLoader.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/repo/MinionHelperRepoMinionLoader.java new file mode 100644 index 00000000..6abc5c56 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/repo/MinionHelperRepoMinionLoader.java @@ -0,0 +1,132 @@ +/* + * 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.miscgui.minionhelper.loaders.repo; + +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.miscgui.minionhelper.Minion; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.MinionHelperManager; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.requirements.CollectionRequirement; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.requirements.ReputationRequirement; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.requirements.SlayerRequirement; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.sources.CraftingSource; +import io.github.moulberry.notenoughupdates.util.Utils; + +import java.util.Map; +import java.util.TreeMap; +import java.util.regex.Pattern; + +public class MinionHelperRepoMinionLoader { + + private final MinionHelperRepoLoader repoLoader; + private final MinionHelperManager manager; + + public MinionHelperRepoMinionLoader(MinionHelperRepoLoader repoLoader, MinionHelperManager manager) { + this.repoLoader = repoLoader; + this.manager = manager; + } + + void loadMinionData() { + TreeMap<String, JsonObject> itemInformation = NotEnoughUpdates.INSTANCE.manager.getItemInformation(); + + for (Map.Entry<String, Minion> entry : manager.getAllMinions().entrySet()) { + String internalName = entry.getKey(); + if (!itemInformation.containsKey(internalName)) continue; + Minion minion = entry.getValue(); + + JsonObject jsonObject = itemInformation.get(internalName); + if (jsonObject.has("displayname")) { + String displayName = jsonObject.get("displayname").getAsString(); + displayName = StringUtils.cleanColour(displayName); + displayName = StringUtils.removeLastWord(displayName, " "); + minion.setDisplayName(displayName); + } + + if (jsonObject.has("recipe")) { + loadRecipes(minion, jsonObject); + } + + loadRequirements(minion, jsonObject); + } + } + + private void loadRequirements(Minion minion, JsonObject jsonObject) { + for (Map.Entry<String, JsonElement> entry : jsonObject.entrySet()) { + String name = entry.getKey(); + if (name.endsWith("_req") || name.equals("crafttext")) { + String value = entry.getValue().getAsString(); + + try { + switch (name) { + case "reputation_req": { + String[] split = value.split(":"); + String reputationType = split[0]; + int reputation = Integer.parseInt(split[1]); + minion.getRequirements().add(new ReputationRequirement(reputationType, reputation)); + break; + } + case "crafttext": { + if (minion.getTier() != 1) break; + if (value.isEmpty()) break; + + String rawCollection = value.split(Pattern.quote(": "))[1]; + String cleanCollection = StringUtils.removeLastWord(rawCollection, " "); + String rawTier = rawCollection.substring(cleanCollection.length() + 1); + int tier = Utils.parseRomanNumeral(rawTier); + minion.getRequirements().add(new CollectionRequirement(cleanCollection, tier)); + break; + } + case "slayer_req": { + String[] split = value.split("_"); + String slayerType = split[0].toLowerCase(); + int tier = Integer.parseInt(split[1]); + minion.getRequirements().add(new SlayerRequirement(slayerType, tier)); + break; + } + } + } catch (ArrayIndexOutOfBoundsException | NumberFormatException e) { + repoLoader.errorWhileLoading = true; + if (NotEnoughUpdates.INSTANCE.config.hidden.dev) { + Utils.addChatMessage( + "§c[NEU] Error in MinionHelperRepoLoader while loading repo entry " + minion.getDisplayName() + " " + + minion.getTier() + ": " + + e.getClass().getSimpleName() + ": " + e.getMessage()); + } + e.printStackTrace(); + } + } + } + } + + private void loadRecipes(Minion minion, JsonObject jsonObject) { + JsonObject recipes = jsonObject.get("recipe").getAsJsonObject(); + RecipeBuilder builder = new RecipeBuilder(manager); + for (Map.Entry<String, JsonElement> entry : recipes.entrySet()) { + String rawString = entry.getValue().getAsString(); + + builder.addLine(minion, rawString); + } + + minion.setMinionSource(new CraftingSource(builder.getItems())); + minion.setParent(builder.getParent()); + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/repo/RecipeBuilder.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/repo/RecipeBuilder.java new file mode 100644 index 00000000..e7738954 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/repo/RecipeBuilder.java @@ -0,0 +1,75 @@ +/* + * 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.miscgui.minionhelper.loaders.repo; + +import com.google.common.collect.ArrayListMultimap; +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.core.util.StringUtils; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.Minion; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.MinionHelperManager; +import io.github.moulberry.notenoughupdates.util.Utils; + +public class RecipeBuilder { + private final MinionHelperManager manager; + private Minion parent = null; + private final ArrayListMultimap<String, Integer> items = ArrayListMultimap.create(); + + public RecipeBuilder(MinionHelperManager manager) { + this.manager = manager; + } + + public Minion getParent() { + return parent; + } + + public ArrayListMultimap<String, Integer> getItems() { + return items; + } + + public void addLine(Minion minion, String rawString) { + String[] split = rawString.split(":"); + String itemName = split[0]; + + boolean isParent = false; + if (itemName.contains("_GENERATOR_")) { + String minionInternalName = minion.getInternalName(); + boolean same = StringUtils.removeLastWord(itemName, "_").equals(StringUtils.removeLastWord( + minionInternalName, + "_" + )); + if (same) { + Minion recipeMinion = manager.getMinionById(itemName); + if (recipeMinion.getTier() == minion.getTier() - 1) { + parent = recipeMinion; + if (parent == null) { + if (NotEnoughUpdates.INSTANCE.config.hidden.dev) { + Utils.addChatMessage("Parent is null for minion " + minionInternalName); + } + } + isParent = true; + } + } + } + if (!isParent) { + int amount = Integer.parseInt(split[1]); + items.put(itemName, amount); + } + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/render/MinionHelperOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/render/MinionHelperOverlay.java new file mode 100644 index 00000000..12a8c24d --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/render/MinionHelperOverlay.java @@ -0,0 +1,358 @@ +/* + * 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.miscgui.minionhelper.render; + +import com.google.common.collect.Lists; +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.core.util.PageArrowsUtils; +import io.github.moulberry.notenoughupdates.core.util.StringUtils; +import io.github.moulberry.notenoughupdates.miscgui.TrophyRewardOverlay; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.Minion; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.MinionHelperManager; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.render.renderables.OverviewLine; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.render.renderables.OverviewText; +import io.github.moulberry.notenoughupdates.mixins.AccessorGuiContainer; +import io.github.moulberry.notenoughupdates.util.NotificationHandler; +import io.github.moulberry.notenoughupdates.util.Utils; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.gui.Gui; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.gui.ScaledResolution; +import net.minecraft.client.gui.inventory.GuiChest; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.client.event.GuiOpenEvent; +import net.minecraftforge.client.event.GuiScreenEvent; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import org.lwjgl.input.Mouse; +import org.lwjgl.opengl.GL11; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +public class MinionHelperOverlay { + + private final ResourceLocation minionOverlayImage = new ResourceLocation("notenoughupdates:minion_overlay.png"); + + private final MinionHelperManager manager; + private final MinionHelperOverlayHover hover; + private int[] topLeft = new int[]{237, 110}; + + private LinkedHashMap<String, OverviewLine> cacheRenderMap = null; + private int cacheTotalPages = -1; + + private boolean showOnlyAvailable = true; + + private int maxPerPage = 8; + private int currentPage = 0; + + public MinionHelperOverlay(MinionHelperManager manager) { + this.manager = manager; + hover = new MinionHelperOverlayHover(this, manager); + } + + @SubscribeEvent + public void onGuiOpen(GuiOpenEvent event) { + resetCache(); + } + + public void resetCache() { + cacheRenderMap = null; + cacheTotalPages = -1; + } + + @SubscribeEvent + public void onDrawBackground(GuiScreenEvent.BackgroundDrawnEvent event) { + if (!manager.inCraftedMinionsInventory()) return; + if (!NotEnoughUpdates.INSTANCE.config.minionHelper.gui) return; + if (!manager.isReadyToUse()) { + LinkedHashMap<String, OverviewLine> map = new LinkedHashMap<>(); + map.put("§cLoading...", new OverviewText(Collections.emptyList(), () -> {})); + render(event, map); + return; + } + + if (manager.getApi().isNotifyNoCollectionApi()) { + NotificationHandler.displayNotification(Lists.newArrayList( + "", + "§cCollection API is disabled!", + "§cMinion Helper will not filter minions that", + "§cdo not meet the collection requirements!" + ), false, true); + //TODO add tutorial how to enable collection api + manager.getApi().setNotifyNoCollectionApi(false); + } + + LinkedHashMap<String, OverviewLine> renderMap = getRenderMap(); + + hover.renderHover(renderMap); + render(event, renderMap); + + renderArrows(event); + } + + private void renderArrows(GuiScreenEvent.BackgroundDrawnEvent event) { + GuiScreen gui = event.gui; + if (gui instanceof AccessorGuiContainer) { + AccessorGuiContainer container = (AccessorGuiContainer) gui; + int guiLeft = container.getGuiLeft(); + int guiTop = container.getGuiTop(); + int totalPages = getTotalPages(); + PageArrowsUtils.onDraw(guiLeft, guiTop, topLeft, currentPage, totalPages); + } + } + + @SubscribeEvent + public void onMouseClick(GuiScreenEvent.MouseInputEvent.Pre event) { + if (!manager.inCraftedMinionsInventory()) return; + if (!NotEnoughUpdates.INSTANCE.config.minionHelper.gui) return; + if (!manager.isReadyToUse()) return; + if (!Mouse.getEventButtonState()) return; + + OverviewLine overviewLine = getObjectOverMouse(getRenderMap()); + if (overviewLine != null) { + overviewLine.onClick(); + event.setCanceled(true); + } + + int totalPages = getTotalPages(); + if (event.gui instanceof AccessorGuiContainer) { + int guiLeft = ((AccessorGuiContainer) event.gui).getGuiLeft(); + int guiTop = ((AccessorGuiContainer) event.gui).getGuiTop(); + if (PageArrowsUtils.onPageSwitch(guiLeft, guiTop, topLeft, currentPage, totalPages, pageChange -> { + currentPage = pageChange; + resetCache(); + })) { + event.setCanceled(true); + } + } + } + + private Map<Minion, Long> getMissing() { + Map<Minion, Long> prices = new HashMap<>(); + for (Minion minion : manager.getAllMinions().values()) { + + if (!minion.doesMeetRequirements() && showOnlyAvailable) continue; + if (!minion.isCrafted()) { + long price = manager.getPriceCalculation().calculateUpgradeCosts(minion, true); + prices.put(minion, price); + } + } + return prices; + } + + private void render(GuiScreenEvent.BackgroundDrawnEvent event, Map<String, OverviewLine> renderMap) { + Minecraft minecraft = Minecraft.getMinecraft(); + if (!(Minecraft.getMinecraft().currentScreen instanceof GuiChest)) return; + Gui gui = event.gui; + int xSize = ((AccessorGuiContainer) gui).getXSize(); + int guiLeft = ((AccessorGuiContainer) gui).getGuiLeft(); + int guiTop = ((AccessorGuiContainer) gui).getGuiTop(); + minecraft.getTextureManager().bindTexture(minionOverlayImage); + GL11.glColor4f(1, 1, 1, 1); + GlStateManager.disableLighting(); + Utils.drawTexturedRect(guiLeft + xSize + 4, guiTop, 168, 128, 0, 1f, 0, 1f, GL11.GL_NEAREST); + + int a = guiLeft + xSize + 4; + FontRenderer fontRendererObj = minecraft.fontRendererObj; + + int i = 0; + int y = 0; + for (Map.Entry<String, OverviewLine> entry : renderMap.entrySet()) { + String line = entry.getKey(); + OverviewLine overviewLine = entry.getValue(); + String prefix = ""; + if (overviewLine instanceof Minion) { + Minion minion = (Minion) overviewLine; + if (minion == hover.getLastHovered()) { + prefix = "§e"; + } + } + fontRendererObj.drawString(prefix + line, a + 6, guiTop + 6 + y, -1, false); + i++; + if (i == 2) { + y += 15; + } else { + y += 10; + } + } + } + + private LinkedHashMap<String, OverviewLine> getRenderMap() { + if (cacheRenderMap != null) return cacheRenderMap; + + Map<Minion, Long> prices = getMissing(); + LinkedHashMap<String, OverviewLine> renderMap = new LinkedHashMap<>(); + + addTitle(prices, renderMap); + addNeedToNextSlot(prices, renderMap); + + if (!prices.isEmpty()) { + addMinions(prices, renderMap); + } + + cacheRenderMap = renderMap; + return renderMap; + } + + private void addNeedToNextSlot( + Map<Minion, Long> prices, + LinkedHashMap<String, OverviewLine> renderMap + ) { + int neededForNextSlot = manager.getNeedForNextSlot(); + String color = showOnlyAvailable ? "§e" : "§c"; + if (neededForNextSlot == -1) { + renderMap.put(color + "Next slot in: ?", new OverviewText(Collections.emptyList(), () -> {})); + return; + } + + long priceNeeded = 0; + int index = 0; + for (Long price : TrophyRewardOverlay.sortByValue(prices).values()) { + priceNeeded += price; + index++; + if (index == neededForNextSlot) break; + } + String format = manager.getPriceCalculation().formatCoins(priceNeeded); + String text = color + "Next slot in: §b" + neededForNextSlot + " §8- " + format; + renderMap.put(text, new OverviewText(Collections.emptyList(), () -> {})); + } + + private void addTitle(Map<Minion, Long> prices, LinkedHashMap<String, OverviewLine> renderMap) { + String name; + String hoverText; + if (prices.isEmpty()) { + name = (showOnlyAvailable ? "No minion obtainable!" : "§aAll minions collected!"); + hoverText = "No minions to craft available!"; + } else { + name = (showOnlyAvailable ? "Obtainable" : "All") + ": " + prices.size(); + if (showOnlyAvailable) { + hoverText = "There are " + prices.size() + " more minions in total!"; + } else { + hoverText = "You can craft " + prices.size() + " more minions!"; + } + } + String toggleText = "§eClick to " + (showOnlyAvailable ? "show" : "hide") + " minion upgrades without requirements"; + renderMap.put("§e" + name, new OverviewText(Arrays.asList(hoverText, "", toggleText), this::toggleShowAvailable)); + } + + private void addMinions(Map<Minion, Long> prices, LinkedHashMap<String, OverviewLine> renderMap) { + int skipPreviousPages = currentPage * maxPerPage; + int i = 0; + Map<Minion, Long> sort = TrophyRewardOverlay.sortByValue(prices); + for (Minion minion : sort.keySet()) { + if (i >= skipPreviousPages) { + String displayName = minion.getDisplayName(); + if (displayName == null) { + if (NotEnoughUpdates.INSTANCE.config.hidden.dev) { + Utils.addChatMessage("§cDisplayname is null for " + minion.getInternalName()); + } + continue; + } + + displayName = displayName.replace(" Minion", ""); + String format = manager.getPriceCalculation().calculateUpgradeCostsFormat(minion, true); + String requirementFormat = !minion.doesMeetRequirements() ? "§7§o" : ""; + renderMap.put( + requirementFormat + displayName + " " + minion.getTier() + " §r§8- " + format, + minion + ); + } + + i++; + if (i == ((currentPage + 1) * maxPerPage)) break; + } + } + + private int getTotalPages() { + if (cacheTotalPages != -1) return cacheTotalPages; + + Map<Minion, Long> prices = getMissing(); + int totalPages = (int) ((double) prices.size() / maxPerPage); + if (prices.size() % maxPerPage != 0) { + totalPages++; + } + + cacheTotalPages = totalPages; + return totalPages; + } + + private void toggleShowAvailable() { + showOnlyAvailable = !showOnlyAvailable; + currentPage = 0; + resetCache(); + } + + OverviewLine getObjectOverMouse(LinkedHashMap<String, OverviewLine> renderMap) { + GuiScreen gui = Minecraft.getMinecraft().currentScreen; + if (!(gui instanceof GuiChest)) return null; + + int xSize = ((AccessorGuiContainer) gui).getXSize(); + int guiLeft = ((AccessorGuiContainer) gui).getGuiLeft(); + int guiTop = ((AccessorGuiContainer) gui).getGuiTop(); + + int x = guiLeft + xSize + 9; + int y = guiTop + 5; + + final ScaledResolution scaledresolution = new ScaledResolution(Minecraft.getMinecraft()); + final int scaledWidth = scaledresolution.getScaledWidth(); + final int scaledHeight = scaledresolution.getScaledHeight(); + int mouseX = Mouse.getX() * scaledWidth / Minecraft.getMinecraft().displayWidth; + int mouseY = scaledHeight - Mouse.getY() * scaledHeight / Minecraft.getMinecraft().displayHeight - 1; + + int i = 0; + FontRenderer fontRenderer = Minecraft.getMinecraft().fontRendererObj; + for (Map.Entry<String, OverviewLine> entry : renderMap.entrySet()) { + String text = entry.getKey(); + int width = fontRenderer.getStringWidth(StringUtils.cleanColour(text)); + if (mouseX > x && mouseX < x + width && + mouseY > y && mouseY < y + 11) { + return entry.getValue(); + } + i++; + if (i == 2) { + y += 15; + } else { + y += 10; + } + } + + return null; + } + + public void onProfileSwitch() { + currentPage = 0; + showOnlyAvailable = true; + } + + public void setMaxPerPage(int maxPerPage) { + this.maxPerPage = maxPerPage; + } + + public void setTopLeft(int[] topLeft) { + this.topLeft = topLeft; + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/render/MinionHelperOverlayHover.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/render/MinionHelperOverlayHover.java new file mode 100644 index 00000000..a7628d31 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/render/MinionHelperOverlayHover.java @@ -0,0 +1,168 @@ +/* + * 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.miscgui.minionhelper.render; + +import com.google.common.collect.ArrayListMultimap; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.Minion; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.MinionHelperManager; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.render.renderables.OverviewLine; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.render.renderables.OverviewText; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.requirements.CollectionRequirement; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.requirements.MinionRequirement; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.sources.CraftingSource; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.sources.MinionSource; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.sources.NpcSource; +import io.github.moulberry.notenoughupdates.util.Utils; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.ScaledResolution; +import net.minecraft.client.gui.inventory.GuiChest; +import net.minecraft.client.renderer.GlStateManager; +import org.lwjgl.input.Mouse; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +public class MinionHelperOverlayHover { + + private final MinionHelperOverlay overlay; + private final MinionHelperManager manager; + private Minion lastHovered = null; + + public MinionHelperOverlayHover(MinionHelperOverlay overlay, MinionHelperManager manager) { + this.overlay = overlay; + this.manager = manager; + } + + void renderHover(LinkedHashMap<String, OverviewLine> renderMap) { + lastHovered = null; + + if (!(Minecraft.getMinecraft().currentScreen instanceof GuiChest)) return; + + final ScaledResolution scaledresolution = new ScaledResolution(Minecraft.getMinecraft()); + final int scaledWidth = scaledresolution.getScaledWidth(); + final int scaledHeight = scaledresolution.getScaledHeight(); + int mouseX = Mouse.getX() * scaledWidth / Minecraft.getMinecraft().displayWidth; + int mouseY = scaledHeight - Mouse.getY() * scaledHeight / Minecraft.getMinecraft().displayHeight - 1; + + OverviewLine mouseObject = overlay.getObjectOverMouse(renderMap); + if (mouseObject != null) { + GlStateManager.pushMatrix(); + GlStateManager.scale(2f / scaledresolution.getScaleFactor(), 2f / scaledresolution.getScaleFactor(), 1); + Utils.drawHoveringText(getTooltip(mouseObject), + mouseX * scaledresolution.getScaleFactor() / 2, + mouseY * scaledresolution.getScaleFactor() / 2, + scaledWidth * scaledresolution.getScaleFactor() / 2, + scaledHeight * scaledresolution.getScaleFactor() / 2, -1, Minecraft.getMinecraft().fontRendererObj + ); + GlStateManager.popMatrix(); + } + } + + private List<String> getTooltip(OverviewLine overviewLine) { + List<String> lines = new ArrayList<>(); + + if (overviewLine instanceof OverviewText) { + OverviewText overviewText = (OverviewText) overviewLine; + lines.addAll(overviewText.getLines()); + } else if (overviewLine instanceof Minion) { + + Minion minion = (Minion) overviewLine; + MinionSource minionSource = minion.getMinionSource(); + lastHovered = minion; + String displayName = minion.getDisplayName(); + lines.add("§9" + displayName + " " + minion.getTier()); + List<MinionRequirement> requirements = manager.getRequirementsManager().getRequirements(minion); + if (!requirements.isEmpty()) { + for (MinionRequirement requirement : requirements) { + //TODO maybe change the §7 color + String color = manager.getRequirementsManager().meetRequirement(minion, requirement) ? "§a" : "§7"; + if (requirement instanceof CollectionRequirement && manager.getApi().isCollectionApiDisabled()) { + color = "§cAPI DISABLED! §7"; + } + lines.add(" §8- " + color + requirement.printDescription()); + } + } else { + lines.add("§cNo requirements loaded!"); + } + + if (minionSource instanceof CraftingSource) { + CraftingSource craftingSource = (CraftingSource) minionSource; + lines.add(""); + String format = manager.getPriceCalculation().calculateUpgradeCostsFormat(minion, true); + if (minion.getTier() == 1) { + lines.add("§7Full crafting costs: " + format); + } else { + lines.add("§7Upgrade costs: " + format); + } + formatItems(lines, grabAllItems(craftingSource.getItems())); + + } else if (minionSource instanceof NpcSource) { + NpcSource npcSource = (NpcSource) minionSource; + String npcName = npcSource.getNpcName(); + lines.add(""); + lines.add("§7Buy from: §9" + npcName + " (NPC)"); + lines.add(""); + lines.add("§7Buy costs: " + manager.getPriceCalculation().calculateUpgradeCostsFormat(minion, true)); + int coins = npcSource.getCoins(); + if (coins != 0) { + lines.add(" §8- " + manager.getPriceCalculation().formatCoins(coins)); + } + formatItems(lines, grabAllItems(npcSource.getItems())); + } + + lines.add(""); + lines.add("§eClick to view recipe"); + } + return lines; + } + + private void formatItems(List<String> lines, Map<String, Integer> allItems) { + for (Map.Entry<String, Integer> entry : allItems.entrySet()) { + String internalName = entry.getKey(); + if (internalName.equals("SKYBLOCK_PELT")) continue; + + String name = manager.getRepo().getDisplayName(internalName); + + int amount = entry.getValue(); + String amountText = amount != 1 ? amount + "§7x " : ""; + String price = manager.getPriceCalculation().formatCoins( + manager.getPriceCalculation().getPrice(internalName) * amount); + lines.add(" §8- §a" + amountText + "§f" + name + " " + price); + } + } + + private Map<String, Integer> grabAllItems(ArrayListMultimap<String, Integer> multimap) { + Map<String, Integer> allItems = new HashMap<>(); + for (Map.Entry<String, Integer> entry : multimap.entries()) { + String name = entry.getKey(); + int amount = entry.getValue(); + amount = allItems.getOrDefault(name, 0) + amount; + allItems.put(name, amount); + } + return allItems; + } + + public Minion getLastHovered() { + return lastHovered; + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/render/MinionHelperTooltips.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/render/MinionHelperTooltips.java new file mode 100644 index 00000000..945594a0 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/render/MinionHelperTooltips.java @@ -0,0 +1,91 @@ +/* + * 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.miscgui.minionhelper.render; + +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.core.util.StringUtils; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.Minion; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.MinionHelperManager; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.sources.MinionSource; +import io.github.moulberry.notenoughupdates.util.ItemUtils; +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.List; + +public class MinionHelperTooltips { + private final MinionHelperManager manager; + private boolean pressedShiftLast = false; + private boolean showFullCost = false; + + public MinionHelperTooltips(MinionHelperManager manager) { + this.manager = manager; + } + + @SubscribeEvent(priority = EventPriority.LOW) + public void onItemTooltip(ItemTooltipEvent event) { + if (!manager.inCraftedMinionsInventory()) return; + if (!NotEnoughUpdates.INSTANCE.config.minionHelper.tooltip) return; + if (!manager.isReadyToUse()) return; + + boolean shift = Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown(Keyboard.KEY_RSHIFT); + if (!pressedShiftLast && shift) { + showFullCost = !showFullCost; + } + pressedShiftLast = shift; + + ItemStack itemStack = event.itemStack; + if (itemStack == null) return; + String displayName = itemStack.getDisplayName(); + if (!displayName.endsWith(" Minion")) return; + displayName = StringUtils.cleanColour(displayName); + + List<String> lore = ItemUtils.getLore(itemStack); + if (lore.get(0).equals("§7You haven't crafted this minion.")) return; + + int index = 0; + for (String line : lore) { + index++; + if (!line.contains("Tier")) continue; + + Minion minion = manager.getMinionByName(displayName, index); + if (minion == null) { + System.err.println("minion is null for displayName '" + displayName + "' and tier " + index); + continue; + } + MinionSource minionSource = minion.getMinionSource(); + if (minionSource == null) { + System.err.println("minionSource is null for " + minion.getInternalName()); + continue; + } + String format = manager.getPriceCalculation().calculateUpgradeCostsFormat(minion, !showFullCost); + event.toolTip.set(index, line + " §8- " + format); + } + + if (showFullCost) { + event.toolTip.add("§8[Press SHIFT to show upgrade costs]"); + } else { + event.toolTip.add("§8[Press SHIFT to show full costs]"); + } + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/render/renderables/OverviewLine.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/render/renderables/OverviewLine.java new file mode 100644 index 00000000..85d682b3 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/render/renderables/OverviewLine.java @@ -0,0 +1,25 @@ +/* + * 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.miscgui.minionhelper.render.renderables; + +public abstract class OverviewLine { + + public abstract void onClick(); +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/render/renderables/OverviewText.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/render/renderables/OverviewText.java new file mode 100644 index 00000000..499ca758 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/render/renderables/OverviewText.java @@ -0,0 +1,42 @@ +/* + * 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.miscgui.minionhelper.render.renderables; + +import java.util.List; + +public class OverviewText extends OverviewLine { + + private final Runnable clickRunnable; + private final List<String> lines; + + public OverviewText(List<String> line, Runnable clickRunnable) { + this.lines = line; + this.clickRunnable = clickRunnable; + } + + public List<String> getLines() { + return lines; + } + + @Override + public void onClick() { + clickRunnable.run(); + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/requirements/CollectionRequirement.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/requirements/CollectionRequirement.java new file mode 100644 index 00000000..603834f8 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/requirements/CollectionRequirement.java @@ -0,0 +1,44 @@ +/* + * 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.miscgui.minionhelper.requirements; + +public class CollectionRequirement extends MinionRequirement { + + private final String collection; + private final int level; + + public CollectionRequirement(String collection, int level) { + this.collection = collection; + this.level = level; + } + + public int getLevel() { + return level; + } + + public String getCollection() { + return collection; + } + + @Override + public String printDescription() { + return "Collection: " + collection + " level " + level; + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/requirements/CustomRequirement.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/requirements/CustomRequirement.java new file mode 100644 index 00000000..2755e4ad --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/requirements/CustomRequirement.java @@ -0,0 +1,33 @@ +/* + * 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.miscgui.minionhelper.requirements; + +public class CustomRequirement extends MinionRequirement { + + private final String text; + + public CustomRequirement(String text) { + this.text = text; + } + @Override + public String printDescription() { + return text; + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/requirements/MinionRequirement.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/requirements/MinionRequirement.java new file mode 100644 index 00000000..763428df --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/requirements/MinionRequirement.java @@ -0,0 +1,24 @@ +/* + * 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.miscgui.minionhelper.requirements; + +public abstract class MinionRequirement { + public abstract String printDescription(); +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/requirements/ReputationRequirement.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/requirements/ReputationRequirement.java new file mode 100644 index 00000000..525af1df --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/requirements/ReputationRequirement.java @@ -0,0 +1,51 @@ +/* + * 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.miscgui.minionhelper.requirements; + +import io.github.moulberry.notenoughupdates.core.util.StringUtils; +import io.github.moulberry.notenoughupdates.util.Utils; + +public class ReputationRequirement extends MinionRequirement { + + private final String reputationType; + private final int reputation; + private final String description; + + public ReputationRequirement(String reputationType, int reputation) { + this.reputationType = reputationType; + this.reputation = reputation; + + String reputationName = StringUtils.firstUpperLetter(reputationType.toLowerCase()); + description = "Reputation: " + Utils.formatNumberWithDots(reputation) + " " + reputationName + " Reputation"; + } + + public int getReputation() { + return reputation; + } + + public String getReputationType() { + return reputationType; + } + + @Override + public String printDescription() { + return description; + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/requirements/SlayerRequirement.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/requirements/SlayerRequirement.java new file mode 100644 index 00000000..d20555b8 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/requirements/SlayerRequirement.java @@ -0,0 +1,46 @@ +/* + * 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.miscgui.minionhelper.requirements; + +import io.github.moulberry.notenoughupdates.core.util.StringUtils; + +public class SlayerRequirement extends MinionRequirement { + + private final String slayer; + private final int level; + + public SlayerRequirement(String slayer, int level) { + this.slayer = slayer; + this.level = level; + } + + public int getLevel() { + return level; + } + + public String getSlayer() { + return slayer; + } + + @Override + public String printDescription() { + return "Slayer: " + StringUtils.firstUpperLetter(slayer) + " level " + level; + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/sources/CraftingSource.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/sources/CraftingSource.java new file mode 100644 index 00000000..08f27b35 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/sources/CraftingSource.java @@ -0,0 +1,36 @@ +/* + * 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.miscgui.minionhelper.sources; + +import com.google.common.collect.ArrayListMultimap; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.Minion; + +public class CraftingSource extends MinionSource { + //name -> amount + private final ArrayListMultimap<String, Integer> items; + + public CraftingSource(ArrayListMultimap<String, Integer> items) { + this.items = items; + } + + public ArrayListMultimap<String, Integer> getItems() { + return items; + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/sources/CustomSource.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/sources/CustomSource.java new file mode 100644 index 00000000..cf260a88 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/sources/CustomSource.java @@ -0,0 +1,33 @@ +/* + * 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.miscgui.minionhelper.sources; + +public class CustomSource extends MinionSource { + + private final String sourceName; + + public CustomSource(String sourceName) { + this.sourceName = sourceName; + } + + public String getSourceName() { + return sourceName; + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/sources/MinionSource.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/sources/MinionSource.java new file mode 100644 index 00000000..f54f0845 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/sources/MinionSource.java @@ -0,0 +1,23 @@ +/* + * 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.miscgui.minionhelper.sources; + +public abstract class MinionSource { +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/sources/NpcSource.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/sources/NpcSource.java new file mode 100644 index 00000000..a11e8a38 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/sources/NpcSource.java @@ -0,0 +1,48 @@ +/* + * 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.miscgui.minionhelper.sources; + +import com.google.common.collect.ArrayListMultimap; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.Minion; + +public class NpcSource extends MinionSource { + private final String npcName; + // name -> amount + private final ArrayListMultimap<String, Integer> items; + private final int coins; + + public NpcSource(String npcName, int coins, ArrayListMultimap<String, Integer> items) { + this.npcName = npcName; + this.coins = coins; + this.items = items; + } + + public String getNpcName() { + return npcName; + } + + public ArrayListMultimap<String, Integer> getItems() { + return items; + } + + public int getCoins() { + return coins; + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/util/MinionHelperPriceCalculation.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/util/MinionHelperPriceCalculation.java new file mode 100644 index 00000000..3ffe4846 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/util/MinionHelperPriceCalculation.java @@ -0,0 +1,189 @@ +/* + * 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.miscgui.minionhelper.util; + +import com.google.common.collect.ArrayListMultimap; +import com.google.gson.JsonObject; +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.Minion; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.MinionHelperManager; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.sources.CraftingSource; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.sources.CustomSource; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.sources.MinionSource; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.sources.NpcSource; +import io.github.moulberry.notenoughupdates.util.Utils; +import net.minecraftforge.client.event.GuiOpenEvent; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; + +import java.util.HashMap; +import java.util.Map; + +public class MinionHelperPriceCalculation { + + private final MinionHelperManager manager; + private final Map<String, String> upgradeCostFormatCache = new HashMap<>(); + private final Map<String, String> fullCostFormatCache = new HashMap<>(); + //TODO maybe change logic with 0 coins later or stuff +// private final List<String> cheapItems = Arrays.asList( +// "WOOD_SWORD", +// "WOOD_HOE", +// "WOOD_AXE", +// "WOOD_PICKAXE", +// "WOOD_SPADE", +// "FISHING_ROD", +// "SKYBLOCK_PELT" +// ); + + public MinionHelperPriceCalculation(MinionHelperManager manager) { + this.manager = manager; + } + + @SubscribeEvent + public void onGuiOpen(GuiOpenEvent event) { + upgradeCostFormatCache.clear(); + fullCostFormatCache.clear(); + } + + public String calculateUpgradeCostsFormat(Minion minion, boolean upgradeOnly) { + MinionSource source = minion.getMinionSource(); + + if (source == null) return "§c?"; + String internalName = minion.getInternalName(); + if (upgradeOnly) { + if (upgradeCostFormatCache.containsKey(internalName)) { + return upgradeCostFormatCache.get(internalName); + } + } else { + if (fullCostFormatCache.containsKey(internalName)) { + return fullCostFormatCache.get(internalName); + } + } + + if (upgradeOnly) { + if (minion.getCustomSource() != null) { + return "§f" + (minion.getCustomSource()).getSourceName(); + } + } + + long costs = calculateUpgradeCosts(minion, upgradeOnly); + String result = formatCoins(costs, !upgradeOnly ? "§o" : ""); + + if (source instanceof NpcSource) { + ArrayListMultimap<String, Integer> items = ((NpcSource) source).getItems(); + if (items.containsKey("SKYBLOCK_PELT")) { + int amount = items.get("SKYBLOCK_PELT").get(0); + result += " §7+ §5" + amount + " Pelts"; + } + } + + if (upgradeOnly) { + upgradeCostFormatCache.put(internalName, result); + } else { + fullCostFormatCache.put(internalName, result); + } + + return result; + } + + public long calculateUpgradeCosts(Minion minion, boolean upgradeOnly) { + MinionSource source = minion.getMinionSource(); + + if (upgradeOnly) { + if (minion.getCustomSource() != null) { + return 0; + } + } + + if (source instanceof CraftingSource) { + CraftingSource craftingSource = (CraftingSource) source; + return getCosts(minion, upgradeOnly, craftingSource.getItems()); + + } else if (source instanceof NpcSource) { + NpcSource npcSource = (NpcSource) source; + long upgradeCost = getCosts(minion, upgradeOnly, npcSource.getItems()); + long coins = npcSource.getCoins(); + upgradeCost += coins; + + return upgradeCost; + } + + return 0; + } + + private long getCosts(Minion minion, boolean upgradeOnly, ArrayListMultimap<String, Integer> items) { + long upgradeCost = 0; + for (Map.Entry<String, Integer> entry : items.entries()) { + String internalName = entry.getKey(); + if (internalName.equals("SKYBLOCK_PELT")) continue; + long price = getPrice(internalName); + int amount = entry.getValue(); + upgradeCost += price * amount; + } + if (!upgradeOnly) { + Minion parent = minion.getParent(); + if (parent != null) { + upgradeCost += calculateUpgradeCosts(parent, false); + } + } + return upgradeCost; + } + + public long getPrice(String internalName) { + //Is minion + if (internalName.contains("_GENERATOR_")) { + return calculateUpgradeCosts(manager.getMinionById(internalName), false); + } + + //Is bazaar item + JsonObject bazaarInfo = NotEnoughUpdates.INSTANCE.manager.auctionManager.getBazaarInfo(internalName); + if (bazaarInfo != null) { + if (!bazaarInfo.has("curr_sell")) { + System.err.println("curr_sell does not exist for '" + internalName + "'"); + return 0; + } + return (long) bazaarInfo.get("curr_sell").getAsDouble(); + } + + //Is cheap item +// if (cheapItems.contains(internalName)) return 0; + + //is ah bin + long avgBinPrice = (long) NotEnoughUpdates.INSTANCE.manager.auctionManager.getItemAvgBin(internalName); + if (avgBinPrice >= 1) return avgBinPrice; + + //is ah without bin + JsonObject auctionInfo = NotEnoughUpdates.INSTANCE.manager.auctionManager.getItemAuctionInfo(internalName); + if (auctionInfo == null) { + //only wood axe and similar useless items + return 0; + } + return (int) (auctionInfo.get("price").getAsFloat() / auctionInfo.get("count").getAsFloat()); + + } + + public String formatCoins(long coins) { + return formatCoins(coins, ""); + } + + public String formatCoins(long coins, String extraFormat) { + String format = Utils.shortNumberFormat(coins, 0); + return "§6" + extraFormat + format + " coins"; + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/util/MinionHelperRequirementsManager.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/util/MinionHelperRequirementsManager.java new file mode 100644 index 00000000..adc30a53 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/util/MinionHelperRequirementsManager.java @@ -0,0 +1,120 @@ +/* + * 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.miscgui.minionhelper.util; + +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.ApiData; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.Minion; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.MinionHelperManager; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.requirements.CollectionRequirement; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.requirements.CustomRequirement; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.requirements.MinionRequirement; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.requirements.ReputationRequirement; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.requirements.SlayerRequirement; +import io.github.moulberry.notenoughupdates.util.Utils; + +import java.util.Collections; +import java.util.List; +import java.util.Map; + +public class MinionHelperRequirementsManager { + + private final MinionHelperManager manager; + + public MinionHelperRequirementsManager(MinionHelperManager manager) { + this.manager = manager; + } + + public List<MinionRequirement> getRequirements(Minion minion) { + if (!minion.getRequirements().isEmpty()) { + return minion.getRequirements(); + } + + Minion parent = minion.getParent(); + if (parent != null) { + return getRequirements(parent); + } + + return Collections.emptyList(); + } + + public boolean meetAllRequirements(Minion minion) { + List<MinionRequirement> list = getRequirements(minion); + for (MinionRequirement requirement : list) { + if (!meetRequirement(minion, requirement)) { + return false; + } + } + + return true; + } + + public boolean meetRequirement(Minion minion, MinionRequirement requirement) { + ApiData apiData = manager.getApi().getApiData(); + if (apiData == null) return false; + + if (requirement instanceof CollectionRequirement) { + if (apiData.isCollectionApiDisabled()) return true; + + CollectionRequirement collectionRequirement = (CollectionRequirement) requirement; + String collection = collectionRequirement.getCollection(); + String internalName = manager.formatInternalName(collection); + + int need = collectionRequirement.getLevel(); + Map<String, Integer> highestCollectionTier = apiData.getHighestCollectionTier(); + if (highestCollectionTier.containsKey(internalName)) { + int has = highestCollectionTier.get(internalName); + + return has >= need; + } + + } else if (requirement instanceof SlayerRequirement) { + SlayerRequirement slayerRequirement = (SlayerRequirement) requirement; + String slayer = slayerRequirement.getSlayer(); + int need = slayerRequirement.getLevel(); + Map<String, Integer> slayerTiers = apiData.getSlayerTiers(); + if (slayerTiers.containsKey(slayer)) { + return slayerTiers.get(slayer) >= need; + } + + } else if (requirement instanceof ReputationRequirement) { + ReputationRequirement reputationRequirement = (ReputationRequirement) requirement; + int need = reputationRequirement.getReputation(); + String reputationType = reputationRequirement.getReputationType(); + if (reputationType.equals("BARBARIAN")) { + return apiData.getBarbariansReputation() >= need; + } else if (reputationType.equals("MAGE")) { + return apiData.getMagesReputation() >= need; + } else { + Utils.addChatMessage("§c[NEU] Minion Helper: Unknown reputation type: '" + reputationType + "'"); + return false; + } + } else if (requirement instanceof CustomRequirement) { + return minion.isCrafted(); + } + + return false; + } + + public void reloadRequirements() { + for (Minion minion : manager.getAllMinions().values()) { + minion.setMeetRequirements(meetAllRequirements(minion)); + } + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinEntityPlayerSP.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinEntityPlayerSP.java index 765ed372..581a2c17 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinEntityPlayerSP.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinEntityPlayerSP.java @@ -21,10 +21,10 @@ package io.github.moulberry.notenoughupdates.mixins; import io.github.moulberry.notenoughupdates.miscfeatures.SlotLocking; import io.github.moulberry.notenoughupdates.util.SBInfo; +import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.entity.item.EntityItem; -import net.minecraft.util.ChatComponentText; import net.minecraft.util.EnumChatFormatting; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -42,8 +42,7 @@ public class MixinEntityPlayerSP { int slot = Minecraft.getMinecraft().thePlayer.inventory.currentItem; if (SlotLocking.getInstance().isSlotIndexLocked(slot) || SlotLocking.getInstance().isSwapedSlotLocked()) { ci.cancel(); - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + - "NotEnoughUpdates has prevented you from dropping that locked item!")); + Utils.addChatMessage(EnumChatFormatting.RED + "NotEnoughUpdates has prevented you from dropping that locked item!"); } } } 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..bb2ae6ba 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java @@ -49,6 +49,7 @@ import io.github.moulberry.notenoughupdates.options.seperateSections.ItemOverlay import io.github.moulberry.notenoughupdates.options.seperateSections.Itemlist; import io.github.moulberry.notenoughupdates.options.seperateSections.LocationEdit; import io.github.moulberry.notenoughupdates.options.seperateSections.Mining; +import io.github.moulberry.notenoughupdates.options.seperateSections.MinionHelper; import io.github.moulberry.notenoughupdates.options.seperateSections.Misc; import io.github.moulberry.notenoughupdates.options.seperateSections.MiscOverlays; import io.github.moulberry.notenoughupdates.options.seperateSections.NeuAuctionHouse; @@ -392,6 +393,13 @@ public class NEUConfig extends Config { @Expose @Category( + name = "Minion Helper", + desc = "Minion Helper" + ) + public MinionHelper minionHelper = new MinionHelper(); + + @Expose + @Category( name = "Apis", desc = "Api Data" ) diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/MinionHelper.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/MinionHelper.java new file mode 100644 index 00000000..089b2ae7 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/MinionHelper.java @@ -0,0 +1,45 @@ +/* + * 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.ConfigEditorBoolean; +import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigOption; + +//TODO jani rename message format +public class MinionHelper { + @Expose + @ConfigOption( + name = "Enable gui", + desc = + "Shows a list in the crafted minions inventory of every available to craft or all missing minion, in multiple pages " + + "that you need to get the next minion slot, sorted by upgrade cost" + ) + + @ConfigEditorBoolean + public boolean gui = true; + @Expose + @ConfigOption( + name = "Enable tooltip", + desc = "Shows the price per minion at the crafted minions " + ) + @ConfigEditorBoolean + public boolean tooltip = true; +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewer.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewer.java index 1b5c8950..98bc1896 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewer.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewer.java @@ -158,10 +158,10 @@ public class ProfileViewer { put("SUGAR_CANE", Utils.createItemStack(Items.reeds, EnumChatFormatting.YELLOW + "Sugar Cane")); put("FEATHER", Utils.createItemStack(Items.feather, EnumChatFormatting.YELLOW + "Feather")); put("LEATHER", Utils.createItemStack(Items.leather, EnumChatFormatting.YELLOW + "Leather")); - put("PORK", Utils.createItemStack(Items.porkchop, EnumChatFormatting.YELLOW + "Porkchop")); - put("RAW_CHICKEN", Utils.createItemStack(Items.chicken, EnumChatFormatting.YELLOW + "Chicken")); + put("PORK", Utils.createItemStack(Items.porkchop, EnumChatFormatting.YELLOW + "Raw Porkchop")); + put("RAW_CHICKEN", Utils.createItemStack(Items.chicken, EnumChatFormatting.YELLOW + "Raw Chicken")); put("MUTTON", Utils.createItemStack(Items.mutton, EnumChatFormatting.YELLOW + "Mutton")); - put("RABBIT", Utils.createItemStack(Items.rabbit, EnumChatFormatting.YELLOW + "Rabbit")); + put("RABBIT", Utils.createItemStack(Items.rabbit, EnumChatFormatting.YELLOW + "Raw Rabbit")); put("NETHER_STALK", Utils.createItemStack(Items.nether_wart, EnumChatFormatting.YELLOW + "Nether Wart")); /* MINING COLLECTIONS */ @@ -181,7 +181,7 @@ public class ProfileViewer { "OBSIDIAN", Utils.createItemStack(Item.getItemFromBlock(Blocks.obsidian), EnumChatFormatting.GRAY + "Obsidian") ); - put("GLOWSTONE_DUST", Utils.createItemStack(Items.glowstone_dust, EnumChatFormatting.GRAY + "Glowstone")); + put("GLOWSTONE_DUST", Utils.createItemStack(Items.glowstone_dust, EnumChatFormatting.GRAY + "Glowstone Dust")); put("GRAVEL", Utils.createItemStack(Item.getItemFromBlock(Blocks.gravel), EnumChatFormatting.GRAY + "Gravel")); put("ICE", Utils.createItemStack(Item.getItemFromBlock(Blocks.ice), EnumChatFormatting.GRAY + "Ice")); put( @@ -225,27 +225,27 @@ public class ProfileViewer { )); /* FORAGING COLLECTIONS */ - put("LOG", Utils.createItemStack(Item.getItemFromBlock(Blocks.log), EnumChatFormatting.DARK_GREEN + "Oak")); + put("LOG", Utils.createItemStack(Item.getItemFromBlock(Blocks.log), EnumChatFormatting.DARK_GREEN + "Oak Wood")); put( "LOG:1", - Utils.createItemStack(Item.getItemFromBlock(Blocks.log), EnumChatFormatting.DARK_GREEN + "Spruce", 1) + Utils.createItemStack(Item.getItemFromBlock(Blocks.log), EnumChatFormatting.DARK_GREEN + "Spruce Wood", 1) ); put( "LOG:2", - Utils.createItemStack(Item.getItemFromBlock(Blocks.log), EnumChatFormatting.DARK_GREEN + "Birch", 2) + Utils.createItemStack(Item.getItemFromBlock(Blocks.log), EnumChatFormatting.DARK_GREEN + "Birch Wood", 2) ); put( "LOG_2:1", - Utils.createItemStack(Item.getItemFromBlock(Blocks.log2), EnumChatFormatting.DARK_GREEN + "Dark Oak", 1) + Utils.createItemStack(Item.getItemFromBlock(Blocks.log2), EnumChatFormatting.DARK_GREEN + "Dark Oak Wood", 1) ); - put("LOG_2", Utils.createItemStack(Item.getItemFromBlock(Blocks.log2), EnumChatFormatting.DARK_GREEN + "Acacia")); + put("LOG_2", Utils.createItemStack(Item.getItemFromBlock(Blocks.log2), EnumChatFormatting.DARK_GREEN + "Acacia Wood")); put( "LOG:3", - Utils.createItemStack(Item.getItemFromBlock(Blocks.log), EnumChatFormatting.DARK_GREEN + "Jungle", 3) + Utils.createItemStack(Item.getItemFromBlock(Blocks.log), EnumChatFormatting.DARK_GREEN + "Jungle Wood", 3) ); /* FISHING COLLECTIONS */ - put("RAW_FISH", Utils.createItemStack(Items.fish, EnumChatFormatting.AQUA + "Fish")); + put("RAW_FISH", Utils.createItemStack(Items.fish, EnumChatFormatting.AQUA + "Raw Fish")); put("RAW_FISH:1", Utils.createItemStack(Items.fish, EnumChatFormatting.AQUA + "Salmon", 1)); put("RAW_FISH:2", Utils.createItemStack(Items.fish, EnumChatFormatting.AQUA + "Clownfish", 2)); put("RAW_FISH:3", Utils.createItemStack(Items.fish, EnumChatFormatting.AQUA + "Pufferfish", 3)); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/recipes/RecipeGenerator.java b/src/main/java/io/github/moulberry/notenoughupdates/recipes/RecipeGenerator.java index d63ea42c..54daf42d 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/recipes/RecipeGenerator.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/recipes/RecipeGenerator.java @@ -33,7 +33,6 @@ import net.minecraft.inventory.ContainerChest; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagList; -import net.minecraft.util.ChatComponentText; import net.minecraft.util.EnumChatFormatting; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.gameevent.TickEvent; @@ -91,32 +90,30 @@ public class RecipeGenerator { if (uiTitle.equals("Confirm Process") && saveRecipe) { ForgeRecipe recipe = parseSingleForgeRecipe(menu); if (recipe == null) { - p.addChatMessage(new ChatComponentText( - "" + EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + "Could not parse recipe for this UI")); + Utils.addChatMessage( + "" + EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + "Could not parse recipe for this UI"); } else { - p.addChatMessage(new ChatComponentText( - "" + EnumChatFormatting.GREEN + EnumChatFormatting.BOLD + "Parsed recipe:")); - p.addChatMessage(new ChatComponentText("" + EnumChatFormatting.AQUA + " Inputs:")); + Utils.addChatMessage("" + EnumChatFormatting.GREEN + EnumChatFormatting.BOLD + "Parsed recipe:"); + Utils.addChatMessage("" + EnumChatFormatting.AQUA + " Inputs:"); for (Ingredient i : recipe.getInputs()) - p.addChatMessage(new ChatComponentText( - " - " + EnumChatFormatting.AQUA + i.getInternalItemId() + " x " + i.getCount())); - p.addChatMessage(new ChatComponentText("" + EnumChatFormatting.AQUA + " Output: " + EnumChatFormatting.GOLD + - recipe.getOutput().getInternalItemId() + " x " + recipe.getOutput().getCount())); - p.addChatMessage(new ChatComponentText( + Utils.addChatMessage(" - " + EnumChatFormatting.AQUA + i.getInternalItemId() + " x " + i.getCount()); + Utils.addChatMessage("" + EnumChatFormatting.AQUA + " Output: " + EnumChatFormatting.GOLD + + recipe.getOutput().getInternalItemId() + " x " + recipe.getOutput().getCount()); + Utils.addChatMessage( "" + EnumChatFormatting.AQUA + " Time: " + EnumChatFormatting.GRAY + recipe.getTimeInSeconds() + - " seconds (no QF) .")); + " seconds (no QF) ."); boolean saved = false; try { saved = saveRecipes(recipe.getOutput().getInternalItemId(), Collections.singletonList(recipe)); - } catch (IOException e) { + } catch (IOException ignored) { } if (!saved) - p.addChatMessage(new ChatComponentText("" + - EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + EnumChatFormatting.OBFUSCATED + "#" + - EnumChatFormatting.RESET + EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + " ERROR " + - EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + EnumChatFormatting.OBFUSCATED + "#" + - EnumChatFormatting.RESET + EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + - " Failed to save recipe. Does the item already exist?")); + Utils.addChatMessage( + "" + EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + EnumChatFormatting.OBFUSCATED + "#" + + EnumChatFormatting.RESET + EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + " ERROR " + + EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + EnumChatFormatting.OBFUSCATED + "#" + + EnumChatFormatting.RESET + EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + + " Failed to save recipe. Does the item already exist?"); } } if (saveRecipe) attemptToSaveBestiary(menu); @@ -171,8 +168,7 @@ public class RecipeGenerator { for (String loreLine : mobLore) { Matcher loreMatcher = LORE_PATTERN.matcher(loreLine); if (!loreMatcher.matches()) { - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( - "[WARNING] Unknown lore line: " + loreLine)); + Utils.addChatMessage("[WARNING] Unknown lore line: " + loreLine); continue; } if (loreMatcher.group("coins") != null) @@ -186,8 +182,7 @@ public class RecipeGenerator { List<JsonObject> possibleItems = neu.manager.getItemInformation().values().stream().filter(it -> it.get( "displayname").getAsString().equals(dropName)).collect(Collectors.toList()); if (possibleItems.size() != 1) { - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( - "[WARNING] Could not parse drop, ambiguous or missing item information: " + loreLine)); + Utils.addChatMessage("[WARNING] Could not parse drop, ambiguous or missing item information: " + loreLine); continue; } Ingredient item = new Ingredient(neu.manager, possibleItems.get(0).get("internalname").getAsString()); @@ -197,9 +192,7 @@ public class RecipeGenerator { drops.add(new MobLootRecipe.MobDrop(item, chance, new ArrayList<>())); } if (loreMatcher.group("missing") != null) { - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( - "[WARNING] You are missing Bestiary levels for drop: " + loreLine)); - + Utils.addChatMessage("[WARNING] You are missing Bestiary levels for drop: " + loreLine); } } recipes.add(new MobLootRecipe( @@ -218,15 +211,15 @@ public class RecipeGenerator { boolean saved = false; try { saved = saveRecipes(internalMobName, recipes); - } catch (IOException e) { + } catch (IOException ignored) { } if (!saved) - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("" + - EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + EnumChatFormatting.OBFUSCATED + "#" + - EnumChatFormatting.RESET + EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + " ERROR " + - EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + EnumChatFormatting.OBFUSCATED + "#" + - EnumChatFormatting.RESET + EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + - " Failed to save recipe. Does the item already exist?")); // TODO: MERGE CODE OVER + Utils.addChatMessage( + "" + EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + EnumChatFormatting.OBFUSCATED + "#" + + EnumChatFormatting.RESET + EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + " ERROR " + + EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + EnumChatFormatting.OBFUSCATED + "#" + + EnumChatFormatting.RESET + EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + + " Failed to save recipe. Does the item already exist?"); // TODO: MERGE CODE OVER } private int parseIntIgnoringCommas(String text) { @@ -307,7 +300,7 @@ public class RecipeGenerator { ); } - private static Map<Character, Integer> durationSuffixLengthMap = new HashMap<Character, Integer>() {{ + private static final Map<Character, Integer> durationSuffixLengthMap = new HashMap<Character, Integer>() {{ put('d', 60 * 60 * 24); put('h', 60 * 60); put('m', 60); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/NEUDebugLogger.java b/src/main/java/io/github/moulberry/notenoughupdates/util/NEUDebugLogger.java index 230b8ae5..e5d00a66 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/NEUDebugLogger.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/NEUDebugLogger.java @@ -34,7 +34,7 @@ public class NEUDebugLogger { public static boolean allFlagsEnabled = false; private static void chatLogger(String message) { - mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "[NEU DEBUG] " + message)); + Utils.addChatMessage(EnumChatFormatting.YELLOW + "[NEU DEBUG] " + message); } public static boolean isFlagEnabled(NEUDebugFlag flag) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java b/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java index 9419be4f..dd7ccbcf 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java @@ -24,6 +24,7 @@ import com.google.gson.JsonObject; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.listener.ScoreboardLocationChangeListener; import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.LocationChangeEvent; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.MinionHelperManager; import io.github.moulberry.notenoughupdates.overlays.SlayerOverlay; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiScreen; @@ -38,7 +39,6 @@ import net.minecraft.scoreboard.Score; import net.minecraft.scoreboard.ScoreObjective; import net.minecraft.scoreboard.ScorePlayerTeam; import net.minecraft.scoreboard.Scoreboard; -import net.minecraft.util.ChatComponentText; import net.minecraft.util.EnumChatFormatting; import net.minecraft.util.IChatComponent; import net.minecraftforge.client.event.ClientChatReceivedEvent; @@ -149,8 +149,7 @@ public class SBInfo { public boolean checkForSkyblockLocation() { if (!NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard() || getLocation() == null) { - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + - "[NEU] This command is not available outside SkyBlock")); + Utils.addChatMessage(EnumChatFormatting.RED + "[NEU] This command is not available outside SkyBlock"); return false; } @@ -296,7 +295,7 @@ public class SBInfo { for (NetworkPlayerInfo info : Minecraft.getMinecraft().thePlayer.sendQueue.getPlayerInfoMap()) { String name = Minecraft.getMinecraft().ingameGUI.getTabList().getPlayerName(info); if (name.startsWith(profilePrefix)) { - currentProfile = Utils.cleanColour(name.substring(profilePrefix.length())); + setCurrentProfile(Utils.cleanColour(name.substring(profilePrefix.length()))); hasNewTab = true; } else if (name.startsWith(skillsPrefix)) { String levelInfo = name.substring(skillsPrefix.length()).trim(); @@ -415,4 +414,11 @@ public class SBInfo { e.printStackTrace(); } } + + public void setCurrentProfile(String newProfile) { + if (!newProfile.equals(currentProfile)) { + currentProfile = newProfile; + MinionHelperManager.getInstance().onProfileSwitch(); + } + } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java b/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java index 4d546505..29c039b8 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java @@ -326,6 +326,7 @@ public class Utils { } public static String shortNumberFormat(double n, int iteration) { + if (n < 1000 && iteration == 0) return "" + (int) n; double d = ((long) n / 100) / 10.0; boolean isRound = (d * 10) % 10 == 0; return (d < 1000 ? @@ -1940,9 +1941,13 @@ public class Utils { public static void showOutdatedRepoNotification() { NotificationHandler.displayNotification(Lists.newArrayList( EnumChatFormatting.RED + EnumChatFormatting.BOLD.toString() + "Missing repo data", - EnumChatFormatting.RED + "Data used for many NEU features is not up to date, this should normally not be the case.", - EnumChatFormatting.RED + "You can try " + EnumChatFormatting.BOLD + "/neuresetrepo" + EnumChatFormatting.RESET + EnumChatFormatting.RED +" and restart your game" + - " to see if that fixes the issue.", EnumChatFormatting.RED + "If the problem persists please join " + EnumChatFormatting.BOLD + "discord.gg/moulberry" + + EnumChatFormatting.RED + + "Data used for many NEU features is not up to date, this should normally not be the case.", + EnumChatFormatting.RED + "You can try " + EnumChatFormatting.BOLD + "/neuresetrepo" + EnumChatFormatting.RESET + + EnumChatFormatting.RED + " and restart your game" + + " to see if that fixes the issue.", + EnumChatFormatting.RED + "If the problem persists please join " + EnumChatFormatting.BOLD + + "discord.gg/moulberry" + EnumChatFormatting.RESET + EnumChatFormatting.RED + " and message in " + EnumChatFormatting.BOLD + "#neu-support" + EnumChatFormatting.RESET + EnumChatFormatting.RED + " to get support" ), @@ -1974,4 +1979,13 @@ public class Utils { } return -1; } + + public static void addChatMessage(String message) { + EntityPlayerSP thePlayer = Minecraft.getMinecraft().thePlayer; + if (thePlayer != null) { + thePlayer.addChatMessage(new ChatComponentText(message)); + } else { + System.out.println(message); + } + } } |