aboutsummaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/item/PriceInfoTooltip.java43
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java650
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/skyblock/item/exotic/CheckExotic.java105
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/utils/Constants.java34
-rw-r--r--src/main/resources/assets/skyblocker/lang/en_us.json8
5 files changed, 840 insertions, 0 deletions
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/PriceInfoTooltip.java b/src/main/java/de/hysky/skyblocker/skyblock/item/PriceInfoTooltip.java
index 0885ae6b..667382ee 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/item/PriceInfoTooltip.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/item/PriceInfoTooltip.java
@@ -4,6 +4,7 @@ import com.google.gson.Gson;
import com.google.gson.JsonObject;
import de.hysky.skyblocker.config.SkyblockerConfig;
import de.hysky.skyblocker.config.SkyblockerConfigManager;
+import de.hysky.skyblocker.skyblock.item.exotic.CheckExotic;
import de.hysky.skyblocker.utils.Constants;
import de.hysky.skyblocker.utils.Http;
import de.hysky.skyblocker.utils.ItemUtils;
@@ -13,6 +14,7 @@ import net.minecraft.client.MinecraftClient;
import net.minecraft.client.item.TooltipContext;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound;
+import net.minecraft.nbt.NbtElement;
import net.minecraft.text.MutableText;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
@@ -35,6 +37,7 @@ public class PriceInfoTooltip {
private static JsonObject lowestPricesJson;
private static JsonObject isMuseumJson;
private static JsonObject motesPricesJson;
+ public static JsonObject ColorApiData;
private static volatile boolean nullMsgSend = false;
private final static Gson gson = new Gson();
private static final Map<String, String> apiAddresses;
@@ -55,6 +58,45 @@ public class PriceInfoTooltip {
neuName = internalID;
}
+ if (lines.size() == 0) {
+ return;
+ }
+
+ if (SkyblockerConfig.get().general.itemTooltip.enableExoticCheck) {
+
+ if (ColorApiData == null) { // Only download once, don't need to waste resources on downloading every few seconds
+ ColorApiData = downloadPrices("color");
+ }
+
+ final NbtElement Color = stack.getNbt().getCompound("display").get("color");
+
+ if (Color != null) {
+ String colorHex = String.format("%06X", Integer.parseInt(Color.asString()));
+ String expectedHex = CheckExotic.getExpectedHex(internalID);
+
+ boolean correctLine = false;
+ for (int i = 0; i < lines.size(); i++) {
+ String existingTooltip = String.valueOf(lines.get(i));
+ if (existingTooltip.startsWith("Color: ")) {
+ correctLine = true;
+
+ if (!colorHex.equalsIgnoreCase(expectedHex) && !CheckExotic.checkExceptions(internalID, colorHex) && !CheckExotic.intendedDyed(stack.getNbt())) {
+ final String type = CheckExotic.checkDyeType(colorHex);
+ lines.add(1, Text.literal(existingTooltip + Formatting.DARK_GRAY + " (" + CheckExotic.FormattingColor(type) + CheckExotic.getTranslatatedText(type).getString() + Formatting.DARK_GRAY + ")"));
+ }
+ break;
+ }
+ }
+
+ if (!correctLine) {
+ if (!colorHex.equalsIgnoreCase(expectedHex) && !CheckExotic.checkExceptions(internalID, colorHex) && !CheckExotic.intendedDyed(stack.getNbt())) {
+ final String type = CheckExotic.checkDyeType(colorHex);
+ lines.add(1, Text.literal(Formatting.DARK_GRAY + "(" + CheckExotic.FormattingColor(type) + CheckExotic.getTranslatatedText(type).getString() + Formatting.DARK_GRAY + ")"));
+ }
+ }
+ }
+ }
+
int count = stack.getCount();
boolean bazaarOpened = lines.stream().anyMatch(each -> each.getString().contains("Buy price:") || each.getString().contains("Sell price:"));
@@ -421,5 +463,6 @@ public class PriceInfoTooltip {
apiAddresses.put("npc", "https://hysky.de/api/npcprice");
apiAddresses.put("museum", "https://hysky.de/api/museum");
apiAddresses.put("motes", "https://hysky.de/api/motesprice");
+ apiAddresses.put("color", "https://hysky.de/api/color");
}
} \ No newline at end of file
diff --git a/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java b/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java
new file mode 100644
index 00000000..7fc042e5
--- /dev/null
+++ b/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java
@@ -0,0 +1,650 @@
+package me.xmrvizzy.skyblocker.config;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.mojang.brigadier.builder.LiteralArgumentBuilder;
+import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
+import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
+import me.shedaniel.autoconfig.AutoConfig;
+import me.shedaniel.autoconfig.ConfigData;
+import me.shedaniel.autoconfig.annotation.Config;
+import me.shedaniel.autoconfig.annotation.ConfigEntry;
+import me.shedaniel.autoconfig.serializer.ConfigSerializer;
+import me.shedaniel.autoconfig.serializer.GsonConfigSerializer;
+import me.xmrvizzy.skyblocker.SkyblockerMod;
+import me.xmrvizzy.skyblocker.skyblock.item.CustomArmorTrims;
+import me.xmrvizzy.skyblocker.utils.chat.ChatFilterResult;
+import me.xmrvizzy.skyblocker.utils.scheduler.Scheduler;
+import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback;
+import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
+import net.minecraft.client.resource.language.I18n;
+import net.minecraft.text.Style;
+import net.minecraft.text.Text;
+import net.minecraft.util.Identifier;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal;
+
+@Config(name = "skyblocker")
+public class SkyblockerConfig implements ConfigData {
+
+ @ConfigEntry.Category("general")
+ @ConfigEntry.Gui.TransitiveObject
+ public General general = new General();
+
+ @ConfigEntry.Category("locations")
+ @ConfigEntry.Gui.TransitiveObject
+ public Locations locations = new Locations();
+
+ @ConfigEntry.Category("slayer")
+ @ConfigEntry.Gui.TransitiveObject
+ public Slayer slayer = new Slayer();
+
+ @ConfigEntry.Category("quickNav")
+ @ConfigEntry.Gui.TransitiveObject
+ public QuickNav quickNav = new QuickNav();
+
+ @ConfigEntry.Category("messages")
+ @ConfigEntry.Gui.TransitiveObject
+ public Messages messages = new Messages();
+
+ @ConfigEntry.Category("richPresence")
+ @ConfigEntry.Gui.TransitiveObject
+ public RichPresence richPresence = new RichPresence();
+
+ public static class QuickNav {
+ public boolean enableQuickNav = true;
+
+ @ConfigEntry.Category("button1")
+ @ConfigEntry.Gui.CollapsibleObject()
+ public QuickNavItem button1 = new QuickNavItem(true, new ItemData("diamond_sword"), "Your Skills", "/skills");
+
+ @ConfigEntry.Category("button2")
+ @ConfigEntry.Gui.CollapsibleObject()
+ public QuickNavItem button2 = new QuickNavItem(true, new ItemData("painting"), "Collections", "/collection");
+
+ @ConfigEntry.Category("button3")
+ @ConfigEntry.Gui.CollapsibleObject()
+ public QuickNavItem button3 = new QuickNavItem(true, new ItemData("bone"), "\\Pets \\(\\d+/\\d+\\)", "/pets");
+
+ @ConfigEntry.Category("button4")
+ @ConfigEntry.Gui.CollapsibleObject()
+ public QuickNavItem button4 = new QuickNavItem(true, new ItemData("leather_chestplate", 1, "tag:{display:{color:8991416}}"), "Wardrobe \\([12]/2\\)", "/wardrobe");
+
+ @ConfigEntry.Category("button5")
+ @ConfigEntry.Gui.CollapsibleObject()
+ public QuickNavItem button5 = new QuickNavItem(true, new ItemData("player_head", 1, "tag:{SkullOwner:{Id:[I;-2081424676,-57521078,-2073572414,158072763],Properties:{textures:[{Value:\"ewogICJ0aW1lc3RhbXAiIDogMTU5MTMxMDU4NTYwOSwKICAicHJvZmlsZUlkIiA6ICI0MWQzYWJjMmQ3NDk0MDBjOTA5MGQ1NDM0ZDAzODMxYiIsCiAgInByb2ZpbGVOYW1lIiA6ICJNZWdha2xvb24iLAogICJzaWduYXR1cmVSZXF1aXJlZCIgOiB0cnVlLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvODBhMDc3ZTI0OGQxNDI3NzJlYTgwMDg2NGY4YzU3OGI5ZDM2ODg1YjI5ZGFmODM2YjY0YTcwNjg4MmI2ZWMxMCIKICAgIH0KICB9Cn0=\"}]}}}"), "Sack of Sacks", "/sacks");
+
+ @ConfigEntry.Category("button6")
+ @ConfigEntry.Gui.CollapsibleObject()
+ public QuickNavItem button6 = new QuickNavItem(true, new ItemData("ender_chest"), "(?:Rift )?Storage(?: \\(1/2\\))?", "/storage");
+
+ @ConfigEntry.Category("button7")
+ @ConfigEntry.Gui.CollapsibleObject()
+ public QuickNavItem button7 = new QuickNavItem(true, new ItemData("player_head", 1, "tag:{SkullOwner:{Id:[I;-300151517,-631415889,-1193921967,-1821784279],Properties:{textures:[{Value:\"e3RleHR1cmVzOntTS0lOOnt1cmw6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZDdjYzY2ODc0MjNkMDU3MGQ1NTZhYzUzZTA2NzZjYjU2M2JiZGQ5NzE3Y2Q4MjY5YmRlYmVkNmY2ZDRlN2JmOCJ9fX0=\"}]}}}"), "none", "/hub");
+
+ @ConfigEntry.Category("button8")
+ @ConfigEntry.Gui.CollapsibleObject()
+ public QuickNavItem button8 = new QuickNavItem(true, new ItemData("player_head", 1, "tag:{SkullOwner:{Id:[I;1605800870,415127827,-1236127084,15358548],Properties:{textures:[{Value:\"e3RleHR1cmVzOntTS0lOOnt1cmw6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNzg5MWQ1YjI3M2ZmMGJjNTBjOTYwYjJjZDg2ZWVmMWM0MGExYjk0MDMyYWU3MWU3NTQ3NWE1NjhhODI1NzQyMSJ9fX0=\"}]}}}"), "none", "/warp dungeon_hub");
+
+ @ConfigEntry.Category("button9")
+ @ConfigEntry.Gui.CollapsibleObject()
+ public QuickNavItem button9 = new QuickNavItem(true, new ItemData("player_head", 1, "tag:{SkullOwner:{Id:[I;-562285948,532499670,-1705302742,775653035],Properties:{textures:[{Value:\"eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYjVkZjU1NTkyNjQzMGQ1ZDc1YWRlZDIxZGQ5NjE5Yjc2YzViN2NhMmM3ZjU0MDE0NDA1MjNkNTNhOGJjZmFhYiJ9fX0=\"}]}}}"), "Visit prtl", "/visit prtl");
+
+ @ConfigEntry.Category("button10")
+ @ConfigEntry.Gui.CollapsibleObject()
+ public QuickNavItem button10 = new QuickNavItem(true, new ItemData("enchanting_table"), "Enchant Item", "/etable");
+
+ @ConfigEntry.Category("button11")
+ @ConfigEntry.Gui.CollapsibleObject()
+ public QuickNavItem button11 = new QuickNavItem(true, new ItemData("anvil"), "Anvil", "/anvil");
+
+ @ConfigEntry.Category("button12")
+ @ConfigEntry.Gui.CollapsibleObject()
+ public QuickNavItem button12 = new QuickNavItem(true, new ItemData("crafting_table"), "Craft Item", "/craft");
+ }
+
+ public static class QuickNavItem {
+ public QuickNavItem(Boolean render, ItemData itemData, String uiTitle, String clickEvent) {
+ this.render = render;
+ this.item = itemData;
+ this.clickEvent = clickEvent;
+ this.uiTitle = uiTitle;
+ }
+
+ public Boolean render;
+
+ @ConfigEntry.Category("item")
+ @ConfigEntry.Gui.CollapsibleObject()
+ public ItemData item;
+
+ public String uiTitle;
+ public String clickEvent;
+ }
+
+ public static class ItemData {
+ public ItemData(String itemName, int count, String nbt) {
+ this.itemName = itemName;
+ this.count = count;
+ this.nbt = nbt;
+ }
+
+ public ItemData(String itemName) {
+ this.itemName = itemName;
+ this.count = 1;
+ this.nbt = "";
+ }
+
+ public String itemName;
+ public int count;
+ public String nbt;
+ }
+
+ public static class General {
+ public boolean acceptReparty = true;
+ public boolean backpackPreviewWithoutShift = false;
+ public boolean hideEmptyTooltips = true;
+ public boolean hideStatusEffectOverlay = false;
+
+ @ConfigEntry.Category("tabHud")
+ @ConfigEntry.Gui.CollapsibleObject()
+ public TabHudConf tabHud = new TabHudConf();
+
+ @ConfigEntry.Gui.Excluded
+ public String apiKey;
+
+ @ConfigEntry.Category("bars")
+ @ConfigEntry.Gui.CollapsibleObject()
+ public Bars bars = new Bars();
+
+ @ConfigEntry.Category("experiments")
+ @ConfigEntry.Gui.CollapsibleObject()
+ public Experiments experiments = new Experiments();
+
+ @ConfigEntry.Category("fishing")
+ @ConfigEntry.Gui.CollapsibleObject()
+ public Fishing fishing = new Fishing();
+
+ @ConfigEntry.Category("fairySouls")
+ @ConfigEntry.Gui.CollapsibleObject()
+ public FairySouls fairySouls = new FairySouls();
+
+ @ConfigEntry.Category("shortcuts")
+ @ConfigEntry.Gui.CollapsibleObject()
+ public Shortcuts shortcuts = new Shortcuts();
+
+ @ConfigEntry.Category("quiverWarning")
+ @ConfigEntry.Gui.CollapsibleObject()
+ public QuiverWarning quiverWarning = new QuiverWarning();
+
+ @ConfigEntry.Category("itemList")
+ @ConfigEntry.Gui.CollapsibleObject()
+ public ItemList itemList = new ItemList();
+
+ @ConfigEntry.Category("itemTooltip")
+ @ConfigEntry.Gui.CollapsibleObject()
+ public ItemTooltip itemTooltip = new ItemTooltip();
+
+ @ConfigEntry.Category("itemInfoDisplay")
+ @ConfigEntry.Gui.CollapsibleObject
+ public ItemInfoDisplay itemInfoDisplay = new ItemInfoDisplay();
+
+ @ConfigEntry.Category("specialEffects")
+ @ConfigEntry.Gui.CollapsibleObject
+ public SpecialEffects specialEffects = new SpecialEffects();
+
+ @ConfigEntry.Category("hitbox")
+ @ConfigEntry.Gui.CollapsibleObject()
+ public Hitbox hitbox = new Hitbox();
+
+ @ConfigEntry.Gui.Tooltip()
+ @ConfigEntry.Category("titleContainer")
+ @ConfigEntry.Gui.CollapsibleObject()
+ public TitleContainer titleContainer = new TitleContainer();
+
+ @ConfigEntry.Category("Teleport Overlay")
+ @ConfigEntry.Gui.CollapsibleObject()
+ public TeleportOverlay teleportOverlay = new TeleportOverlay();
+
+ @ConfigEntry.Gui.Excluded
+ public List<Integer> lockedSlots = new ArrayList<>();
+
+ @ConfigEntry.Gui.Excluded
+ public Object2ObjectOpenHashMap<String, Text> customItemNames = new Object2ObjectOpenHashMap<>();
+
+ @ConfigEntry.Gui.Excluded
+ public Object2IntOpenHashMap<String> customDyeColors = new Object2IntOpenHashMap<>();
+
+ @ConfigEntry.Gui.Excluded
+ public Object2ObjectOpenHashMap<String, CustomArmorTrims.ArmorTrimId> customArmorTrims = new Object2ObjectOpenHashMap<>();
+ }
+
+ public static class TabHudConf {
+ public boolean tabHudEnabled = true;
+
+ @ConfigEntry.BoundedDiscrete(min = 10, max = 200)
+ @ConfigEntry.Gui.Tooltip()
+ public int tabHudScale = 100;
+ @ConfigEntry.Gui.Tooltip
+ public boolean plainPlayerNames = false;
+ @ConfigEntry.Gui.EnumHandler(option = ConfigEntry.Gui.EnumHandler.EnumDisplayOption.BUTTON)
+ @ConfigEntry.Gui.Tooltip
+ public NameSorting nameSorting = NameSorting.DEFAULT;
+ }
+
+ public enum NameSorting {
+ DEFAULT,
+ ALPHABETICAL;
+
+ @Override
+ public String toString() {
+ return switch (this) {
+ case DEFAULT -> "Default";
+ case ALPHABETICAL -> "Alphabetical";
+ };
+ }
+ }
+
+ public static class Bars {
+ public boolean enableBars = true;
+
+ @ConfigEntry.Category("barpositions")
+ @ConfigEntry.Gui.CollapsibleObject()
+ public BarPositions barpositions = new BarPositions();
+ }
+
+ public static class BarPositions {
+ @ConfigEntry.Gui.EnumHandler(option = ConfigEntry.Gui.EnumHandler.EnumDisplayOption.BUTTON)
+ public BarPosition healthBarPosition = BarPosition.LAYER1;
+ @ConfigEntry.Gui.EnumHandler(option = ConfigEntry.Gui.EnumHandler.EnumDisplayOption.BUTTON)
+ public BarPosition manaBarPosition = BarPosition.LAYER1;
+ @ConfigEntry.Gui.EnumHandler(option = ConfigEntry.Gui.EnumHandler.EnumDisplayOption.BUTTON)
+ public BarPosition defenceBarPosition = BarPosition.LAYER1;
+ @ConfigEntry.Gui.EnumHandler(option = ConfigEntry.Gui.EnumHandler.EnumDisplayOption.BUTTON)
+ public BarPosition experienceBarPosition = BarPosition.LAYER1;
+
+ }
+
+ public enum BarPosition {
+ LAYER1,
+ LAYER2,
+ RIGHT,
+ NONE;
+
+ @Override
+ public String toString() {
+ return I18n.translate("text.autoconfig.skyblocker.option.general.bars.barpositions." + name());
+ }
+
+ public int toInt() {
+ return switch (this) {
+ case LAYER1 -> 0;
+ case LAYER2 -> 1;
+ case RIGHT -> 2;
+ case NONE -> -1;
+ };
+ }
+ }
+
+ public static class Experiments {
+ public boolean enableChronomatronSolver = true;
+ public boolean enableSuperpairsSolver = true;
+ public boolean enableUltrasequencerSolver = true;
+ }
+
+ public static class Fishing {
+ public boolean enableFishingHelper = true;
+ }
+
+ public static class FairySouls {
+ public boolean enableFairySoulsHelper = false;
+ }
+
+ public static class Shortcuts {
+ @ConfigEntry.Gui.Tooltip()
+ public boolean enableShortcuts = true;
+ @ConfigEntry.Gui.Tooltip()
+ public boolean enableCommandShortcuts = true;
+ @ConfigEntry.Gui.Tooltip()
+ public boolean enableCommandArgShortcuts = true;
+ }
+
+ public static class QuiverWarning {
+ public boolean enableQuiverWarning = true;
+ public boolean enableQuiverWarningInDungeons = true;
+ public boolean enableQuiverWarningAfterDungeon = true;
+ }
+
+ public static class Hitbox {
+ public boolean oldFarmlandHitbox = true;
+ public boolean oldLeverHitbox = false;
+ }
+
+ public static class TitleContainer {
+ @ConfigEntry.BoundedDiscrete(min = 30, max = 140)
+ public float titleContainerScale = 100;
+ public int x = 540;
+ public int y = 10;
+ @ConfigEntry.Gui.EnumHandler(option = ConfigEntry.Gui.EnumHandler.EnumDisplayOption.BUTTON)
+ public Direction direction = Direction.HORIZONTAL;
+ @ConfigEntry.Gui.EnumHandler(option = ConfigEntry.Gui.EnumHandler.EnumDisplayOption.DROPDOWN)
+ public Alignment alignment = Alignment.MIDDLE;
+ }
+
+ public static class TeleportOverlay {
+ public boolean enableTeleportOverlays = true;
+ public boolean enableWeirdTransmission = true;
+ public boolean enableInstantTransmission = true;
+ public boolean enableEtherTransmission = true;
+ public boolean enableSinrecallTransmission = true;
+ public boolean enableWitherImpact = true;
+ }
+
+ public enum Direction {
+ HORIZONTAL,
+ VERTICAL;
+
+ @Override
+ public String toString() {
+ return switch (this) {
+ case HORIZONTAL -> "Horizontal";
+ case VERTICAL -> "Vertical";
+ };
+ }
+ }
+
+ public enum Alignment {
+ LEFT,
+ RIGHT,
+ MIDDLE;
+
+ @Override
+ public String toString() {
+ return switch (this) {
+ case LEFT -> "Left";
+ case RIGHT -> "Right";
+ case MIDDLE -> "Middle";
+ };
+ }
+ }
+
+ public static class RichPresence {
+ public boolean enableRichPresence = false;
+ @ConfigEntry.Gui.EnumHandler(option = ConfigEntry.Gui.EnumHandler.EnumDisplayOption.BUTTON)
+ @ConfigEntry.Gui.Tooltip()
+ public Info info = Info.LOCATION;
+ public boolean cycleMode = false;
+ public String customMessage = "Playing Skyblock";
+ }
+
+ public static class ItemList {
+ public boolean enableItemList = true;
+ }
+
+ public enum Average {
+ ONE_DAY,
+ THREE_DAY,
+ BOTH;
+
+ @Override
+ public String toString() {
+ return I18n.translate("text.autoconfig.skyblocker.option.general.itemTooltip.avg." + name());
+ }
+ }
+
+ public static class ItemTooltip {
+ public boolean enableExoticCheck = true;
+ public boolean enableNPCPrice = true;
+ @ConfigEntry.Gui.Tooltip
+ public boolean enableMotesPrice = true;
+ public boolean enableAvgBIN = true;
+ @ConfigEntry.Gui.EnumHandler(option = ConfigEntry.Gui.EnumHandler.EnumDisplayOption.BUTTON)
+ @ConfigEntry.Gui.Tooltip()
+ public Average avg = Average.THREE_DAY;
+ public boolean enableLowestBIN = true;
+ public boolean enableBazaarPrice = true;
+ public boolean enableMuseumDate = true;
+ }
+
+ public static class ItemInfoDisplay {
+ @ConfigEntry.Gui.Tooltip
+ public boolean attributeShardInfo = true;
+ }
+
+ public static class SpecialEffects {
+ @ConfigEntry.Gui.Tooltip
+ public boolean rareDungeonDropEffects = true;
+ }
+
+ public static class Locations {
+ @ConfigEntry.Category("barn")
+ @ConfigEntry.Gui.CollapsibleObject()
+ public Barn barn = new Barn();
+
+ @ConfigEntry.Category("dungeons")
+ @ConfigEntry.Gui.CollapsibleObject()
+ public Dungeons dungeons = new Dungeons();
+
+ @ConfigEntry.Category("dwarvenmines")
+ @ConfigEntry.Gui.CollapsibleObject()
+ public DwarvenMines dwarvenMines = new DwarvenMines();
+
+ @ConfigEntry.Category("rift")
+ @ConfigEntry.Gui.CollapsibleObject()
+ public Rift rift = new Rift();
+ }
+
+ public static class Dungeons {
+ @ConfigEntry.Gui.CollapsibleObject
+ public SecretWaypoints secretWaypoints = new SecretWaypoints();
+ @ConfigEntry.Gui.CollapsibleObject
+ public DungeonChestProfit dungeonChestProfit = new DungeonChestProfit();
+ @ConfigEntry.Gui.Tooltip()
+ public boolean croesusHelper = true;
+ public boolean enableMap = true;
+ public float mapScaling = 1f;
+ public int mapX = 2;
+ public int mapY = 2;
+ @ConfigEntry.Gui.Tooltip
+ public boolean starredMobGlow = true;
+ public boolean solveThreeWeirdos = true;
+ @ConfigEntry.Gui.Tooltip
+ public boolean blazesolver = true;
+ public boolean solveTrivia = true;
+ @ConfigEntry.Gui.Tooltip
+ public boolean solveTicTacToe = true;
+ @ConfigEntry.Gui.CollapsibleObject
+ public LividColor lividColor = new LividColor();
+ @ConfigEntry.Gui.CollapsibleObject()
+ public Terminals terminals = new Terminals();
+ }
+
+ public static class SecretWaypoints {
+
+ public boolean enableSecretWaypoints = true;
+ @ConfigEntry.Gui.Tooltip()
+ public boolean noInitSecretWaypoints = false;
+ public boolean enableEntranceWaypoints = true;
+ public boolean enableSuperboomWaypoints = true;
+ public boolean enableChestWaypoints = true;
+ public boolean enableItemWaypoints = true;
+ public boolean enableBatWaypoints = true;
+ public boolean enableWitherWaypoints = true;
+ public boolean enableLeverWaypoints = true;
+ public boolean enableFairySoulWaypoints = true;
+ public boolean enableStonkWaypoints = true;
+ @ConfigEntry.Gui.Tooltip()
+ public boolean enableDefaultWaypoints = true;
+ }
+
+ public static class DungeonChestProfit {
+ @ConfigEntry.Gui.Tooltip
+ public boolean enableProfitCalculator = true;
+ @ConfigEntry.Gui.Tooltip
+ public boolean includeKismet = false;
+ @ConfigEntry.Gui.Tooltip
+ public boolean includeEssence = true;
+ }
+
+ public static class LividColor {
+ @ConfigEntry.Gui.Tooltip()
+ public boolean enableLividColor = true;
+ @ConfigEntry.Gui.Tooltip()
+ public String lividColorText = "The livid color is [color]";
+ }
+
+ public static class Terminals {
+ public boolean solveColor = true;
+ public boolean solveOrder = true;
+ public boolean solveStartsWith = true;
+ }
+
+ public static class DwarvenMines {
+ public boolean enableDrillFuel = true;
+ public boolean solveFetchur = true;
+ public boolean solvePuzzler = true;
+ @ConfigEntry.Gui.CollapsibleObject()
+ public DwarvenHud dwarvenHud = new DwarvenHud();
+ }
+
+ public static class DwarvenHud {
+ public boolean enabled = true;
+ @ConfigEntry.Gui.EnumHandler(option = ConfigEntry.Gui.EnumHandler.EnumDisplayOption.BUTTON)
+ @ConfigEntry.Gui.Tooltip(count = 3)
+ public DwarvenHudStyle style = DwarvenHudStyle.SIMPLE;
+ public boolean enableBackground = true;
+ public int x = 10;
+ public int y = 10;
+ }
+
+ public enum DwarvenHudStyle {
+ SIMPLE,
+ FANCY,
+ CLASSIC;
+
+ @Override
+ public String toString() {
+ return switch (this) {
+ case SIMPLE -> "Simple";
+ case FANCY -> "Fancy";
+ case CLASSIC -> "Classic";
+ };
+ }
+ }
+
+ public static class Barn {
+ public boolean solveHungryHiker = true;
+ public boolean solveTreasureHunter = true;
+ }
+
+ public static class Rift {
+ public boolean mirrorverseWaypoints = true;
+ @ConfigEntry.BoundedDiscrete(min = 0, max = 5)
+ @ConfigEntry.Gui.Tooltip
+ public int mcGrubberStacks = 0;
+ }
+
+ public static class Slayer {
+ @ConfigEntry.Category("vampire")
+ @ConfigEntry.Gui.CollapsibleObject()
+ public VampireSlayer vampireSlayer = new VampireSlayer();
+ }
+
+ public static class VampireSlayer {
+ public boolean enableEffigyWaypoints = true;
+ public boolean compactEffigyWaypoints;
+ @ConfigEntry.BoundedDiscrete(min = 1, max = 10)
+ @ConfigEntry.Gui.Tooltip()
+ public int effigyUpdateFrequency = 5;
+ public boolean enableHolyIceIndicator = true;
+ public int holyIceIndicatorTickDelay = 10;
+ @ConfigEntry.BoundedDiscrete(min = 1, max = 10)
+ @ConfigEntry.Gui.Tooltip()
+ public int holyIceUpdateFrequency = 5;
+ public boolean enableHealingMelonIndicator = true;
+ public float healingMelonHealthThreshold = 4F;
+ public boolean enableSteakStakeIndicator = true;
+ @ConfigEntry.BoundedDiscrete(min = 1, max = 10)
+ @ConfigEntry.Gui.Tooltip()
+ public int steakStakeUpdateFrequency = 5;
+ public boolean enableManiaIndicator = true;
+ @ConfigEntry.BoundedDiscrete(min = 1, max = 10)
+ @ConfigEntry.Gui.Tooltip()
+ public int maniaUpdateFrequency = 5;
+ }
+
+ public static class Messages {
+ @ConfigEntry.Gui.EnumHandler(option = ConfigEntry.Gui.EnumHandler.EnumDisplayOption.BUTTON)
+ public ChatFilterResult hideAbility = ChatFilterResult.PASS;
+ @ConfigEntry.Gui.EnumHandler(option = ConfigEntry.Gui.EnumHandler.EnumDisplayOption.BUTTON)
+ public ChatFilterResult hideHeal = ChatFilterResult.PASS;
+ @ConfigEntry.Gui.EnumHandler(option = ConfigEntry.Gui.EnumHandler.EnumDisplayOption.BUTTON)
+ public ChatFilterResult hideAOTE = ChatFilterResult.PASS;
+ @ConfigEntry.Gui.EnumHandler(option = ConfigEntry.Gui.EnumHandler.EnumDisplayOption.BUTTON)
+ public ChatFilterResult hideImplosion = ChatFilterResult.PASS;
+ @ConfigEntry.Gui.EnumHandler(option = ConfigEntry.Gui.EnumHandler.EnumDisplayOption.BUTTON)
+ public ChatFilterResult hideMoltenWave = ChatFilterResult.PASS;
+ @ConfigEntry.Gui.EnumHandler(option = ConfigEntry.Gui.EnumHandler.EnumDisplayOption.BUTTON)
+ public ChatFilterResult hideAds = ChatFilterResult.PASS;
+ @ConfigEntry.Gui.EnumHandler(option = ConfigEntry.Gui.EnumHandler.EnumDisplayOption.BUTTON)
+ public ChatFilterResult hideTeleportPad = ChatFilterResult.PASS;
+ @ConfigEntry.Gui.EnumHandler(option = ConfigEntry.Gui.EnumHandler.EnumDisplayOption.BUTTON)
+ public ChatFilterResult hideCombo = ChatFilterResult.PASS;
+ @ConfigEntry.Gui.EnumHandler(option = ConfigEntry.Gui.EnumHandler.EnumDisplayOption.BUTTON)
+ public ChatFilterResult hideAutopet = ChatFilterResult.PASS;
+ @ConfigEntry.Gui.EnumHandler(option = ConfigEntry.Gui.EnumHandler.EnumDisplayOption.BUTTON)
+ @ConfigEntry.Gui.Tooltip
+ public ChatFilterResult hideShowOff = ChatFilterResult.PASS;
+ @ConfigEntry.Gui.Tooltip()
+ public boolean hideMana = false;
+ }
+
+ public enum Info {
+ PURSE,
+ BITS,
+ LOCATION;
+
+ @Override
+ public String toString() {
+ return I18n.translate("text.autoconfig.skyblocker.option.richPresence.info." + name());
+ }
+ }
+
+ /**
+ * Registers the config to AutoConfig and registers commands to open the config screen.
+ */
+ public static void init() {
+ Gson gson = new GsonBuilder()
+ .setPrettyPrinting()
+ .registerTypeHierarchyAdapter(Text.class, new Text.Serializer())
+ .registerTypeHierarchyAdapter(Style.class, new Style.Serializer())
+ .registerTypeHierarchyAdapter(Identifier.class, new Identifier.Serializer())
+ .create();
+
+ ConfigSerializer.Factory<SkyblockerConfig> serializer = (cfg, cfgClass) -> new GsonConfigSerializer<>(cfg, cfgClass, gson);
+
+ AutoConfig.register(SkyblockerConfig.class, serializer);
+ ClientCommandRegistrationCallback.EVENT.register(((dispatcher, registryAccess) -> dispatcher.register(literal(SkyblockerMod.NAMESPACE).then(optionsLiteral("config")).then(optionsLiteral("options")))));
+ }
+
+ /**
+ * Registers an options command with the given name. Used for registering both options and config as valid commands.
+ *
+ * @param name the name of the command node
+ * @return the command builder
+ */
+ private static LiteralArgumentBuilder<FabricClientCommandSource> optionsLiteral(String name) {
+ // Don't immediately open the next screen as it will be closed by ChatScreen right after this command is executed
+ return literal(name).executes(Scheduler.queueOpenScreenCommand(AutoConfig.getConfigScreen(SkyblockerConfig.class, null)));
+ }
+
+ public static SkyblockerConfig get() {
+ return AutoConfig.getConfigHolder(SkyblockerConfig.class).getConfig();
+ }
+
+ public static void save() {
+ AutoConfig.getConfigHolder(SkyblockerConfig.class).save();
+ }
+}
diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/item/exotic/CheckExotic.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/item/exotic/CheckExotic.java
new file mode 100644
index 00000000..fb22362e
--- /dev/null
+++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/item/exotic/CheckExotic.java
@@ -0,0 +1,105 @@
+package me.xmrvizzy.skyblocker.skyblock.item.exotic;
+
+import me.xmrvizzy.skyblocker.skyblock.item.PriceInfoTooltip;
+import me.xmrvizzy.skyblocker.utils.Constants;
+import net.minecraft.nbt.NbtCompound;
+import net.minecraft.text.Text;
+import net.minecraft.util.Formatting;
+
+public class CheckExotic {
+ static String[] SeymourIDS = {"VELVET_TOP_HAT", "CASHMERE_JACKET", "SATIN_TROUSERS", "OXFORD_SHOES"};
+ public static String getExpectedHex(String id) {
+ String color = PriceInfoTooltip.ColorApiData.get(id).getAsString();
+ if (color != null) {
+ String[] RGBValues = color.split(",");
+ String hex = String.format("%02x%02x%02x", Integer.parseInt(RGBValues[0]), Integer.parseInt(RGBValues[1]), Integer.parseInt(RGBValues[2]));
+ return hex.toUpperCase();
+ } else {
+ System.out.println("Color is null");
+ return null;
+ }
+ }
+
+ public static Boolean checkExceptions(String id, String hex) {
+ if (id.startsWith("LEATHER") || id.equals("GHOST_BOOTS") || ListContainsString(SeymourIDS, id)) {
+ return true;
+ }
+ if (id.startsWith("RANCHER")) {
+ return ListContainsString(Constants.Ranchers, hex);
+ }
+ if (id.contains("ADAPTIVE_CHESTPLATE")) {
+ return ListContainsString(Constants.AdaptiveChest, hex);
+ } else if (id.contains("ADAPTIVE")) {
+ return ListContainsString(Constants.Adaptive, hex);
+ }
+ if (id.startsWith("REAPER")) {
+ return ListContainsString(Constants.Reaper, hex);
+ }
+ if (id.startsWith("FAIRY")) {
+ return ListContainsString(Constants.FairyHexes, hex);
+ }
+ if (id.startsWith("CRYSTAL")) {
+ return ListContainsString(Constants.CrystalHexes, hex);
+ }
+ if (id.contains("SPOOK")) {
+ return ListContainsString(Constants.Spook, hex);
+ }
+ return false;
+ }
+
+ public static String checkDyeType(String ActualHex) {
+ if (ListContainsString(Constants.CrystalHexes, ActualHex)) {
+ return "CRYSTAL";
+ }
+ if (ListContainsString(Constants.FairyHexes, ActualHex)) {
+ return "FAIRY";
+ }
+ if (ListContainsString(Constants.OgFairyHexes, ActualHex)) {
+ return "OG_FAIRY";
+ }
+ if (ListContainsString(Constants.Spook, ActualHex)) {
+ return "SPOOK";
+ }
+ if (ListContainsString(Constants.Glitched, ActualHex)) {
+ return "GLITCHED";
+ }
+ return "EXOTIC";
+ }
+
+ private static Boolean ListContainsString(String[] list, String s) {
+ for (int i = 0; i < list.length; i++) {
+ if (list[i].equalsIgnoreCase(s)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static Boolean intendedDyed(NbtCompound ItemData) {
+ return ItemData.getCompound("ExtraAttributes").getKeys().contains("dye_item");
+ }
+
+ public static Formatting FormattingColor(String s) {
+ switch (s) {
+ case "CRYSTAL": return Formatting.AQUA;
+ case "FAIRY": return Formatting.LIGHT_PURPLE;
+ case "OG_FAIRY": return Formatting.DARK_PURPLE;
+ case "SPOOK": return Formatting.RED;
+ case "GLITCHED": return Formatting.BLUE;
+ case "EXOTIC": return Formatting.GOLD;
+ }
+ return Formatting.DARK_GRAY;
+ }
+
+ public static Text getTranslatatedText(String s) {
+ switch (s) {
+ case "CRYSTAL": return Text.translatable("skyblocker.exotic.crystal");
+ case "FAIRY": return Text.translatable("skyblocker.exotic.fairy");
+ case "OG_FAIRY": return Text.translatable("skyblocker.exotic.og_fairy");
+ case "SPOOK": return Text.translatable("skyblocker.exotic.spook");
+ case "GLITCHED": return Text.translatable("skyblocker.exotic.glitched");
+ case "EXOTIC": return Text.translatable("skyblocker.exotic.exotic");
+ }
+ return null;
+ }
+}
diff --git a/src/main/java/me/xmrvizzy/skyblocker/utils/Constants.java b/src/main/java/me/xmrvizzy/skyblocker/utils/Constants.java
new file mode 100644
index 00000000..23d4a43f
--- /dev/null
+++ b/src/main/java/me/xmrvizzy/skyblocker/utils/Constants.java
@@ -0,0 +1,34 @@
+package me.xmrvizzy.skyblocker.utils;
+
+/**
+ * Holds generic static constants
+ */
+public interface Constants {
+ String LEVEL_EMBLEMS = "\u2E15\u273F\u2741\u2E19\u03B1\u270E\u2615\u2616\u2663\u213B\u2694\u27B6\u26A1\u2604\u269A\u2693\u2620\u269B\u2666\u2660\u2764\u2727\u238A\u1360\u262C\u269D\u29C9\uA214\u32D6\u2E0E\u26A0\uA541\u3020\u30C4\u2948\u2622\u2623\u273E\u269C\u0BD0\u0A6D\u2742\u16C3\u3023\u10F6\u0444\u266A\u266B\u04C3\u26C1\u26C3\u16DD\uA03E\u1C6A\u03A3\u09EB\u2603\u2654\u26C2\u12DE";
+
+ // Exotic Hexes
+ String[] CrystalHexes = {"1F0030", "46085E", "54146E", "5D1C78", "63237D", "6A2C82", "7E4196", "8E51A6", "9C64B3", "A875BD",
+ "B88BC9", "C6A3D4", "D9C1E3", "E5D1ED", "EFE1F5", "FCF3FF"};
+ String[] FairyHexes = {"330066", "4C0099", "660033", "660066", "6600CC", "7F00FF", "99004C", "990099", "9933FF", "B266FF",
+ "CC0066", "CC00CC", "CC99FF", "E5CCFF", "FF007F", "FF00FF", "FF3399", "FF33FF", "FF66B2", "FF66FF", "FF99CC", "FF99FF", "FFCCE5",
+ "FFCCFF"};
+
+ String[] OgFairyHexes = {"FF99FF", "FFCCFF", "E5CCFF", "CC99FF", "CC00CC", "FF00FF", "FF33FF", "FF66FF",
+ "B266FF", "9933FF", "7F00FF", "660066", "6600CC", "4C0099", "330066", "990099", "660033", "99004C", "CC0066",
+ "660033", "99004C", "FFCCE5", "660033", "FFCCE5", "FF99CC", "FFCCE5", "FF99CC", "FF66B2"};
+
+ String[] Glitched = {"FFDC51", "F7DA33", "606060", "E7413C", "45413C", "4A14B7", "1793C4", "000000", "E75C3C", "65605A",
+ "5D2FB9", "17A8C4", "E76E3C", "88837E", "8969C8", "1CD4E4"}; // Glitched through other means such as Shark Scale upgrade color
+
+ String[] Spook = {"000000", "070008", "0E000F", "150017", "1B001F", "220027", "29002E", "300036", "37003E", "3E0046",
+ "45004D", "4C0055", "52005D", "590065", "60006C", "670074", "6E007C", "750084", "7C008B", "830093",
+ "89009B", "9000A3", "9700AA", "993399", "9E00B2"};
+
+ // List of exceptions
+
+ String[] Ranchers = {"CC5500", "000000", "0"};
+ String[] Reaper = {"1B1B1B", "FF0000"};
+
+ String[] AdaptiveChest = {"3ABE78", "82E3D8", "BFBCB2", "D579FF", "FF4242", "FFC234"};
+ String[] Adaptive = {"169F57", "2AB5A5", "6E00A0", "BB0000", "BFBCB2", "FFF7E6"};
+}
diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json
index 8665ce45..990fc351 100644
--- a/src/main/resources/assets/skyblocker/lang/en_us.json
+++ b/src/main/resources/assets/skyblocker/lang/en_us.json
@@ -65,6 +65,7 @@
"text.autoconfig.skyblocker.option.general.tabHud.nameSorting": "Player Name Sorting Method",
"text.autoconfig.skyblocker.option.general.tabHud.nameSorting.@Tooltip": "Alphabetical sorting sorts names alphabetically while Default has no particular order.",
"text.autoconfig.skyblocker.option.general.itemTooltip": "Item Tooltip",
+ "text.autoconfig.skyblocker.option.general.itemTooltip.enableExoticCheck": "Enable Exotic Check",
"text.autoconfig.skyblocker.option.general.itemTooltip.enableNPCPrice": "Enable NPC Price",
"text.autoconfig.skyblocker.option.general.itemTooltip.enableMotesPrice": "Enable Motes Price",
"text.autoconfig.skyblocker.option.general.itemTooltip.enableMotesPrice.@Tooltip": "Displays the Motes sell price of an item while in The Rift.",
@@ -279,6 +280,13 @@
"skyblocker.dungeons.secrets.customWaypointRemoved": "§rRemoved custom waypoint at X: %d, Y: %d, Z: %d for room %s secret #%d of category %s with name '%s'.",
"skyblocker.dungeons.secrets.customWaypointNotFound": "§cNo custom waypoint found at X: %d, Y: %d, Z: %d for room %s.",
+ "skyblocker.exotic.crystal": "CRYSTAL",
+ "skyblocker.exotic.fairy": "FAIRY",
+ "skyblocker.exotic.og_fairy": "OG_FAIRY",
+ "skyblocker.exotic.spook": "SPOOK",
+ "skyblocker.exotic.glitched": "GLITCHED",
+ "skyblocker.exotic.exotic": "EXOTIC",
+
"skyblocker.fishing.reelNow": "Reel in now!",
"skyblocker.rift.healNow": "Heal now!",
"skyblocker.rift.iceNow": "Ice now!",