diff options
31 files changed, 3043 insertions, 1 deletions
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java index 09c910e9..301aec26 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java @@ -67,6 +67,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; @@ -307,6 +308,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); if (Minecraft.getMinecraft().getResourceManager() instanceof IReloadableResourceManager) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DevTestCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DevTestCommand.java index bad9afe8..6036e796 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 @@ -29,6 +29,7 @@ import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.Custom import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.LocationChangeEvent; import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.SpecialBlockZone; import io.github.moulberry.notenoughupdates.miscgui.GuiPriceGraph; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.MinionHelperManager; import io.github.moulberry.notenoughupdates.util.PronounDB; import io.github.moulberry.notenoughupdates.util.SBInfo; import io.github.moulberry.notenoughupdates.util.TabListUtils; @@ -197,6 +198,9 @@ 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()) { 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 3ddb05f6..e465f3d3 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; @@ -536,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) { @@ -664,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) { @@ -1141,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) { 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..38f1c9e1 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/render/MinionHelperOverlay.java @@ -0,0 +1,400 @@ +/* + * 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.NotificationHandler; +import io.github.moulberry.notenoughupdates.util.Utils; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.gui.Gui; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.gui.ScaledResolution; +import net.minecraft.client.gui.inventory.GuiChest; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.client.event.GuiOpenEvent; +import net.minecraftforge.client.event.GuiScreenEvent; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import org.lwjgl.input.Mouse; +import org.lwjgl.opengl.GL11; + +import java.util.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 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); + } + } + checkToggleClick(); + } + + private void checkToggleClick() { + 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(); + + int x = guiLeft + xSize + 4 + 149 - 3; + int y = guiTop + 109 - 3; + + 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; + + if (mouseX > x && mouseX < x + 16 && + mouseY > y && mouseY < y + 16) { + toggleShowAvailable(); + } + } + + @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); + + 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(); + } + + 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; + } + + public void setMaxPerPage(int maxPerPage) { + this.maxPerPage = maxPerPage; + } + + public void setTopLeft(int[] topLeft) { + this.topLeft = topLeft; + } + + public boolean isFilterEnabled() { + return filterEnabled; + } +} 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..ce0757a6 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/render/MinionHelperOverlayHover.java @@ -0,0 +1,240 @@ +/* + * 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 + ); + } + + renderToggleButton(); + } + + private void renderToggleButton() { + 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(); + + int x = guiLeft + xSize + 4 + 149 - 3; + int y = guiTop + 109 - 3; + + 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; + + 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!"); + + if (mouseX > x && mouseX < x + 16 && + mouseY > y && mouseY < y + 16) { + + 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..495aeaac --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/util/MinionHelperPriceCalculation.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.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) { + 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) { + if (!bazaarInfo.has("curr_sell")) { + System.err.println("curr_sell does not exist for '" + internalName + "'"); + return 0; + } + return bazaarInfo.get("curr_sell").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/options/NEUConfig.java b/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java index 4d04bfbc..808de00b 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; @@ -400,6 +401,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/util/SBInfo.java b/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java index 58adb307..4b31d022 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java @@ -24,6 +24,7 @@ import com.google.gson.JsonObject; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.listener.ScoreboardLocationChangeListener; import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.LocationChangeEvent; +import io.github.moulberry.notenoughupdates.miscgui.minionhelper.MinionHelperManager; import io.github.moulberry.notenoughupdates.overlays.SlayerOverlay; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.inventory.GuiChest; @@ -440,7 +441,8 @@ public class SBInfo { public void setCurrentProfile(String newProfile) { if (!newProfile.equals(currentProfile)) { - currentProfile = newProfile; // TODO @hannibal2: maybe event + currentProfile = newProfile; + MinionHelperManager.getInstance().onProfileSwitch(); } } } |