aboutsummaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
authorhannibal2 <24389977+hannibal002@users.noreply.github.com>2022-10-23 13:33:15 +0200
committerGitHub <noreply@github.com>2022-10-23 13:33:15 +0200
commitdd6a4011a95da0481b98ff472dedc7911f9a3741 (patch)
treec526a50c3dd178cc55b6d92529e6c89d265dc0ce /src/main
parenta2e1983b47392d7724df78f842ef81bfb6f67d60 (diff)
downloadNotEnoughUpdates-dd6a4011a95da0481b98ff472dedc7911f9a3741.tar.gz
NotEnoughUpdates-dd6a4011a95da0481b98ff472dedc7911f9a3741.tar.bz2
NotEnoughUpdates-dd6a4011a95da0481b98ff472dedc7911f9a3741.zip
Minion Helper (#254)
Co-authored-by: hannibal2 <24389977+hannibal00212@users.noreply.github.com> Co-authored-by: ThexXTURBOXx <nico.mexis@kabelmail.de> Co-authored-by: efefury <69400149+efefury@users.noreply.github.com>
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java33
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DevTestCommand.java32
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/commands/dev/PackDevCommand.java8
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/commands/dev/StatsCommand.java8
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/commands/dungeon/DnCommand.java5
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/commands/dungeon/JoinDungeonCommand.java13
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/commands/dungeon/MapCommand.java4
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/commands/help/FeaturesCommand.java20
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/commands/help/HelpCommand.java10
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/commands/help/LinksCommand.java7
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/commands/misc/AhCommand.java10
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/commands/misc/CalculatorCommand.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/commands/misc/CosmeticsCommand.java7
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/commands/profile/PeekCommand.java44
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/commands/profile/ViewProfileCommand.java20
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/core/util/ArrowPagesUtils.java190
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/core/util/StringUtils.java16
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/events/ProfileDataLoadedEvent.java40
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/infopanes/DevInfoPane.java8
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/listener/ChatListener.java7
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/listener/NEUEventListener.java25
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/listener/RenderListener.java81
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/listener/ScoreboardLocationChangeListener.java4
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CookieWarning.java7
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalMetalDetectorSolver.java26
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalWishingCompassSolver.java64
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/FairySouls.java4
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/Navigation.java6
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/PetInfoOverlay.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiItemRecipe.java126
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/TrophyRewardOverlay.java15
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/ApiData.java84
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/Minion.java112
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/MinionHelperManager.java332
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/MinionHelperApiLoader.java305
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/MinionHelperChatLoader.java91
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/MinionHelperInventoryLoader.java175
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/repo/MinionHelperRepoLoader.java218
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/repo/MinionHelperRepoMinionLoader.java132
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/repo/RecipeBuilder.java75
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/render/MinionHelperOverlay.java439
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/render/MinionHelperOverlayHover.java274
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/render/MinionHelperTooltips.java91
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/render/renderables/OverviewLine.java25
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/render/renderables/OverviewText.java42
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/requirements/CollectionRequirement.java44
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/requirements/CustomRequirement.java33
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/requirements/MinionRequirement.java24
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/requirements/ReputationRequirement.java51
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/requirements/SlayerRequirement.java46
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/sources/CraftingSource.java35
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/sources/CustomSource.java33
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/sources/MinionSource.java23
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/sources/NpcSource.java47
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/util/MinionHelperPriceCalculation.java195
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/util/MinionHelperRequirementsManager.java129
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinEntityPlayerSP.java5
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java8
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/MinionHelper.java45
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/overlays/MiningOverlay.java32
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/Panorama.java5
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/bestiary/BestiaryData.java5
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/lily/LilyDungeonsWeight.java1
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/lily/LilySkillsWeight.java5
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/lily/LilySlayerWeight.java1
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/lily/LilyWeight.java1
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/senither/SenitherDungeonsWeight.java1
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/senither/SenitherSkillsWeight.java1
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/senither/SenitherSlayerWeight.java1
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/senither/SenitherWeight.java1
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/weight/DungeonsWeight.java1
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/weight/SkillsWeight.java1
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/weight/SlayerWeight.java1
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/recipes/RecipeGenerator.java61
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/ApiUtil.java22
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/HotmInformation.java24
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/HypixelApi.java0
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/NEUDebugLogger.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java13
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/TabListUtils.java70
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java30
-rw-r--r--src/main/resources/assets/notenoughupdates/minion_overlay.pngbin0 -> 393 bytes
83 files changed, 3810 insertions, 428 deletions
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java
index 34d87c5b..af190244 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java
@@ -132,6 +132,8 @@ public class NEUManager {
private final HashMap<String, Set<NeuRecipe>> recipesMap = new HashMap<>();
private final HashMap<String, Set<NeuRecipe>> usagesMap = new HashMap<>();
+ private final Map<String, String> displayNameCache = new HashMap<>();
+
public String latestRepoCommit = null;
public File configLocation;
@@ -157,10 +159,6 @@ public class NEUManager {
repoLocation.mkdir();
}
- public void setCurrentProfile(String currentProfile) {
- SBInfo.getInstance().currentProfile = currentProfile;
- }
-
public String getCurrentProfile() {
return SBInfo.getInstance().currentProfile;
}
@@ -1606,6 +1604,7 @@ public class NEUManager {
new RepositoryReloadEvent(repoLocation, !hasBeenLoadedBefore).post();
hasBeenLoadedBefore = true;
comp.complete(null);
+ displayNameCache.clear();
} catch (Exception e) {
comp.completeExceptionally(e);
}
@@ -1622,4 +1621,30 @@ public class NEUManager {
public boolean isValidInternalName(String internalName) {
return itemMap.containsKey(internalName);
}
+
+ 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;
+ }
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java
index 054cbca4..143033b7 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java
@@ -68,6 +68,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.EquipmentOverlay;
@@ -318,6 +319,7 @@ public class NotEnoughUpdates {
MinecraftForge.EVENT_BUS.register(AbiphoneWarning.getInstance());
MinecraftForge.EVENT_BUS.register(new BetterContainers());
MinecraftForge.EVENT_BUS.register(AuctionBINWarning.getInstance());
+ MinecraftForge.EVENT_BUS.register(MinionHelperManager.getInstance());
MinecraftForge.EVENT_BUS.register(navigation);
MinecraftForge.EVENT_BUS.register(new WorldListener(this));
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 138486c3..5f1fe191 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
@@ -23,13 +23,17 @@ import io.github.moulberry.notenoughupdates.BuildFlags;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
import io.github.moulberry.notenoughupdates.commands.ClientCommandBase;
import io.github.moulberry.notenoughupdates.core.config.GuiPositionEditor;
+import io.github.moulberry.notenoughupdates.core.util.MiscUtils;
import io.github.moulberry.notenoughupdates.miscfeatures.FishingHelper;
import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.CustomBiomes;
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.PronounDB;
import io.github.moulberry.notenoughupdates.util.SBInfo;
+import io.github.moulberry.notenoughupdates.util.TabListUtils;
+import io.github.moulberry.notenoughupdates.util.Utils;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.command.CommandException;
@@ -62,7 +66,8 @@ public class DevTestCommand extends ClientCommandBase {
"a7d6b3f1-8425-48e5-8acc-9a38ab9b86f7", // whalker
"0ce87d5a-fa5f-4619-ae78-872d9c5e07fe", // ascynx
"a049a538-4dd8-43f8-87d5-03f09d48b4dc", // egirlefe
- "7a9dc802-d401-4d7d-93c0-8dd1bc98c70d" // efefury
+ "7a9dc802-d401-4d7d-93c0-8dd1bc98c70d", // efefury
+ "bb855349-dfd8-4125-a750-5fc2cf543ad5" // hannibal2
);
private static final String[] DEV_FAIL_STRINGS = {
@@ -114,8 +119,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")) {
@@ -167,7 +171,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")) {
@@ -176,8 +181,7 @@ 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 == 1 && args[0].equalsIgnoreCase("bluehair")) {
@@ -187,11 +191,10 @@ public class DevTestCommand extends ClientCommandBase {
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")) {
@@ -199,5 +202,16 @@ 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);
+ }
+ if (args.length == 1 && args[0].equalsIgnoreCase("copytablist")) {
+ StringBuilder builder = new StringBuilder();
+ for (String name : TabListUtils.getTabList()) {
+ builder.append(name).append("\n");
+ }
+ MiscUtils.copyToClipboard(builder.toString());
+ Utils.addChatMessage("§e[NEU] Copied tablist to clipboard!");
+ }
}
}
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 e9d4eb44..ea417977 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.client.FMLClientHandler;
@@ -119,10 +119,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 c1f88942..58bfbef2 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].toLowerCase().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 49123f45..3a47509d 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 d51d4d2e..1ca398ef 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 NEU AH: an api key is not set. Run /api new and put the result in settings."));
+ Utils.addChatMessage(
+ EnumChatFormatting.RED + "Can't open NEU AH: an api key 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/CalculatorCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/CalculatorCommand.java
index 2ba93585..b01f106b 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/CalculatorCommand.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/CalculatorCommand.java
@@ -26,8 +26,8 @@ import net.minecraft.command.ICommandSender;
import net.minecraft.util.ChatComponentText;
import net.minecraft.util.EnumChatFormatting;
-import java.text.DecimalFormat;
import java.math.BigDecimal;
+import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
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 67430ffa..bbab316e 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 OptiFine Fast Render. Go to ESC > Options > Video Settings > Performance > Fast Render to disable it."));
+ Utils.addChatMessage(EnumChatFormatting.RED +
+ "NEU Cosmetics do not work with OptiFine 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 77377917..23852ab6 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
@@ -78,8 +78,8 @@ public class PeekCommand extends ClientCommandBase {
}
if (peekScheduledFuture != null && !peekScheduledFuture.isDone()) {
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(
- EnumChatFormatting.RED + "[PEEK] New peek command was run, cancelling old one."));
+ Utils.addChatMessage(
+ EnumChatFormatting.RED + "[PEEK] New peek command was run, cancelling old one.");
peekScheduledFuture.cancel(true);
}
@@ -136,8 +136,7 @@ public class PeekCommand extends ClientCommandBase {
EnumChatFormatting.STRIKETHROUGH + "-=-"), id);
if (skyblockInfo == 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;
@@ -208,20 +207,17 @@ 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) + g + "-" +
endermanPrefix + (int) Math.floor(enderman) + g + "-" +
- blazePrefix + (int) Math.floor(blaze)));
+ blazePrefix + (int) Math.floor(blaze));
}
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");
@@ -249,11 +245,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);
@@ -275,11 +270,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));
@@ -295,8 +289,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) {
@@ -321,8 +314,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 887cd28f..26468e39 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 OptiFine 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 OptiFine 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, an API key is not set. Run /api new and put the result in settings."));
+ Utils.addChatMessage(EnumChatFormatting.RED +
+ "Can't view profile, an API key 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 the API is down? Try /api new."));
+ Utils.addChatMessage(EnumChatFormatting.RED +
+ "Invalid player name/API key. Maybe the 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 the API is down? Try /api new."));
+ Utils.addChatMessage(EnumChatFormatting.RED + "Invalid player name/api key. Maybe the 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/ArrowPagesUtils.java b/src/main/java/io/github/moulberry/notenoughupdates/core/util/ArrowPagesUtils.java
new file mode 100644
index 00000000..86430804
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/core/util/ArrowPagesUtils.java
@@ -0,0 +1,190 @@
+/*
+ * 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.Keyboard;
+import org.lwjgl.input.Mouse;
+import org.lwjgl.opengl.GL11;
+
+import java.awt.*;
+import java.util.function.Consumer;
+
+public class ArrowPagesUtils {
+
+ 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, 28, Color.BLACK.getRGB()
+ );
+ }
+
+ public static boolean onPageSwitchKey(
+ int currentPage,
+ int totalPages,
+ Consumer<Integer> pageChange
+ ) {
+
+ int keyPressed = Keyboard.getEventKey() == 0 ? Keyboard.getEventCharacter() + 256 : Keyboard.getEventKey();
+ if (Keyboard.getEventKeyState() && keyPressed == Keyboard.KEY_LEFT) {
+ int newPage = currentPage - 1;
+ pageChange.accept(MathHelper.clamp_int(newPage, 0, totalPages - 1));
+ return true;
+ }
+ if (Keyboard.getEventKeyState() && keyPressed == Keyboard.KEY_RIGHT) {
+ int newPage = currentPage + 1;
+ pageChange.accept(MathHelper.clamp_int(newPage, 0, totalPages - 1));
+ return true;
+ }
+
+ return false;
+ }
+
+ public static boolean onPageSwitchMouse(
+ int guiLeft,
+ int guiTop,
+ int[] topLeft,
+ int currentPage,
+ int totalPages,
+ Consumer<Integer> pageChange
+ ) {
+
+ int keyPressed = Keyboard.getEventKey() == 0 ? Keyboard.getEventCharacter() + 256 : Keyboard.getEventKey();
+ if (Keyboard.getEventKeyState() && keyPressed == Keyboard.KEY_LEFT) {
+ int newPage = currentPage - 1;
+ pageChange.accept(MathHelper.clamp_int(newPage, 0, totalPages - 1));
+ return true;
+ }
+ if (Keyboard.getEventKeyState() && keyPressed == Keyboard.KEY_RIGHT) {
+ int newPage = currentPage + 1;
+ pageChange.accept(MathHelper.clamp_int(newPage, 0, totalPages - 1));
+ return true;
+ }
+
+ 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 a4f814d1..7ea9cd00 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/core/util/StringUtils.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/core/util/StringUtils.java
@@ -102,4 +102,20 @@ public class StringUtils {
int start = string.lastIndexOf(toReplace);
return string.substring(0, start) + replacement + string.substring(start + toReplace.length());
}
+
+ public static String removeLastWord(String string, String splitString) {
+ try {
+ String[] split = string.split(splitString);
+ 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/events/ProfileDataLoadedEvent.java b/src/main/java/io/github/moulberry/notenoughupdates/events/ProfileDataLoadedEvent.java
new file mode 100644
index 00000000..956acfe0
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/events/ProfileDataLoadedEvent.java
@@ -0,0 +1,40 @@
+/*
+ * 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.events;
+
+import com.google.gson.JsonObject;
+
+import javax.annotation.Nullable;
+
+//TODO extend the usage of this event (accessory bag and storage data)
+public class ProfileDataLoadedEvent extends NEUEvent {
+
+ @Nullable
+ private final JsonObject data;
+
+ public ProfileDataLoadedEvent(@Nullable JsonObject entireApiResponse) {
+ this.data = entireApiResponse;
+ }
+
+ @Nullable
+ public JsonObject getData() {
+ return data;
+ }
+}
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 253cc245..421bc798 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;
@@ -656,7 +654,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) {
@@ -881,7 +879,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) {
@@ -914,7 +912,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 0ad9fd99..a5acd5b4 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/listener/ChatListener.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/listener/ChatListener.java
@@ -201,11 +201,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 ")) {
@@ -214,8 +214,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 e202b828..43a1daf9 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/listener/NEUEventListener.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/listener/NEUEventListener.java
@@ -235,35 +235,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 2abb2ee8..2eb4c23a 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/listener/RenderListener.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/listener/RenderListener.java
@@ -50,6 +50,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.miscgui.hex.GuiCustomHex;
import io.github.moulberry.notenoughupdates.mixins.AccessorGuiContainer;
import io.github.moulberry.notenoughupdates.options.NEUConfig;
@@ -83,7 +84,6 @@ import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
-import net.minecraft.util.ChatComponentText;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.StringUtils;
@@ -327,8 +327,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);
}
@@ -538,6 +537,12 @@ 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) {
@@ -666,6 +671,12 @@ 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) {
@@ -1143,6 +1154,12 @@ 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) {
@@ -1306,17 +1323,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) {
@@ -1411,8 +1426,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;
@@ -1441,17 +1455,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) &&
@@ -1471,9 +1484,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);
@@ -1493,13 +1506,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;
}
@@ -1703,7 +1714,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) {
@@ -1717,4 +1728,24 @@ public class RenderListener {
public void onRenderLast(RenderWorldLastEvent event) {
CrystalMetalDetectorSolver.render(event.partialTicks);
}
+
+ /**
+ * Support for switching between different pages in the RecipeView gui via right and left arrow key
+ * @param event
+ */
+ //Because GuiScreen.keyTyped does not fire the KEY_LEFT and KEY_RIGHT keys. Maybe some event cancelled it?
+ @SubscribeEvent
+ public void onMouseClick(GuiScreenEvent.KeyboardInputEvent.Post event) {
+
+ if (!NotEnoughUpdates.INSTANCE.isOnSkyblock()) return;
+
+ Minecraft minecraft = Minecraft.getMinecraft();
+ if (minecraft == null || minecraft.thePlayer == null) return;
+
+ GuiScreen screen = minecraft.currentScreen;
+ if (screen instanceof GuiItemRecipe) {
+ GuiItemRecipe itemRecipe = (GuiItemRecipe) screen;
+ itemRecipe.arrowKeyboardInput();
+ }
+ }
}
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 ab9345cb..23115c36 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 (NEUDebugFlag.METAL.isSet() &&
(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 0ee29b4f..f378fdca 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalWishingCompassSolver.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalWishingCompassSolver.java
@@ -233,35 +233,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;
@@ -374,39 +374,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();
}
}
@@ -780,15 +777,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;
}
@@ -798,13 +794,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]";
@@ -919,8 +915,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 6244c32c..89e95e25 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/Navigation.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/Navigation.java
@@ -38,7 +38,6 @@ import net.minecraft.client.gui.inventory.GuiChest;
import net.minecraft.inventory.ContainerChest;
import net.minecraft.item.ItemStack;
import net.minecraft.util.BlockPos;
-import net.minecraft.util.ChatComponentText;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.Vec3i;
import net.minecraftforge.client.event.RenderWorldLastEvent;
@@ -93,7 +92,7 @@ public class Navigation {
}
}
- private NotEnoughUpdates neu;
+ private final NotEnoughUpdates neu;
public Navigation(NotEnoughUpdates notEnoughUpdates) {
neu = notEnoughUpdates;
@@ -379,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 776e3647..20fa553f 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/PetInfoOverlay.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/PetInfoOverlay.java
@@ -1087,7 +1087,7 @@ public class PetInfoOverlay extends TextOverlay {
PetInfoOverlay.config.selectedPet = -1;
Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(
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(
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 e06c271f..0a1e5b81 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.ArrowPagesUtils;
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();
+ ArrowPagesUtils.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,15 @@ 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;
- }
- }
+ ArrowPagesUtils.onPageSwitchMouse(
+ 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)) {
@@ -398,4 +303,9 @@ public class GuiItemRecipe extends GuiScreen {
currentRecipe.mouseClicked(this, mouseX, mouseY, mouseButton);
}
+
+ public void arrowKeyboardInput() {
+ ArrowPagesUtils.onPageSwitchKey(currentIndex, getCurrentRecipeList().size(), pageChange ->
+ changeRecipe(currentTab, pageChange));
+ }
}
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 e6c4dc74..828e50b1 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/TrophyRewardOverlay.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/TrophyRewardOverlay.java
@@ -160,7 +160,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(" ");
@@ -206,6 +206,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..215c3fe7
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/ApiData.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2022 NotEnoughUpdates contributors
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.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;
+ private int peltCount;
+
+ public ApiData(
+ Map<String, Integer> highestCollectionTier,
+ Map<String, Integer> slayerTiers,
+ int magesReputation,
+ int barbariansReputation,
+ boolean collectionApiDisabled,
+ List<String> craftedMinions,
+ int peltCount
+ ) {
+ this.highestCollectionTier = highestCollectionTier;
+ this.slayerTiers = slayerTiers;
+ this.magesReputation = magesReputation;
+ this.barbariansReputation = barbariansReputation;
+ this.collectionApiDisabled = collectionApiDisabled;
+ this.craftedMinions = craftedMinions;
+ this.peltCount = peltCount;
+ }
+
+ 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;
+ }
+
+ public int getPeltCount() {
+ return peltCount;
+ }
+
+ public void setPeltCount(int peltCount) {
+ this.peltCount = peltCount;
+ }
+}
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..f3c8a86a
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/MinionHelperManager.java
@@ -0,0 +1,332 @@
+/*
+ * 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 int localPelts = -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 MinionHelperInventoryLoader inventoryLoader = new MinionHelperInventoryLoader(this);
+ private String debugPlayerUuid;
+ private String debugProfileName;
+ private int debugNeedForNextSlot = -1;
+
+ 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(new MinionHelperTooltips(this));
+ MinecraftForge.EVENT_BUS.register(new MinionHelperChatLoader(this));
+ 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;
+ String name = containerChest.getLowerChestInventory().getDisplayName().getUnformattedText();
+ return name.equalsIgnoreCase("Crafted Minions");
+ }
+
+ public boolean notReady() {
+ return !repo.isReadyToUse() || !api.isReadyToUse();
+ }
+
+ public boolean isInvalidApiKey() {
+ return api.isInvalidApiKey();
+ }
+
+ 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(" ", "_");
+ }
+
+ private 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()) {
+ setCrafted(getMinionById(minion));
+ }
+ }
+ }
+
+ public void setCrafted(Minion minion) {
+ minion.setCrafted(true);
+
+ if (minion.getCustomSource() != null) {
+ minion.setMeetRequirements(true);
+
+ for (Minion child : getChildren(minion)) {
+ child.setMeetRequirements(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 (parameter.equals("debugplayer")) {
+ if (args.length == 3) {
+ if (args[2].equals("reset")) {
+ Utils.addChatMessage("§e[NEU] Minion debug player reset.");
+ setDebugPlayer(null, null, -1);
+ return;
+ }
+ }
+ if (args.length < 4) {
+ Utils.addChatMessage("§c[NEU] Usage: /neudevtest minion " +
+ "setplayer <player-uuid> <player-profile-name> [need-for-next-slot]");
+ return;
+ }
+ String playerUuid = args[2];
+ String playerProfileName = args[3];
+ int need = args.length == 5 ? Integer.parseInt(args[4]) : -1;
+ setDebugPlayer(playerUuid, playerProfileName, need);
+ Utils.addChatMessage("§e[NEU] Minion debug player set.");
+ return;
+ }
+
+ 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("§6/neudevtest minion debugplayer <player-uuid> <player-profile-name> [need-for-next-slot] §7" +
+ "See the Minions missing of other player");
+ Utils.addChatMessage("");
+ }
+
+ private void setDebugPlayer(String playerUuid, String playerProfileName, int fakeNeedForNextSlot) {
+ this.debugPlayerUuid = playerUuid;
+ this.debugProfileName = playerProfileName;
+ this.debugNeedForNextSlot = fakeNeedForNextSlot;
+
+ onProfileSwitch();
+ }
+
+ public MinionHelperPriceCalculation getPriceCalculation() {
+ return priceCalculation;
+ }
+
+ public MinionHelperRequirementsManager getRequirementsManager() {
+ return requirementsManager;
+ }
+
+ public MinionHelperApiLoader getApi() {
+ return api;
+ }
+
+ 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);
+ }
+
+ public int getLocalPelts() {
+ return localPelts;
+ }
+
+ public void setLocalPelts(int pelts) {
+ localPelts = pelts;
+ if (localPelts != -1) {
+ ApiData apiData = api.getApiData();
+ if (apiData != null) {
+ apiData.setPeltCount(localPelts);
+ }
+ }
+ }
+
+ public String getDebugPlayerUuid() {
+ return debugPlayerUuid;
+ }
+
+ public String getDebugProfileName() {
+ return debugProfileName;
+ }
+
+ public int getDebugNeedForNextSlot() {
+ return debugNeedForNextSlot;
+ }
+}
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..aaa398f4
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/MinionHelperApiLoader.java
@@ -0,0 +1,305 @@
+/*
+ * 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.events.ProfileDataLoadedEvent;
+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 readyToUse = false;
+ private ApiData apiData = null;
+ private boolean notifyNoCollectionApi = false;
+ private long lastLoaded = 0;
+ private boolean invalidApiKey = 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();
+ } else {
+ if (System.currentTimeMillis() > lastLoaded + 60_000 * 3) {
+ dirty = true;
+ }
+ }
+ }
+
+ private void load() {
+ lastLoaded = System.currentTimeMillis();
+
+ dirty = false;
+ String uuid = getUuid();
+ if (uuid == null) return;
+
+ NotEnoughUpdates.INSTANCE.manager.apiUtils.updateProfileData(uuid);
+ }
+
+ private String getUuid() {
+ EntityPlayerSP thePlayer = Minecraft.getMinecraft().thePlayer;
+ if (thePlayer == null) return null;
+
+ String debugPlayerUuid = manager.getDebugPlayerUuid();
+ if (debugPlayerUuid != null) return debugPlayerUuid;
+
+ return thePlayer.getUniqueID().toString().replace("-", "");
+ }
+
+ @SubscribeEvent
+ public void onApiDataLoaded(ProfileDataLoadedEvent event) {
+ JsonObject data = event.getData();
+ if (data == null) {
+ invalidApiKey = true;
+ return;
+ }
+ invalidApiKey = false;
+
+ if (!data.has("success") || !data.get("success").getAsBoolean()) return;
+ JsonArray profiles = data.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(getUuid());
+
+ String debugProfileName = manager.getDebugProfileName();
+ String currentProfile = debugProfileName != null ? debugProfileName : SBInfo.getInstance().currentProfile;
+
+ if (profileName.equals(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),
+ loadPeltCount(player)
+ );
+
+ manager.reloadData();
+ readyToUse = true;
+ }
+
+ private int loadPeltCount(JsonObject player) {
+ int localPelts = manager.getLocalPelts();
+ if (localPelts != -1) return localPelts;
+
+ int peltCount = 0;
+ if (player.has("trapper_quest")) {
+ JsonObject jsonObject = player.getAsJsonObject("trapper_quest");
+ if (jsonObject.has("pelt_count")) {
+ peltCount = jsonObject.get("pelt_count").getAsInt();
+ }
+ }
+ return peltCount;
+ }
+
+ 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;
+ readyToUse = false;
+ }
+
+ public void prepareProfileSwitch() {
+ ignoreWorldSwitches = true;
+ readyToUse = false;
+ }
+
+ public void onProfileSwitch() {
+ apiData = null;
+ setDirty();
+ ignoreWorldSwitches = false;
+ collectionApiEnabled = true;
+ }
+
+ public boolean isReadyToUse() {
+ return readyToUse;
+ }
+
+ 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;
+ }
+
+ public boolean isInvalidApiKey() {
+ return invalidApiKey;
+ }
+}
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..bef633d2
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/MinionHelperChatLoader.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.loaders;
+
+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.util.Utils;
+import net.minecraftforge.client.event.ClientChatReceivedEvent;
+import net.minecraftforge.fml.common.eventhandler.EventPriority;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class MinionHelperChatLoader {
+
+ private final MinionHelperManager manager;
+
+ //§aYou crafted a §eTier I Redstone Minion§a! That's a new one!
+ // §aCraft §e7 §amore unique Minions to unlock your §e9th Minion slot§a!
+ private final Pattern PATTERN_OWN_MINION = Pattern.compile(
+ "§r§aYou crafted a §eTier (\\S+) (.+) Minion§a! That's a new one!(\\r\\n|\\r|\\n)(.*)");
+ //§aYou crafted a §eTier VI Enderman Minion§a! That's a new one!
+
+ //§b[MVP§3+§b] Eisengolem§f §acrafted a §eTier I Birch Minion§a!
+ private final Pattern PATTERN_COOP_MINION = Pattern.compile(
+ "(.+)§f §acrafted a §eTier (\\S+) (.+) Minion§a!(§r)?(\\r\\n|\\r|\\n)?(.*)?");
+
+ 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 {
+ Matcher ownMatcher = PATTERN_OWN_MINION.matcher(message);
+ if (ownMatcher.matches()) {
+ String rawTier = ownMatcher.group(1);
+ int tier = Utils.parseRomanNumeral(rawTier);
+ String name = ownMatcher.group(2) + " Minion";
+
+ setCrafted(manager.getMinionByName(name, tier));
+ }
+
+ Matcher coopMatcher = PATTERN_COOP_MINION.matcher(message);
+ if (coopMatcher.matches()) {
+ String rawTier = coopMatcher.group(2);
+ int tier = Utils.parseRomanNumeral(rawTier);
+ String name = coopMatcher.group(3) + " Minion";
+
+ 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) {
+ manager.setCrafted(minion);
+ }
+}
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..7fc703e6
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/MinionHelperInventoryLoader.java
@@ -0,0 +1,175 @@
+/*
+ * 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 io.github.moulberry.notenoughupdates.util.TabListUtils;
+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.event.world.WorldEvent;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+import net.minecraftforge.fml.common.gameevent.TickEvent;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class MinionHelperInventoryLoader {
+ private final MinionHelperManager manager;
+ private final List<String> pagesSeenAlready = new ArrayList<>();
+ private boolean dirty = true;
+
+ private int ticks = 0;
+
+ //§7Craft §b5 §7more §aunique §7minions
+ private final Pattern PATTERN_MINIONS_NEEDED = Pattern.compile("§7Craft §b(\\d+) §7more §aunique( §7minions)?");
+
+ //§r §r§fPelts: §r§59§r
+ private final Pattern PATTERN_PELTS = Pattern.compile("§r §r§fPelts: §r§5(\\d+)§r");
+
+ public MinionHelperInventoryLoader(MinionHelperManager manager) {
+ this.manager = manager;
+ }
+
+ @SubscribeEvent
+ public void onWorldLoad(WorldEvent.Load event) {
+ manager.setLocalPelts(-1);
+ }
+
+ @SubscribeEvent
+ public void onTick(TickEvent.ClientTickEvent event) {
+ if (!NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) return;
+ if (!NotEnoughUpdates.INSTANCE.config.minionHelper.gui) return;
+ if (manager.notReady()) return;
+ ticks++;
+
+ if (ticks % 5 != 0) return;
+
+ if (manager.inCraftedMinionsInventory()) {
+ checkInventory();
+ } else {
+ pagesSeenAlready.clear();
+ dirty = true;
+ }
+ }
+
+ private void checkInventory() {
+ Container openContainer = Minecraft.getMinecraft().thePlayer.openContainer;
+ if (openContainer instanceof ContainerChest) {
+ if (dirty) {
+ dirty = false;
+ checkNextSlot(openContainer);
+ checkLocalPelts();
+ }
+ if (manager.getDebugPlayerUuid() == null) {
+ loadMinionData(openContainer);
+ }
+ }
+ }
+
+ private void checkLocalPelts() {
+ int pelts = -1;
+ for (String name : TabListUtils.getTabList()) {
+ Matcher matcher = PATTERN_PELTS.matcher(name);
+ if (matcher.matches()) {
+ pelts = Integer.parseInt(matcher.group(1));
+ break;
+ }
+ }
+
+ manager.setLocalPelts(pelts);
+ }
+
+ private void checkNextSlot(Container openContainer) {
+ Slot informationSlot = openContainer.inventorySlots.get(50);
+ if (informationSlot.getHasStack()) {
+ ItemStack informationStack = informationSlot.getStack();
+ for (String line : ItemUtils.getLore(informationStack)) {
+ Matcher matcher = PATTERN_MINIONS_NEEDED.matcher(line);
+ if (matcher.matches()) {
+ int debugNeedForNextSlot = manager.getDebugNeedForNextSlot();
+ int needForNextSlot = debugNeedForNextSlot != -1 ? debugNeedForNextSlot : Integer.parseInt(matcher.group(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() {
+ dirty = 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..49dac537
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/repo/MinionHelperRepoLoader.java
@@ -0,0 +1,218 @@
+/*
+ * 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 boolean readyToUse = 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();
+ readyToUse = 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 §cFlower Minion 1 §7from Dark Auction"));
+ manager.getMinionById("SNOW_GENERATOR_1").getRequirements().add(new CustomRequirement(
+ "Get a §cSnow Minion 1 §7from 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!");
+ }
+ }
+ }
+ }
+
+ public void setDirty() {
+ dirty = true;
+ readyToUse = false;
+ }
+
+ public boolean isReadyToUse() {
+ return readyToUse;
+ }
+}
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..6219cf2c
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/render/MinionHelperOverlay.java
@@ -0,0 +1,439 @@
+/*
+ * 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.ArrowPagesUtils;
+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.ItemUtils;
+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.client.renderer.RenderHelper;
+import net.minecraft.item.ItemStack;
+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.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+public class MinionHelperOverlay {
+
+ private final ResourceLocation minionOverlayImage = new ResourceLocation("notenoughupdates:minion_overlay.png");
+ private final ResourceLocation greenCheckImage = new ResourceLocation("notenoughupdates:dungeon_map/green_check.png");
+ private final ResourceLocation whiteCheckImage = new ResourceLocation("notenoughupdates:dungeon_map/white_check.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 filterEnabled = true;
+ private boolean useInstantBuyPrice = 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.isInvalidApiKey()) {
+ LinkedHashMap<String, OverviewLine> map = new LinkedHashMap<>();
+ map.put("§cInvalid API Key!", new OverviewText(Collections.emptyList(), () -> {}));
+ render(map);
+ return;
+ }
+ if (manager.notReady()) {
+ LinkedHashMap<String, OverviewLine> map = new LinkedHashMap<>();
+ map.put("§cLoading...", new OverviewText(Collections.emptyList(), () -> {}));
+ render(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);
+ manager.getApi().setNotifyNoCollectionApi(false);
+ }
+
+ LinkedHashMap<String, OverviewLine> renderMap = getRenderMap();
+
+ hover.renderHover(renderMap);
+ render(renderMap);
+
+ renderArrows();
+ }
+
+ private void renderArrows() {
+ GuiScreen gui = Minecraft.getMinecraft().currentScreen;
+ if (gui instanceof AccessorGuiContainer) {
+ AccessorGuiContainer container = (AccessorGuiContainer) gui;
+ int guiLeft = container.getGuiLeft();
+ int guiTop = container.getGuiTop();
+ int totalPages = getTotalPages();
+ ArrowPagesUtils.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.notReady()) 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 (ArrowPagesUtils.onPageSwitchMouse(guiLeft, guiTop, topLeft, currentPage, totalPages, pageChange -> {
+ currentPage = pageChange;
+ resetCache();
+ })) {
+ event.setCanceled(true);
+ }
+ }
+ checkButtonClick();
+ }
+
+ private void checkButtonClick() {
+ GuiScreen gui = Minecraft.getMinecraft().currentScreen;
+ if (!(gui instanceof GuiChest)) return;
+
+ int xSize = ((AccessorGuiContainer) gui).getXSize();
+ int guiLeft = ((AccessorGuiContainer) gui).getGuiLeft();
+ int guiTop = ((AccessorGuiContainer) gui).getGuiTop();
+
+ 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 x = guiLeft + xSize + 4 + 149 - 3;
+ int y = guiTop + 109 - 3;
+ if (mouseX > x && mouseX < x + 16 &&
+ mouseY > y && mouseY < y + 16) {
+ toggleShowAvailable();
+ }
+
+ x = guiLeft + xSize + 4 + 149 - 3 - 16 - 3;
+ y = guiTop + 109 - 3;
+ if (mouseX > x && mouseX < x + 16 &&
+ mouseY > y && mouseY < y + 16) {
+ toggleUseInstantBuyPrice();
+ }
+ }
+
+ @SubscribeEvent
+ public void onMouseClick(GuiScreenEvent.KeyboardInputEvent.Pre event) {
+ if (!manager.inCraftedMinionsInventory()) return;
+ if (!NotEnoughUpdates.INSTANCE.config.minionHelper.gui) return;
+ if (manager.notReady()) return;
+
+ int totalPages = getTotalPages();
+ if (ArrowPagesUtils.onPageSwitchKey(currentPage, totalPages, pageChange -> {
+ currentPage = pageChange;
+ resetCache();
+ })) {
+ event.setCanceled(true);
+ }
+ }
+
+ private Map<Minion, Double> getMissing() {
+ Map<Minion, Double> prices = new HashMap<>();
+ for (Minion minion : manager.getAllMinions().values()) {
+
+ if (!minion.doesMeetRequirements() && filterEnabled) continue;
+ if (!minion.isCrafted()) {
+ double price = manager.getPriceCalculation().calculateUpgradeCosts(minion, true);
+ prices.put(minion, price);
+ }
+ }
+ return prices;
+ }
+
+ private void render(Map<String, OverviewLine> renderMap) {
+ Minecraft minecraft = Minecraft.getMinecraft();
+ Gui gui = Minecraft.getMinecraft().currentScreen;
+ if (!(gui instanceof GuiChest)) return;
+ 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);
+
+ if (filterEnabled) {
+ minecraft.getTextureManager().bindTexture(greenCheckImage);
+ } else {
+ minecraft.getTextureManager().bindTexture(whiteCheckImage);
+ }
+ Utils.drawTexturedRect(guiLeft + xSize + 4 + 149, guiTop + 109, 10, 10, 0, 1f, 0, 1f, GL11.GL_NEAREST);
+ GlStateManager.disableLighting();
+
+ RenderHelper.enableGUIStandardItemLighting();
+ ItemStack itemStack;
+ if (useInstantBuyPrice) {
+ itemStack = ItemUtils.getCoinItemStack(10_000_000);
+ } else {
+ itemStack = ItemUtils.getCoinItemStack(100_000);
+ }
+ Minecraft.getMinecraft().getRenderItem().renderItemIntoGUI(
+ itemStack,
+ guiLeft + xSize + 4 + 149 - 3 - 16 - 3,
+ guiTop + 109 - 3
+ );
+
+ RenderHelper.disableStandardItemLighting();
+
+ int x = guiLeft + xSize + 10;
+ int i = 0;
+ int y = guiTop + 6;
+ FontRenderer fontRendererObj = minecraft.fontRendererObj;
+ for (Map.Entry<String, OverviewLine> entry : renderMap.entrySet()) {
+ String line = entry.getKey();
+
+ if (line.contains("§6")) {
+ String[] split = line.split("§6");
+ line = split[0];
+ String price = "§6§l" + split[1];
+ int lineLen = Minecraft.getMinecraft().fontRendererObj.getStringWidth(line);
+ fontRendererObj.drawString(price, x + lineLen, y, -1, true);
+ }
+
+ fontRendererObj.drawString(line, x, y, -1, false);
+ i++;
+ if (i == 2) {
+ y += 15;
+ } else {
+ y += 10;
+ }
+ }
+ }
+
+ private LinkedHashMap<String, OverviewLine> getRenderMap() {
+ if (cacheRenderMap != null) return cacheRenderMap;
+
+ Map<Minion, Double> 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, Double> prices,
+ LinkedHashMap<String, OverviewLine> renderMap
+ ) {
+ int neededForNextSlot = manager.getNeedForNextSlot();
+ String color = "§8";
+ if (neededForNextSlot == -1) {
+ renderMap.put(color + "Next slot: ?", new OverviewText(Collections.emptyList(), () -> {}));
+ return;
+ }
+
+ double priceNeeded = 0;
+ int index = 0;
+ for (Double price : TrophyRewardOverlay.sortByValue(prices).values()) {
+ priceNeeded += price;
+ index++;
+ if (index == neededForNextSlot) break;
+ }
+ String format = manager.getPriceCalculation().formatCoins(priceNeeded);
+ format = format.replace(" coins", "");
+ String text = color + "Next slot: §3" + neededForNextSlot + " minions §8- " + format;
+ renderMap.put(text, new OverviewText(Collections.emptyList(), () -> {}));
+ }
+
+ private void addTitle(Map<Minion, Double> prices, LinkedHashMap<String, OverviewLine> renderMap) {
+ String name = "§8" + prices.size() + " " + (filterEnabled ? "craftable" : "total") + " minions";
+ renderMap.put(name, new OverviewText(Collections.emptyList(), () -> {}));
+ }
+
+ private void addMinions(Map<Minion, Double> prices, LinkedHashMap<String, OverviewLine> renderMap) {
+ int skipPreviousPages = currentPage * maxPerPage;
+ int i = 0;
+ Map<Minion, Double> 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);
+ format = format.replace(" coins", "");
+ String requirementFormat = minion.doesMeetRequirements() ? "§9" : "§c";
+ renderMap.put(
+ requirementFormat + displayName + " " + minion.getTier() + " §8- " + format,
+ minion
+ );
+ }
+
+ i++;
+ if (i == ((currentPage + 1) * maxPerPage)) break;
+ }
+ }
+
+ private int getTotalPages() {
+ if (cacheTotalPages != -1) return cacheTotalPages;
+
+ Map<Minion, Double> prices = getMissing();
+ int totalPages = (int) ((double) prices.size() / maxPerPage);
+ if (prices.size() % maxPerPage != 0) {
+ totalPages++;
+ }
+
+ cacheTotalPages = totalPages;
+ return totalPages;
+ }
+
+ private void toggleShowAvailable() {
+ filterEnabled = !filterEnabled;
+ currentPage = 0;
+ resetCache();
+ }
+
+ private void toggleUseInstantBuyPrice() {
+ useInstantBuyPrice = !useInstantBuyPrice;
+ currentPage = 0;
+ resetCache();
+ manager.getPriceCalculation().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 + 4 &&
+ mouseY > y && mouseY < y + 11) {
+ return entry.getValue();
+ }
+ i++;
+ if (i == 2) {
+ y += 15;
+ } else {
+ y += 10;
+ }
+ }
+
+ return null;
+ }
+
+ public void onProfileSwitch() {
+ currentPage = 0;
+ filterEnabled = true;
+ useInstantBuyPrice = true;
+ }
+
+ public void setMaxPerPage(int maxPerPage) {
+ this.maxPerPage = maxPerPage;
+ }
+
+ public void setTopLeft(int[] topLeft) {
+ this.topLeft = topLeft;
+ }
+
+ public boolean isFilterEnabled() {
+ return filterEnabled;
+ }
+
+ public boolean isUseInstantBuyPrice() {
+ return useInstantBuyPrice;
+ }
+}
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..fcafa534
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/render/MinionHelperOverlayHover.java
@@ -0,0 +1,274 @@
+/*
+ * 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.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.core.util.StringUtils;
+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.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.requirements.ReputationRequirement;
+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.mixins.AccessorGuiContainer;
+import io.github.moulberry.notenoughupdates.util.Utils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.GuiScreen;
+import net.minecraft.client.gui.ScaledResolution;
+import net.minecraft.client.gui.inventory.GuiChest;
+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;
+
+ public MinionHelperOverlayHover(MinionHelperOverlay overlay, MinionHelperManager manager) {
+ this.overlay = overlay;
+ this.manager = manager;
+ }
+
+ void renderHover(LinkedHashMap<String, OverviewLine> renderMap) {
+ 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) {
+ Utils.drawHoveringText(getTooltip(mouseObject), mouseX, mouseY,
+ scaledWidth, scaledHeight, -1, Minecraft.getMinecraft().fontRendererObj
+ );
+ }
+
+ renderButtons();
+ }
+
+ private void renderButtons() {
+ GuiScreen gui = Minecraft.getMinecraft().currentScreen;
+ if (!(gui instanceof GuiChest)) return;
+
+ int xSize = ((AccessorGuiContainer) gui).getXSize();
+ int guiLeft = ((AccessorGuiContainer) gui).getGuiLeft();
+ int guiTop = ((AccessorGuiContainer) gui).getGuiTop();
+
+ 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 x = guiLeft + xSize + 4 + 149 - 3;
+ int y = guiTop + 109 - 3;
+ if (mouseX > x && mouseX < x + 16 &&
+ mouseY > y && mouseY < y + 16) {
+ renderFilterButton(scaledWidth, scaledHeight, mouseX, mouseY);
+ }
+
+ x = guiLeft + xSize + 4 + 149 - 3 - 16 - 3;
+ y = guiTop + 109 - 3;
+ if (mouseX > x && mouseX < x + 16 &&
+ mouseY > y && mouseY < y + 16) {
+ renderBuyPriceButton(scaledWidth, scaledHeight, mouseX, mouseY);
+ }
+ }
+
+ private void renderFilterButton(int scaledWidth, int scaledHeight, int mouseX, int mouseY) {
+ List<String> list = new ArrayList<>();
+
+ if (overlay.isFilterEnabled()) {
+ list.add("§aFilter enabled");
+ list.add("§7Only show minions that can be");
+ list.add("§7crafted and meet requirements.");
+ } else {
+ list.add("§cFilter disabled");
+ list.add("§7Show all minions. §cRed ones §7have");
+ list.add("§7missing requirements.");
+ }
+
+ list.add("");
+ list.add("§eClick to toggle!");
+
+ Utils.drawHoveringText(list, mouseX, mouseY, scaledWidth, scaledHeight, -1,
+ Minecraft.getMinecraft().fontRendererObj
+ );
+ }
+
+ private void renderBuyPriceButton(int scaledWidth, int scaledHeight, int mouseX, int mouseY) {
+ List<String> list = new ArrayList<>();
+
+ if (overlay.isUseInstantBuyPrice()) {
+ list.add("§bUse Instant Buy price");
+ list.add("§7Use the price to pay when");
+ list.add("§7buying the item right now.");
+ list.add("§7This will be more expensive!");
+ } else {
+ list.add("§6Use Buy Offer price");
+ list.add("§7Use the price for creating an");
+ list.add("§7offer to buy the item cheaper.");
+ list.add("§7This can take longer!");
+ }
+
+ list.add("");
+ list.add("§eClick to toggle!");
+
+ Utils.drawHoveringText(list, mouseX, mouseY, scaledWidth, scaledHeight, -1,
+ Minecraft.getMinecraft().fontRendererObj
+ );
+ }
+
+ 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();
+ if (minion.getCustomSource() != null) {
+ minionSource = minion.getCustomSource();
+ }
+ String displayName = minion.getDisplayName();
+ lines.add("§9" + displayName + " " + minion.getTier());
+ List<MinionRequirement> requirements = manager.getRequirementsManager().getRequirements(minion);
+ if (!requirements.isEmpty()) {
+ for (MinionRequirement requirement : requirements) {
+ String result = getRequirementDescription(minion, requirement);
+ if (result == null) continue;
+ lines.add(result);
+ }
+ } 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 cost: " + format);
+ } else {
+ lines.add("§7Upgrade cost: " + 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("§7Cost: " + 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 String getRequirementDescription(Minion minion, MinionRequirement requirement) {
+ boolean meetRequirement = manager.getRequirementsManager().meetRequirement(minion, requirement);
+ String color = meetRequirement ? "§a" : "§c";
+
+ String description = requirement.printDescription(color);
+ if (requirement instanceof CollectionRequirement && manager.getApi().isCollectionApiDisabled()) {
+ description += " §cAPI DISABLED! §7";
+ }
+
+ if (!meetRequirement) {
+ if (requirement instanceof ReputationRequirement) {
+ ReputationRequirement reputationRequirement = (ReputationRequirement) requirement;
+ String reputationType = reputationRequirement.getReputationType();
+ ApiData apiData = manager.getApi().getApiData();
+ int having;
+ if (reputationType.equals("BARBARIAN")) {
+ having = apiData.getBarbariansReputation();
+ } else if (reputationType.equals("MAGE")) {
+ having = apiData.getMagesReputation();
+ } else {
+ Utils.addChatMessage("§c[NEU] Minion Helper: Unknown reputation type: '" + reputationType + "'");
+ return null;
+ }
+ int need = reputationRequirement.getReputation();
+ if (having < 0) having = 0;
+
+ String reputationName = StringUtils.firstUpperLetter(reputationType.toLowerCase());
+ String havingFormat = Utils.formatNumberWithDots(having);
+ String needFormat = Utils.formatNumberWithDots(need);
+ description = "Reputation: §c" + havingFormat + "§8/§c" + needFormat + " §7" + reputationName + " Reputation";
+ }
+ }
+
+ return " §8- §7" + description;
+ }
+
+ private void formatItems(List<String> lines, Map<String, Integer> allItems) {
+ for (Map.Entry<String, Integer> entry : allItems.entrySet()) {
+ String internalName = entry.getKey();
+ int amount = entry.getValue();
+ if (internalName.equals("SKYBLOCK_PELT")) {
+ int peltCount = manager.getApi().getApiData().getPeltCount();
+
+ lines.add(" §8- §5" + peltCount + "§8/§5" + amount + " Pelts");
+ continue;
+ }
+
+ String name = NotEnoughUpdates.INSTANCE.manager.getDisplayName(internalName);
+ double price = manager.getPriceCalculation().getPrice(internalName);
+ String priceFormat = manager.getPriceCalculation().formatCoins(price * amount);
+ lines.add(" §8- §a" + amount + "§7x §f" + name + " " + priceFormat);
+ }
+ }
+
+ 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;
+ }
+}
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..ef243a6f
--- /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.notReady()) 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 cost]");
+ } else {
+ event.toolTip.add("§8[Press SHIFT to show full cost]");
+ }
+ }
+}
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..c01386e1
--- /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(String color) {
+ return "Collection: " + color + 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..93174f03
--- /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(String color) {
+ 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..9dd3fe09
--- /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(String color);
+}
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..70d1e5fc
--- /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 = Utils.formatNumberWithDots(reputation) + " §7" + reputationName + " Reputation";
+ }
+
+ public int getReputation() {
+ return reputation;
+ }
+
+ public String getReputationType() {
+ return reputationType;
+ }
+
+ @Override
+ public String printDescription(String color) {
+ return "Reputation: " + color + 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..78c588b1
--- /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(String color) {
+ return "Slayer: " + color +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..eca689d1
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/sources/CraftingSource.java
@@ -0,0 +1,35 @@
+/*
+ * 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;
+
+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..941890fa
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/sources/NpcSource.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 NotEnoughUpdates contributors
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.miscgui.minionhelper.sources;
+
+import com.google.common.collect.ArrayListMultimap;
+
+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..8f75b32c
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/util/MinionHelperPriceCalculation.java
@@ -0,0 +1,195 @@
+/*
+ * 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.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<>();
+
+ public MinionHelperPriceCalculation(MinionHelperManager manager) {
+ this.manager = manager;
+ }
+
+ @SubscribeEvent
+ public void onGuiOpen(GuiOpenEvent event) {
+ resetCache();
+ }
+
+ public void resetCache() {
+ 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 (minion.getCustomSource()).getSourceName();
+ }
+ }
+
+ double 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 double 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;
+ double upgradeCost = getCosts(minion, upgradeOnly, npcSource.getItems());
+ long coins = npcSource.getCoins();
+ upgradeCost += coins;
+
+ return upgradeCost;
+ }
+
+ return 0;
+ }
+
+ private double getCosts(Minion minion, boolean upgradeOnly, ArrayListMultimap<String, Integer> items) {
+ double upgradeCost = 0;
+ for (Map.Entry<String, Integer> entry : items.entries()) {
+ String internalName = entry.getKey();
+ if (internalName.equals("SKYBLOCK_PELT")) continue;
+ double 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 double 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) {
+ String bazaarMode;
+ if (manager.getOverlay().isUseInstantBuyPrice()) {
+ bazaarMode = "curr_buy";
+ } else {
+ bazaarMode = "curr_sell";
+ }
+ if (!bazaarInfo.has(bazaarMode)) {
+
+ // Use buy order price when no sell offer exist. (e.g. inferno apex)
+ if (bazaarMode.equals("curr_buy")) {
+ bazaarMode = "curr_sell";
+ if (!bazaarInfo.has(bazaarMode)) {
+ System.err.println(bazaarMode + " does not exist for '" + internalName + "'");
+ return 0;
+ }
+ } else {
+ System.err.println(bazaarMode + " does not exist for '" + internalName + "'");
+ return 0;
+ }
+ }
+ return bazaarInfo.get(bazaarMode).getAsDouble();
+ }
+
+ //is ah bin
+ double avgBinPrice = 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 1;
+ }
+ return (auctionInfo.get("price").getAsFloat() / auctionInfo.get("count").getAsFloat());
+ }
+
+ public String formatCoins(double coins) {
+ return formatCoins(coins, "");
+ }
+
+ public String formatCoins(double coins, String extraFormat) {
+ int i = coins < 3 ? 1 : 0;
+ String format = Utils.shortNumberFormat(coins, i);
+ 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..4a1b96b5
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/util/MinionHelperRequirementsManager.java
@@ -0,0 +1,129 @@
+/*
+ * 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;
+ }
+ }
+
+ Minion parent = minion.getParent();
+ if (parent != null) {
+ return meetAllRequirements(parent);
+ }
+
+ 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();
+ //Because the neu-repo uses 'eman' and the hypixel api is using 'enderman'
+ if (slayer.equals("eman")) {
+ slayer = "enderman";
+ }
+ 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.doesMeetRequirements();
+ }
+
+ 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 e18d1d84..e1e18940 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java
@@ -50,6 +50,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;
@@ -406,6 +407,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/overlays/MiningOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/overlays/MiningOverlay.java
index 60d9b607..7d0b9a0a 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/overlays/MiningOverlay.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/overlays/MiningOverlay.java
@@ -19,8 +19,6 @@
package io.github.moulberry.notenoughupdates.overlays;
-import com.google.common.collect.ComparisonChain;
-import com.google.common.collect.Ordering;
import com.google.gson.annotations.Expose;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
import io.github.moulberry.notenoughupdates.core.config.Position;
@@ -29,16 +27,15 @@ import io.github.moulberry.notenoughupdates.core.util.lerp.LerpUtils;
import io.github.moulberry.notenoughupdates.miscfeatures.ItemCooldowns;
import io.github.moulberry.notenoughupdates.options.NEUConfig;
import io.github.moulberry.notenoughupdates.util.SBInfo;
+import io.github.moulberry.notenoughupdates.util.TabListUtils;
import io.github.moulberry.notenoughupdates.util.Utils;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.inventory.GuiChest;
-import net.minecraft.client.network.NetworkPlayerInfo;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.init.Items;
import net.minecraft.inventory.ContainerChest;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
-import net.minecraft.scoreboard.ScorePlayerTeam;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.world.WorldSettings;
import net.minecraftforge.fml.relauncher.Side;
@@ -47,7 +44,6 @@ import org.lwjgl.input.Keyboard;
import org.lwjgl.util.vector.Vector2f;
import java.util.ArrayList;
-import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
@@ -263,11 +259,8 @@ public class MiningOverlay extends TextTabOverlay {
int forgeInt = 0;
boolean commissions = false;
boolean forges = false;
- List<NetworkPlayerInfo> players =
- playerOrdering.sortedCopy(Minecraft.getMinecraft().thePlayer.sendQueue.getPlayerInfoMap());
- for (NetworkPlayerInfo info : players) {
- String name = Minecraft.getMinecraft().ingameGUI.getTabList().getPlayerName(info);
+ for (String name : TabListUtils.getTabList()) {
if (name.contains("Mithril Powder:")) {
mithrilPowder = DARK_AQUA + Utils.trimWhitespaceAndFormatCodes(name).replaceAll("\u00a7[f|F|r]", "");
continue;
@@ -584,27 +577,6 @@ public class MiningOverlay extends TextTabOverlay {
}
}
- private static final Ordering<NetworkPlayerInfo> playerOrdering = Ordering.from(new PlayerComparator());
-
- @SideOnly(Side.CLIENT)
- static class PlayerComparator implements Comparator<NetworkPlayerInfo> {
- private PlayerComparator() {}
-
- public int compare(NetworkPlayerInfo o1, NetworkPlayerInfo o2) {
- ScorePlayerTeam team1 = o1.getPlayerTeam();
- ScorePlayerTeam team2 = o2.getPlayerTeam();
- return ComparisonChain.start().compareTrueFirst(
- o1.getGameType() != WorldSettings.GameType.SPECTATOR,
- o2.getGameType() != WorldSettings.GameType.SPECTATOR
- )
- .compare(
- team1 != null ? team1.getRegisteredName() : "",
- team2 != null ? team2.getRegisteredName() : ""
- )
- .compare(o1.getGameProfile().getName(), o2.getGameProfile().getName()).result();
- }
- }
-
@Override
protected Vector2f getSize(List<String> strings) {
if (NotEnoughUpdates.INSTANCE.config.mining.dwarvenOverlayIcons)
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/Panorama.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/Panorama.java
index 41217201..af904e1d 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/Panorama.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/Panorama.java
@@ -21,8 +21,6 @@ package io.github.moulberry.notenoughupdates.profileviewer;
import io.github.moulberry.notenoughupdates.util.TexLoc;
import io.github.moulberry.notenoughupdates.util.Utils;
-import java.io.IOException;
-import java.util.HashMap;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.ScaledResolution;
import net.minecraft.client.renderer.GlStateManager;
@@ -36,6 +34,9 @@ import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.glu.Project;
+import java.io.IOException;
+import java.util.HashMap;
+
public class Panorama {
private static final TexLoc tl = new TexLoc(97, 19, Keyboard.KEY_P);
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/bestiary/BestiaryData.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/bestiary/BestiaryData.java
index 7df88964..6f541833 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/bestiary/BestiaryData.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/bestiary/BestiaryData.java
@@ -20,14 +20,15 @@
package io.github.moulberry.notenoughupdates.profileviewer.bestiary;
import io.github.moulberry.notenoughupdates.util.Utils;
-import java.util.LinkedHashMap;
-import java.util.List;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumChatFormatting;
+import java.util.LinkedHashMap;
+import java.util.List;
+
public class BestiaryData {
private static final LinkedHashMap<ItemStack, List<String>> bestiaryLocations = new LinkedHashMap<ItemStack, List<String>>() {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/lily/LilyDungeonsWeight.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/lily/LilyDungeonsWeight.java
index 3ceabaf5..819c16de 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/lily/LilyDungeonsWeight.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/lily/LilyDungeonsWeight.java
@@ -26,6 +26,7 @@ import io.github.moulberry.notenoughupdates.profileviewer.weight.weight.Dungeons
import io.github.moulberry.notenoughupdates.profileviewer.weight.weight.WeightStruct;
import io.github.moulberry.notenoughupdates.util.Constants;
import io.github.moulberry.notenoughupdates.util.Utils;
+
import java.util.Map;
public class LilyDungeonsWeight extends DungeonsWeight {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/lily/LilySkillsWeight.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/lily/LilySkillsWeight.java
index 8ed43f6e..f47032a4 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/lily/LilySkillsWeight.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/lily/LilySkillsWeight.java
@@ -19,16 +19,17 @@
package io.github.moulberry.notenoughupdates.profileviewer.weight.lily;
-import static io.github.moulberry.notenoughupdates.profileviewer.weight.weight.Weight.SKILL_NAMES;
-
import com.google.gson.JsonArray;
import io.github.moulberry.notenoughupdates.profileviewer.ProfileViewer;
import io.github.moulberry.notenoughupdates.profileviewer.weight.weight.SkillsWeight;
import io.github.moulberry.notenoughupdates.profileviewer.weight.weight.WeightStruct;
import io.github.moulberry.notenoughupdates.util.Constants;
import io.github.moulberry.notenoughupdates.util.Utils;
+
import java.util.Map;
+import static io.github.moulberry.notenoughupdates.profileviewer.weight.weight.Weight.SKILL_NAMES;
+
public class LilySkillsWeight extends SkillsWeight {
public LilySkillsWeight(Map<String, ProfileViewer.Level> player) {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/lily/LilySlayerWeight.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/lily/LilySlayerWeight.java
index d26597a1..12cb01e2 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/lily/LilySlayerWeight.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/lily/LilySlayerWeight.java
@@ -24,6 +24,7 @@ import io.github.moulberry.notenoughupdates.profileviewer.weight.weight.SlayerWe
import io.github.moulberry.notenoughupdates.profileviewer.weight.weight.WeightStruct;
import io.github.moulberry.notenoughupdates.util.Constants;
import io.github.moulberry.notenoughupdates.util.Utils;
+
import java.util.Map;
public class LilySlayerWeight extends SlayerWeight {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/lily/LilyWeight.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/lily/LilyWeight.java
index 4ffc9fdd..03c5cfbf 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/lily/LilyWeight.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/lily/LilyWeight.java
@@ -22,6 +22,7 @@ package io.github.moulberry.notenoughupdates.profileviewer.weight.lily;
import com.google.gson.JsonObject;
import io.github.moulberry.notenoughupdates.profileviewer.ProfileViewer;
import io.github.moulberry.notenoughupdates.profileviewer.weight.weight.Weight;
+
import java.util.Map;
public class LilyWeight extends Weight {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/senither/SenitherDungeonsWeight.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/senither/SenitherDungeonsWeight.java
index 3b5adae5..e41b0ff4 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/senither/SenitherDungeonsWeight.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/senither/SenitherDungeonsWeight.java
@@ -24,6 +24,7 @@ import io.github.moulberry.notenoughupdates.profileviewer.weight.weight.Dungeons
import io.github.moulberry.notenoughupdates.profileviewer.weight.weight.WeightStruct;
import io.github.moulberry.notenoughupdates.util.Constants;
import io.github.moulberry.notenoughupdates.util.Utils;
+
import java.util.Map;
public class SenitherDungeonsWeight extends DungeonsWeight {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/senither/SenitherSkillsWeight.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/senither/SenitherSkillsWeight.java
index 2a4ee48c..7ac717f7 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/senither/SenitherSkillsWeight.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/senither/SenitherSkillsWeight.java
@@ -25,6 +25,7 @@ import io.github.moulberry.notenoughupdates.profileviewer.weight.weight.SkillsWe
import io.github.moulberry.notenoughupdates.profileviewer.weight.weight.WeightStruct;
import io.github.moulberry.notenoughupdates.util.Constants;
import io.github.moulberry.notenoughupdates.util.Utils;
+
import java.util.Map;
public class SenitherSkillsWeight extends SkillsWeight {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/senither/SenitherSlayerWeight.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/senither/SenitherSlayerWeight.java
index 80853853..e9fd5b41 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/senither/SenitherSlayerWeight.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/senither/SenitherSlayerWeight.java
@@ -25,6 +25,7 @@ import io.github.moulberry.notenoughupdates.profileviewer.weight.weight.SlayerWe
import io.github.moulberry.notenoughupdates.profileviewer.weight.weight.WeightStruct;
import io.github.moulberry.notenoughupdates.util.Constants;
import io.github.moulberry.notenoughupdates.util.Utils;
+
import java.util.Map;
public class SenitherSlayerWeight extends SlayerWeight {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/senither/SenitherWeight.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/senither/SenitherWeight.java
index 2f813576..532db942 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/senither/SenitherWeight.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/senither/SenitherWeight.java
@@ -21,6 +21,7 @@ package io.github.moulberry.notenoughupdates.profileviewer.weight.senither;
import io.github.moulberry.notenoughupdates.profileviewer.ProfileViewer;
import io.github.moulberry.notenoughupdates.profileviewer.weight.weight.Weight;
+
import java.util.Map;
public class SenitherWeight extends Weight {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/weight/DungeonsWeight.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/weight/DungeonsWeight.java
index 9c233554..c915d3be 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/weight/DungeonsWeight.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/weight/DungeonsWeight.java
@@ -20,6 +20,7 @@
package io.github.moulberry.notenoughupdates.profileviewer.weight.weight;
import io.github.moulberry.notenoughupdates.profileviewer.ProfileViewer;
+
import java.util.Map;
public abstract class DungeonsWeight {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/weight/SkillsWeight.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/weight/SkillsWeight.java
index 5c372591..84d3f551 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/weight/SkillsWeight.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/weight/SkillsWeight.java
@@ -20,6 +20,7 @@
package io.github.moulberry.notenoughupdates.profileviewer.weight.weight;
import io.github.moulberry.notenoughupdates.profileviewer.ProfileViewer;
+
import java.util.Map;
public abstract class SkillsWeight {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/weight/SlayerWeight.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/weight/SlayerWeight.java
index 20b2762d..bab8a154 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/weight/SlayerWeight.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/weight/SlayerWeight.java
@@ -20,6 +20,7 @@
package io.github.moulberry.notenoughupdates.profileviewer.weight.weight;
import io.github.moulberry.notenoughupdates.profileviewer.ProfileViewer;
+
import java.util.Map;
public abstract class SlayerWeight {
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/ApiUtil.java b/src/main/java/io/github/moulberry/notenoughupdates/util/ApiUtil.java
index 7818c3c0..e84c1c43 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/util/ApiUtil.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/util/ApiUtil.java
@@ -22,6 +22,8 @@ package io.github.moulberry.notenoughupdates.util;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.events.ProfileDataLoadedEvent;
+import net.minecraft.client.Minecraft;
import org.apache.commons.io.IOUtils;
import org.apache.http.NameValuePair;
import org.apache.http.client.utils.URIBuilder;
@@ -48,7 +50,9 @@ import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -59,6 +63,7 @@ public class ApiUtil {
private static final ExecutorService executorService = Executors.newFixedThreadPool(3);
private static final String USER_AGENT = "NotEnoughUpdates/" + NotEnoughUpdates.VERSION;
private static SSLContext ctx;
+ private final Map<String, CompletableFuture<Void>> updateTasks = new HashMap<>();
static {
try {
@@ -77,6 +82,23 @@ public class ApiUtil {
}
}
+ public void updateProfileData() {
+ updateProfileData(Minecraft.getMinecraft().thePlayer.getUniqueID().toString().replace("-", ""));
+ }
+
+ public void updateProfileData(String playerUuid) {
+ if (!updateTasks.getOrDefault(playerUuid, CompletableFuture.completedFuture(null)).isDone()) return;
+
+ updateTasks.put(playerUuid, newHypixelApiRequest("skyblock/profiles")
+ .queryArgument("uuid", Minecraft.getMinecraft().thePlayer.getUniqueID().toString().replace("-", ""))
+ .requestJson()
+ .handle((jsonObject, throwable) -> {
+ new ProfileDataLoadedEvent(jsonObject).post();
+ return null;
+ }));
+
+ }
+
public static class Request {
private final List<NameValuePair> queryArguments = new ArrayList<>();
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/HotmInformation.java b/src/main/java/io/github/moulberry/notenoughupdates/util/HotmInformation.java
index 1968b51e..57c4ae3b 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/util/HotmInformation.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/util/HotmInformation.java
@@ -23,6 +23,7 @@ import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.events.ProfileDataLoadedEvent;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.inventory.GuiChest;
import net.minecraft.inventory.ContainerChest;
@@ -135,7 +136,7 @@ public class HotmInformation {
public synchronized void onLobbyJoin(WorldEvent.Load event) {
if (shouldReloadSoon) {
shouldReloadSoon = false;
- requestUpdate(false);
+ neu.manager.apiUtils.updateProfileData();
}
}
@@ -154,17 +155,7 @@ public class HotmInformation {
@SubscribeEvent
public synchronized void onChat(ClientChatReceivedEvent event) {
if (event.message.getUnformattedText().equals("Welcome to Hypixel SkyBlock!"))
- requestUpdate(false);
- }
-
- public synchronized void requestUpdate(boolean force) {
- if (updateTask.isDone() || force) {
- updateTask = neu.manager.apiUtils
- .newHypixelApiRequest("skyblock/profiles")
- .queryArgument("uuid", Minecraft.getMinecraft().thePlayer.getUniqueID().toString().replace("-", ""))
- .requestJson()
- .thenAccept(this::updateInformation);
- }
+ neu.manager.apiUtils.updateProfileData();
}
/*
@@ -176,10 +167,13 @@ public class HotmInformation {
if (level > 20) return -1;
return QUICK_FORGE_MULTIPLIERS[level - 1];
}
+ @SubscribeEvent
+ public void onApiDataLoaded(ProfileDataLoadedEvent event) {
+ JsonObject data = event.getData();
+ if (data == null) return;
- public void updateInformation(JsonObject entireApiResponse) {
- if (!entireApiResponse.has("success") || !entireApiResponse.get("success").getAsBoolean()) return;
- JsonArray profiles = entireApiResponse.getAsJsonArray("profiles");
+ if (!data.has("success") || !data.get("success").getAsBoolean()) return;
+ JsonArray profiles = data.getAsJsonArray("profiles");
for (JsonElement element : profiles) {
JsonObject profile = element.getAsJsonObject();
String profileName = profile.get("cute_name").getAsString();
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/HypixelApi.java b/src/main/java/io/github/moulberry/notenoughupdates/util/HypixelApi.java
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/util/HypixelApi.java
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 095dde87..e28e52d6 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.OverlayManager;
import io.github.moulberry.notenoughupdates.overlays.SlayerOverlay;
import net.minecraft.client.Minecraft;
@@ -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;
@@ -158,8 +158,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;
}
@@ -312,6 +311,7 @@ public class SBInfo {
String name = Minecraft.getMinecraft().ingameGUI.getTabList().getPlayerName(info);
if (name.startsWith(profilePrefix)) {
String newProfile = Utils.cleanColour(name.substring(profilePrefix.length()));
+ setCurrentProfile(newProfile);
if (!Objects.equals(currentProfile, newProfile)) {
currentProfile = newProfile;
if (NotEnoughUpdates.INSTANCE.config != null)
@@ -454,4 +454,11 @@ public class SBInfo {
public JsonObject getMayorJson() {
return mayorJson;
}
+
+ 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/TabListUtils.java b/src/main/java/io/github/moulberry/notenoughupdates/util/TabListUtils.java
new file mode 100644
index 00000000..a0266122
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/util/TabListUtils.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2022 NotEnoughUpdates contributors
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.util;
+
+import com.google.common.collect.ComparisonChain;
+import com.google.common.collect.Ordering;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.network.NetworkPlayerInfo;
+import net.minecraft.scoreboard.ScorePlayerTeam;
+import net.minecraft.world.WorldSettings;
+import net.minecraftforge.fml.relauncher.Side;
+import net.minecraftforge.fml.relauncher.SideOnly;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+
+public class TabListUtils {
+
+ private static final Ordering<NetworkPlayerInfo> playerOrdering = Ordering.from(new PlayerComparator());
+
+ @SideOnly(Side.CLIENT)
+ static class PlayerComparator implements Comparator<NetworkPlayerInfo> {
+ private PlayerComparator() {}
+
+ public int compare(NetworkPlayerInfo o1, NetworkPlayerInfo o2) {
+ ScorePlayerTeam team1 = o1.getPlayerTeam();
+ ScorePlayerTeam team2 = o2.getPlayerTeam();
+ return ComparisonChain.start().compareTrueFirst(
+ o1.getGameType() != WorldSettings.GameType.SPECTATOR,
+ o2.getGameType() != WorldSettings.GameType.SPECTATOR
+ )
+ .compare(
+ team1 != null ? team1.getRegisteredName() : "",
+ team2 != null ? team2.getRegisteredName() : ""
+ )
+ .compare(o1.getGameProfile().getName(), o2.getGameProfile().getName()).result();
+ }
+ }
+
+ public static List<String> getTabList() {
+ List<NetworkPlayerInfo> players =
+ playerOrdering.sortedCopy(Minecraft.getMinecraft().thePlayer.sendQueue.getPlayerInfoMap());
+
+ List<String> result = new ArrayList<>();
+
+ for (NetworkPlayerInfo info : players) {
+ String name = Minecraft.getMinecraft().ingameGUI.getTabList().getPlayerName(info);
+ result.add(name);
+ }
+ return result;
+ }
+}
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 b02565cd..57f24370 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java
@@ -78,6 +78,7 @@ import java.math.BigInteger;
import java.nio.FloatBuffer;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
+import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -143,6 +144,7 @@ public class Utils {
public static Splitter PATH_SPLITTER = Splitter.on(".").omitEmptyStrings().limit(2);
private static ScaledResolution lastScale = new ScaledResolution(Minecraft.getMinecraft());
private static long startTime = 0;
+ private static DecimalFormat simpleDoubleFormat = new DecimalFormat("0.0");
public static <T> ArrayList<T> createList(T... values) {
ArrayList<T> list = new ArrayList<>();
@@ -325,6 +327,11 @@ public class Utils {
}
public static String shortNumberFormat(double n, int iteration) {
+ if (n < 3 && n > 0) {
+ return simpleDoubleFormat.format(n);
+ }
+
+ if (n < 1000 && iteration == 0) return "" + (int) n;
double d = ((long) n / 100) / 10.0;
boolean isRound = (d * 10) % 10 == 0;
return (d < 1000 ?
@@ -1941,13 +1948,13 @@ public class Utils {
if (NotEnoughUpdates.INSTANCE.config.notifications.outdatedRepo) {
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"
),
@@ -2011,4 +2018,13 @@ public class Utils {
}
return username;
}
+
+ public static void addChatMessage(String message) {
+ EntityPlayerSP thePlayer = Minecraft.getMinecraft().thePlayer;
+ if (thePlayer != null) {
+ thePlayer.addChatMessage(new ChatComponentText(message));
+ } else {
+ System.out.println(message);
+ }
+ }
}
diff --git a/src/main/resources/assets/notenoughupdates/minion_overlay.png b/src/main/resources/assets/notenoughupdates/minion_overlay.png
new file mode 100644
index 00000000..a9bd91ab
--- /dev/null
+++ b/src/main/resources/assets/notenoughupdates/minion_overlay.png
Binary files differ