diff options
| author | Aaron <51387595+AzureAaron@users.noreply.github.com> | 2025-06-26 12:07:10 -0400 |
|---|---|---|
| committer | Aaron <51387595+AzureAaron@users.noreply.github.com> | 2025-06-26 12:07:10 -0400 |
| commit | 71ca871f2a2441813b26e24467b8e75b166f747a (patch) | |
| tree | 68df274445975ad1fc1c13fe667c59b2df486a52 /src | |
| parent | 3bd588279171d1f59b0433d2b94da29f5db4a740 (diff) | |
| download | Skyblocker-71ca871f2a2441813b26e24467b8e75b166f747a.tar.gz Skyblocker-71ca871f2a2441813b26e24467b8e75b166f747a.tar.bz2 Skyblocker-71ca871f2a2441813b26e24467b8e75b166f747a.zip | |
Add attribute list for bazaar price support
The code for generating the list has been left in so that it can easily
be regenerated if necessary.
Diffstat (limited to 'src')
8 files changed, 1314 insertions, 6 deletions
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/hunting/Attribute.java b/src/main/java/de/hysky/skyblocker/skyblock/hunting/Attribute.java new file mode 100644 index 00000000..4090a571 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/hunting/Attribute.java @@ -0,0 +1,16 @@ +package de.hysky.skyblocker.skyblock.hunting; + +import java.util.List; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; + +public record Attribute(String name, String shardName, String id, String apiId) { + private static final Codec<Attribute> CODEC = RecordCodecBuilder.create(instance -> instance.group( + Codec.STRING.fieldOf("name").forGetter(Attribute::name), + Codec.STRING.fieldOf("shardName").forGetter(Attribute::shardName), + Codec.STRING.fieldOf("id").forGetter(Attribute::id), + Codec.STRING.fieldOf("apiId").forGetter(Attribute::apiId) + ).apply(instance, Attribute::new)); + public static final Codec<List<Attribute>> LIST_CODEC = CODEC.listOf(); +} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/hunting/Attributes.java b/src/main/java/de/hysky/skyblocker/skyblock/hunting/Attributes.java new file mode 100644 index 00000000..e24f11bd --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/hunting/Attributes.java @@ -0,0 +1,53 @@ +package de.hysky.skyblocker.skyblock.hunting; + +import java.io.BufferedReader; +import java.util.List; +import java.util.concurrent.CompletableFuture; + +import org.jetbrains.annotations.Nullable; +import org.slf4j.Logger; + +import com.google.gson.JsonParser; +import com.mojang.logging.LogUtils; +import com.mojang.serialization.JsonOps; + +import de.hysky.skyblocker.SkyblockerMod; +import de.hysky.skyblocker.annotations.Init; +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; +import net.minecraft.client.MinecraftClient; +import net.minecraft.component.ComponentHolder; +import net.minecraft.component.DataComponentTypes; +import net.minecraft.util.Identifier; + +public class Attributes { + private static final Logger LOGGER = LogUtils.getLogger(); + private static final Identifier ATTRIBUTES_FILE = Identifier.of(SkyblockerMod.NAMESPACE, "hunting/attributes.json"); + private static List<Attribute> attributes = List.of(); + + @Init + public static void init() { + ClientLifecycleEvents.CLIENT_STARTED.register(Attributes::loadShards); + } + + private static void loadShards(MinecraftClient client) { + CompletableFuture.runAsync(() -> { + try (BufferedReader reader = client.getResourceManager().openAsReader(ATTRIBUTES_FILE)) { + attributes = Attribute.LIST_CODEC.parse(JsonOps.INSTANCE, JsonParser.parseReader(reader)).getOrThrow(); + } catch (Exception e) { + LOGGER.error("[Skyblocker Attributes] Failed to load attributes.", e); + } + }); + } + + @Nullable + public static Attribute getAttributeFromItemName(ComponentHolder stack) { + if (!stack.contains(DataComponentTypes.CUSTOM_NAME)) return null; + String name = stack.get(DataComponentTypes.CUSTOM_NAME).getString(); + + for (Attribute attribute : attributes) { + if (attribute.shardName().equals(name)) return attribute; + } + + return null; + } +} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/hunting/AttributesDebug.java b/src/main/java/de/hysky/skyblocker/skyblock/hunting/AttributesDebug.java new file mode 100644 index 00000000..1ba4bd72 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/hunting/AttributesDebug.java @@ -0,0 +1,103 @@ +package de.hysky.skyblocker.skyblock.hunting; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Locale; +import java.util.concurrent.CompletableFuture; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.lwjgl.glfw.GLFW; +import org.slf4j.Logger; + +import com.mojang.logging.LogUtils; +import com.mojang.serialization.JsonOps; + +import de.hysky.skyblocker.SkyblockerMod; +import de.hysky.skyblocker.skyblock.item.tooltip.info.TooltipInfoType; +import de.hysky.skyblocker.utils.ItemUtils; +import de.hysky.skyblocker.utils.RomanNumerals; +import de.hysky.skyblocker.utils.container.ContainerSolver; +import de.hysky.skyblocker.utils.container.ContainerSolverManager; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents; +import net.fabricmc.fabric.api.client.screen.v1.ScreenKeyboardEvents; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.screen.ingame.HandledScreen; +import net.minecraft.item.ItemStack; +import net.minecraft.screen.GenericContainerScreenHandler; + +public class AttributesDebug { + private static final Logger LOGGER = LogUtils.getLogger(); + private static final MinecraftClient CLIENT = MinecraftClient.getInstance(); + private static final List<Attribute> DUMPED_ATTRIBUTES = new ArrayList<>(); + private static final Pattern SOURCE_PATTERN = Pattern.compile("Source: (?<shardName>[A-za-z ]+) Shard \\((?<id>[CUREL]\\d+)\\)"); + private static final Path ATTRIBUTE_EXPORT_DEST = SkyblockerMod.CONFIG_DIR.resolve("attribute_export.json"); + + //@Init + public static void init() { + ScreenEvents.AFTER_INIT.register((client, screen, scaledWidth, scaledHeight) -> { + ScreenKeyboardEvents.afterKeyPress(screen).register((screen1, key, scancode, modifiers) -> { + if (key == GLFW.GLFW_KEY_G) { + dumpAttributes(); + } else if (key == GLFW.GLFW_KEY_J) { + exportAttributes(); + } + }); + }); + } + + private static void dumpAttributes() { + if (CLIENT.currentScreen instanceof HandledScreen<?> screen && screen.getTitle().getString().equals("Attribute Menu")) { + @SuppressWarnings("unchecked") + Int2ObjectMap<ItemStack> slots = ContainerSolverManager.slotMap(screen.getScreenHandler().slots.subList(0, ((HandledScreen<GenericContainerScreenHandler>) screen).getScreenHandler().getRows() * 9)); + ContainerSolver.trimEdges(slots, 6); + + for (ItemStack stack : slots.values()) { + if (stack.isEmpty()) continue; + + String name = stack.getName().getString(); + Matcher sourceMatcher = ItemUtils.getLoreLineIfMatch(stack, SOURCE_PATTERN); + + //Remove roman numeral from name + List<String> words = new ArrayList<>(Arrays.asList(name.split(" "))); + if (RomanNumerals.isValidRomanNumeral(words.getLast().strip())) { + words.removeLast(); + name = String.join(" ", words); + } + + if (sourceMatcher != null) { + String shardName = sourceMatcher.group("shardName"); + String id = sourceMatcher.group("id"); + String apiIdGuess = "SHARD_" + shardName.replace(' ', '_').toUpperCase(Locale.ENGLISH); + boolean hasDataForId = TooltipInfoType.BAZAAR.getData().containsKey(apiIdGuess); + + //Most attributes follow the format above but some have different ids so this is to catch those ones + if (!hasDataForId) LOGGER.warn("[Skyblocker Attributes Debug] No data found for shard. Shard Name: {}", shardName); + + Attribute attribute = new Attribute(name, shardName, id, apiIdGuess); + DUMPED_ATTRIBUTES.add(attribute); + } else { + LOGGER.warn("[Skyblocker Attributes Debug] Failed to match shard! Name: {}", name); + } + } + } + } + + private static void exportAttributes() { + if (CLIENT.currentScreen instanceof HandledScreen screen && screen.getTitle().getString().equals("Attribute Menu")) { + List<Attribute> copy = DUMPED_ATTRIBUTES.stream().distinct().toList(); + + CompletableFuture.runAsync(() -> { + try { + Files.writeString(ATTRIBUTE_EXPORT_DEST, Attribute.LIST_CODEC.encodeStart(JsonOps.INSTANCE, copy).getOrThrow().toString()); + } catch (Exception e) { + LOGGER.error("[Skyblocker Attributes Debug] Failed to export attributes!", e); + } + }); + } + } +} diff --git a/src/main/java/de/hysky/skyblocker/utils/ItemUtils.java b/src/main/java/de/hysky/skyblocker/utils/ItemUtils.java index a27ed97a..dc3f3c5a 100644 --- a/src/main/java/de/hysky/skyblocker/utils/ItemUtils.java +++ b/src/main/java/de/hysky/skyblocker/utils/ItemUtils.java @@ -11,6 +11,8 @@ import com.mojang.serialization.JsonOps; import com.mojang.serialization.codecs.RecordCodecBuilder; import de.hysky.skyblocker.SkyblockerMod; import de.hysky.skyblocker.debug.Debug; +import de.hysky.skyblocker.skyblock.hunting.Attribute; +import de.hysky.skyblocker.skyblock.hunting.Attributes; import de.hysky.skyblocker.skyblock.item.PetInfo; import de.hysky.skyblocker.skyblock.item.tooltip.adders.ObtainedDateTooltip; import de.hysky.skyblocker.skyblock.item.tooltip.info.TooltipInfoType; @@ -185,11 +187,9 @@ public final class ItemUtils { } } case "ATTRIBUTE_SHARD" -> { - if (customData.contains("attributes")) { - NbtCompound shards = customData.getCompoundOrEmpty("attributes"); - String shard = shards.getKeys().stream().findFirst().orElse(""); - return id + "-" + shard.toUpperCase(Locale.ENGLISH) + "_" + shards.getInt(shard, 0); - } + Attribute attribute = Attributes.getAttributeFromItemName(itemStack); + + if (attribute != null) return attribute.apiId(); } case "NEW_YEAR_CAKE" -> { return id + "_" + customData.getInt("new_years_cake", 0); diff --git a/src/main/resources/assets/skyblocker/hunting/attribute_upgrades.json b/src/main/resources/assets/skyblocker/hunting/attribute_upgrades.json new file mode 100644 index 00000000..c26bc82f --- /dev/null +++ b/src/main/resources/assets/skyblocker/hunting/attribute_upgrades.json @@ -0,0 +1,72 @@ +{ + "COMMON": { + "shardsForUpgrade": [ + 1, + 4, + 9, + 15, + 22, + 30, + 40, + 54, + 72, + 96 + ] + }, + "UNCOMMON": { + "shardsForUpgrade": [ + 1, + 3, + 6, + 10, + 15, + 21, + 28, + 36, + 48, + 64 + ] + }, + "RARE": { + "shardsForUpgrade": [ + 1, + 3, + 6, + 9, + 13, + 17, + 22, + 28, + 36, + 48 + ] + }, + "EPIC": { + "shardsForUpgrade": [ + 1, + 2, + 4, + 6, + 9, + 12, + 16, + 20, + 25, + 32 + ] + }, + "LEGENDARY": { + "shardsForUpgrade": [ + 1, + 2, + 3, + 5, + 7, + 9, + 12, + 15, + 19, + 24 + ] + } +}
\ No newline at end of file diff --git a/src/main/resources/assets/skyblocker/hunting/attributes.json b/src/main/resources/assets/skyblocker/hunting/attributes.json new file mode 100644 index 00000000..97a055af --- /dev/null +++ b/src/main/resources/assets/skyblocker/hunting/attributes.json @@ -0,0 +1,1046 @@ +[ + { + "name": "Nature Elemental", + "shardName": "Grove", + "id": "C1", + "apiId": "SHARD_GROVE" + }, + { + "name": "Fog Elemental", + "shardName": "Mist", + "id": "C2", + "apiId": "SHARD_MIST" + }, + { + "name": "Light Elemental", + "shardName": "Flash", + "id": "C3", + "apiId": "SHARD_FLASH" + }, + { + "name": "Nocturnal Animal", + "shardName": "Phanpyre", + "id": "C4", + "apiId": "SHARD_PHANPYRE" + }, + { + "name": "Cheapstake", + "shardName": "Cod", + "id": "C5", + "apiId": "SHARD_COD" + }, + { + "name": "Moonglade Mastery", + "shardName": "Phanflare", + "id": "C7", + "apiId": "SHARD_PHANFLARE" + }, + { + "name": "Fisherman", + "shardName": "Night Squid", + "id": "C8", + "apiId": "SHARD_NIGHT_SQUID" + }, + { + "name": "Experience", + "shardName": "Lapis Zombie", + "id": "C9", + "apiId": "SHARD_LAPIS_ZOMBIE" + }, + { + "name": "Mossy Box", + "shardName": "Hideonleaf", + "id": "C10", + "apiId": "SHARD_HIDEONLEAF" + }, + { + "name": "Forest Fishing", + "shardName": "Verdant", + "id": "C11", + "apiId": "SHARD_VERDANT" + }, + { + "name": "Skeletal Ruler", + "shardName": "Chill", + "id": "C12", + "apiId": "SHARD_CHILL" + }, + { + "name": "Monster Bait", + "shardName": "Sea Archer", + "id": "C14", + "apiId": "SHARD_SEA_ARCHER" + }, + { + "name": "Arthropod Resistance", + "shardName": "Voracious Spider", + "id": "C15", + "apiId": "SHARD_VORACIOUS_SPIDER" + }, + { + "name": "Happy Box", + "shardName": "Hideongift", + "id": "C16", + "apiId": "SHARD_HIDEONGIFT" + }, + { + "name": "Yummy", + "shardName": "Birries", + "id": "C17", + "apiId": "SHARD_BIRRIES" + }, + { + "name": "Undead Resistance", + "shardName": "Tank Zombie", + "id": "C18", + "apiId": "SHARD_TANK_ZOMBIE" + }, + { + "name": "Fig Sharpening", + "shardName": "Crow", + "id": "C19", + "apiId": "SHARD_CROW" + }, + { + "name": "Unity is Strength", + "shardName": "Tadgang", + "id": "C20", + "apiId": "SHARD_TADGANG" + }, + { + "name": "Ender Resistance", + "shardName": "Zealot", + "id": "C21", + "apiId": "SHARD_ZEALOT" + }, + { + "name": "Bucket Lover", + "shardName": "Coralot", + "id": "C23", + "apiId": "SHARD_CORALOT" + }, + { + "name": "Tree Lurker", + "shardName": "Harpy", + "id": "C24", + "apiId": "SHARD_HARPY" + }, + { + "name": "Visitor Bait", + "shardName": "Mudworm", + "id": "C25", + "apiId": "SHARD_MUDWORM" + }, + { + "name": "Midas Touch", + "shardName": "Golden Ghoul", + "id": "C27", + "apiId": "SHARD_GOLDEN_GHOUL" + }, + { + "name": "Forest Strength", + "shardName": "Azure", + "id": "C29", + "apiId": "SHARD_AZURE" + }, + { + "name": "Blazing Resistance", + "shardName": "Bezal", + "id": "C30", + "apiId": "SHARD_BEZAL" + }, + { + "name": "Yog Membrane", + "shardName": "Yog", + "id": "C33", + "apiId": "SHARD_YOG" + }, + { + "name": "Owl Friend", + "shardName": "Boreal Owl", + "id": "C34", + "apiId": "SHARD_BOREAL_OWL" + }, + { + "name": "Decent Karma", + "shardName": "Newt", + "id": "C35", + "apiId": "SHARD_NEWT" + }, + { + "name": "Rotten Pickaxe", + "shardName": "Miner Zombie", + "id": "C36", + "apiId": "SHARD_MINER_ZOMBIE" + }, + { + "name": "Wood Elemental", + "shardName": "Bramble", + "id": "U1", + "apiId": "SHARD_BRAMBLE" + }, + { + "name": "Water Elemental", + "shardName": "Tide", + "id": "U2", + "apiId": "SHARD_TIDE" + }, + { + "name": "Stone Elemental", + "shardName": "Quake", + "id": "U3", + "apiId": "SHARD_QUAKE" + }, + { + "name": "Fig Collector", + "shardName": "Sparrow", + "id": "U4", + "apiId": "SHARD_SPARROW" + }, + { + "name": "Gold Bait", + "shardName": "Goldfin", + "id": "U5", + "apiId": "SHARD_GOLDFIN" + }, + { + "name": "Mountain Climber", + "shardName": "Troglobyte", + "id": "U6", + "apiId": "SHARD_TROGLOBYTE" + }, + { + "name": "Bigger Box", + "shardName": "Hideoncave", + "id": "U7", + "apiId": "SHARD_HIDEONCAVE" + }, + { + "name": "Good Karma", + "shardName": "Salamander", + "id": "U8", + "apiId": "SHARD_SALAMANDER" + }, + { + "name": "Echo of Boxes", + "shardName": "Cuboa", + "id": "U9", + "apiId": "SHARD_CUBOA" + }, + { + "name": "Pest Luck", + "shardName": "Pest", + "id": "U10", + "apiId": "SHARD_PEST" + }, + { + "name": "Forest Trap", + "shardName": "Mossybit", + "id": "U11", + "apiId": "SHARD_MOSSYBIT" + }, + { + "name": "Mana Steal", + "shardName": "Rain Slime", + "id": "U12", + "apiId": "SHARD_RAIN_SLIME" + }, + { + "name": "Dragon Shortbow Improvement", + "shardName": "Seer", + "id": "U15", + "apiId": "SHARD_SEER" + }, + { + "name": "Mangrove Sharpening", + "shardName": "Heron", + "id": "U16", + "apiId": "SHARD_HERON" + }, + { + "name": "Speed", + "shardName": "Obsidian Defender", + "id": "U18", + "apiId": "SHARD_OBSIDIAN_DEFENDER" + }, + { + "name": "Lost and Found", + "shardName": "Salmon", + "id": "U20", + "apiId": "SHARD_SALMON" + }, + { + "name": "Hunter's Fang", + "shardName": "Viper", + "id": "U21", + "apiId": "SHARD_VIPER" + }, + { + "name": "Insect Power", + "shardName": "Praying Mantis", + "id": "U22", + "apiId": "SHARD_PRAYING_MANTIS" + }, + { + "name": "Undead Ruler", + "shardName": "Zombie Soldier", + "id": "U24", + "apiId": "SHARD_ZOMBIE_SOLDIER" + }, + { + "name": "Strong Arms", + "shardName": "Bambuleaf", + "id": "U25", + "apiId": "SHARD_BAMBULEAF" + }, + { + "name": "Life Recovery", + "shardName": "Sycophant", + "id": "U27", + "apiId": "SHARD_SYCOPHANT" + }, + { + "name": "Mangrove Collector", + "shardName": "Seagull", + "id": "U28", + "apiId": "SHARD_SEAGULL" + }, + { + "name": "Spirit Axe", + "shardName": "Ent", + "id": "U29", + "apiId": "SHARD_ENT" + }, + { + "name": "Combo", + "shardName": "Soul of the Alpha", + "id": "U30", + "apiId": "SHARD_SOUL_OF_THE_ALPHA" + }, + { + "name": "Strong Legs", + "shardName": "Mochibear", + "id": "U31", + "apiId": "SHARD_MOCHIBEAR" + }, + { + "name": "Infection", + "shardName": "Magma Slug", + "id": "U32", + "apiId": "SHARD_MAGMA_SLUG" + }, + { + "name": "Arthropod Ruler", + "shardName": "Flaming Spider", + "id": "U33", + "apiId": "SHARD_FLAMING_SPIDER" + }, + { + "name": "Kat's Favorite", + "shardName": "Kiwi", + "id": "U34", + "apiId": "SHARD_KIWI" + }, + { + "name": "Ender Ruler", + "shardName": "Bruiser", + "id": "U36", + "apiId": "SHARD_BRUISER" + }, + { + "name": "Magmatic Ruler", + "shardName": "Stridersurfer", + "id": "U38", + "apiId": "SHARD_STRIDER_SURFER" + }, + { + "name": "Battle Frog", + "shardName": "Rana", + "id": "U39", + "apiId": "SHARD_RANA" + }, + { + "name": "Infiltration", + "shardName": "Termite", + "id": "U40", + "apiId": "SHARD_TERMITE" + }, + { + "name": "Forest Elemental", + "shardName": "Sylvan", + "id": "R1", + "apiId": "SHARD_SYLVAN" + }, + { + "name": "Torrent Elemental", + "shardName": "Cascade", + "id": "R2", + "apiId": "SHARD_CASCADE" + }, + { + "name": "Lightning Elemental", + "shardName": "Bolt", + "id": "R3", + "apiId": "SHARD_BOLT" + }, + { + "name": "Animal Expertise", + "shardName": "Bambloom", + "id": "R4", + "apiId": "SHARD_BAMBLOOM" + }, + { + "name": "Frog Legs", + "shardName": "Toad", + "id": "R5", + "apiId": "SHARD_TOAD" + }, + { + "name": "Essence of Ice", + "shardName": "Glacite Walker", + "id": "R6", + "apiId": "SHARD_GLACITE_WALKER" + }, + { + "name": "Beacon Zealot", + "shardName": "Beaconmite", + "id": "R7", + "apiId": "SHARD_BEACONMITE" + }, + { + "name": "Great Karma", + "shardName": "Lizard King", + "id": "R8", + "apiId": "SHARD_LIZARD_KING" + }, + { + "name": "Hunter's Pressure", + "shardName": "Python", + "id": "R9", + "apiId": "SHARD_PYTHON" + }, + { + "name": "Fancy Visit", + "shardName": "Invisibug", + "id": "R10", + "apiId": "SHARD_INVISIBUG" + }, + { + "name": "Moonglade Serendipity", + "shardName": "Piranha", + "id": "R11", + "apiId": "SHARD_PIRANHA" + }, + { + "name": "Catacombs Box", + "shardName": "Hideongeon", + "id": "R13", + "apiId": "SHARD_HIDEONGEON" + }, + { + "name": "Bone Font", + "shardName": "Lapis Skeleton", + "id": "R15", + "apiId": "SHARD_LAPIS_SKELETON" + }, + { + "name": "Crop Bug", + "shardName": "Cropeetle", + "id": "R16", + "apiId": "SHARD_CROPEETLE" + }, + { + "name": "Humanoid Ruler", + "shardName": "Drowned", + "id": "R18", + "apiId": "SHARD_DROWNED" + }, + { + "name": "Atomized Mithril", + "shardName": "Star Sentry", + "id": "R21", + "apiId": "SHARD_STAR_SENTRY" + }, + { + "name": "Kuudra's Box", + "shardName": "Hideondra", + "id": "R22", + "apiId": "SHARD_HIDEONDRA" + }, + { + "name": "Dwarven Serendipity", + "shardName": "Abyssal Lanternfish", + "id": "R23", + "apiId": "SHARD_ABYSSAL_LANTERN" + }, + { + "name": "Essence of Arthropods", + "shardName": "Arachne", + "id": "R24", + "apiId": "SHARD_ARACHNE" + }, + { + "name": "Cookie Eater", + "shardName": "Bitbug", + "id": "R25", + "apiId": "SHARD_BITBUG" + }, + { + "name": "Essence of Unliving", + "shardName": "Revenant", + "id": "R27", + "apiId": "SHARD_REVENANT" + }, + { + "name": "Crystal Serendipity", + "shardName": "Silentdepth", + "id": "R29", + "apiId": "SHARD_SILENTDEPTH" + }, + { + "name": "Deadeye", + "shardName": "Skeletor", + "id": "R30", + "apiId": "SHARD_SKELETOR" + }, + { + "name": "Atomized Crystals", + "shardName": "Thyst", + "id": "R31", + "apiId": "SHARD_THYST" + }, + { + "name": "Quartz Speed", + "shardName": "Quartzfang", + "id": "R33", + "apiId": "SHARD_QUARTZFANG" + }, + { + "name": "Accessory Size", + "shardName": "Hideonring", + "id": "R34", + "apiId": "SHARD_HIDEONRING" + }, + { + "name": "Winter's Serendipity", + "shardName": "Snowfin", + "id": "R35", + "apiId": "SHARD_SNOWFIN" + }, + { + "name": "Lifeline", + "shardName": "Kada Knight", + "id": "R36", + "apiId": "SHARD_KADA_KNIGHT" + }, + { + "name": "Rabbit Crew", + "shardName": "Carrot King", + "id": "R38", + "apiId": "SHARD_CARROT_KING" + }, + { + "name": "Breeze", + "shardName": "Wither Specter", + "id": "R39", + "apiId": "SHARD_WITHER_SPECTER" + }, + { + "name": "Ignition", + "shardName": "Matcho", + "id": "R42", + "apiId": "SHARD_MATCHO" + }, + { + "name": "Pretty Clothes", + "shardName": "Ladybug", + "id": "R43", + "apiId": "SHARD_LADYBUG" + }, + { + "name": "Extreme Pressure", + "shardName": "Lumisquid", + "id": "R44", + "apiId": "SHARD_LUMISQUID" + }, + { + "name": "Pure Reptile", + "shardName": "Crocodile", + "id": "R45", + "apiId": "SHARD_CROCODILE" + }, + { + "name": "Berry Enjoyer", + "shardName": "Bullfrog", + "id": "R46", + "apiId": "SHARD_BULLFROG" + }, + { + "name": "Essence of the Forest", + "shardName": "Dreadwing", + "id": "R49", + "apiId": "SHARD_DREADWING" + }, + { + "name": "Deep Diving", + "shardName": "Joydive", + "id": "R50", + "apiId": "SHARD_JOYDIVE" + }, + { + "name": "Atomized Glacite", + "shardName": "Stalagmight", + "id": "R51", + "apiId": "SHARD_STALAGMIGHT" + }, + { + "name": "Fungy Luck", + "shardName": "Fungloom", + "id": "R52", + "apiId": "SHARD_FUNGLOOM" + }, + { + "name": "Eelastic", + "shardName": "Eel", + "id": "R53", + "apiId": "SHARD_EEL" + }, + { + "name": "Hunter's Grasp", + "shardName": "King Cobra", + "id": "R54", + "apiId": "SHARD_KING_COBRA" + }, + { + "name": "Blazing Fortune", + "shardName": "Lava Flame", + "id": "R56", + "apiId": "SHARD_LAVA_FLAME" + }, + { + "name": "Essence of Dragons", + "shardName": "Draconic", + "id": "R57", + "apiId": "SHARD_DRACONIC" + }, + { + "name": "Battle Experience", + "shardName": "Falcon", + "id": "R58", + "apiId": "SHARD_FALCON" + }, + { + "name": "Crimson Serendipity", + "shardName": "Inferno Koi", + "id": "R59", + "apiId": "SHARD_INFERNO_KOI" + }, + { + "name": "Essence of Wither", + "shardName": "Wither", + "id": "R60", + "apiId": "SHARD_WITHER" + }, + { + "name": "Echo of Sharpening", + "shardName": "Gecko", + "id": "R61", + "apiId": "SHARD_GECKO" + }, + { + "name": "Earth Elemental", + "shardName": "Terra", + "id": "E1", + "apiId": "SHARD_TERRA" + }, + { + "name": "Frost Elemental", + "shardName": "Cryo", + "id": "E2", + "apiId": "SHARD_CRYO" + }, + { + "name": "Wind Elemental", + "shardName": "Aero", + "id": "E3", + "apiId": "SHARD_AERO" + }, + { + "name": "Foraging Wisdom", + "shardName": "Pandarai", + "id": "E4", + "apiId": "SHARD_PANDARAI" + }, + { + "name": "Excellent Karma", + "shardName": "Leviathan", + "id": "E5", + "apiId": "SHARD_LEVIATHAN" + }, + { + "name": "Echo of Resistance", + "shardName": "Alligator", + "id": "E6", + "apiId": "SHARD_ALLIGATOR" + }, + { + "name": "Berry Mogul", + "shardName": "Fenlord", + "id": "E7", + "apiId": "SHARD_FENLORD" + }, + { + "name": "Hunter's Suppress", + "shardName": "Basilisk", + "id": "E9", + "apiId": "SHARD_BASILISK" + }, + { + "name": "Echo of Atomized", + "shardName": "Iguana", + "id": "E10", + "apiId": "SHARD_IGUANA" + }, + { + "name": "Lucky Rod", + "shardName": "Moray Eel", + "id": "E11", + "apiId": "SHARD_MORAY_EEL" + }, + { + "name": "Dominance", + "shardName": "Thorn", + "id": "E12", + "apiId": "SHARD_THORN" + }, + { + "name": "Lunar Power", + "shardName": "Lunar Moth", + "id": "E13", + "apiId": "SHARD_LUNAR_MOTH" + }, + { + "name": "Trophy Hunter", + "shardName": "Fire Eel", + "id": "E14", + "apiId": "SHARD_FIRE_EEL" + }, + { + "name": "Deep Technique", + "shardName": "Bal", + "id": "E15", + "apiId": "SHARD_BAL" + }, + { + "name": "Sack Size", + "shardName": "Hideonsack", + "id": "E16", + "apiId": "SHARD_HIDEONSACK" + }, + { + "name": "Fishing Speed", + "shardName": "Water Hydra", + "id": "E17", + "apiId": "SHARD_WATER_HYDRA" + }, + { + "name": "Blazing", + "shardName": "Flare", + "id": "E18", + "apiId": "SHARD_FLARE" + }, + { + "name": "Sea Wisdom", + "shardName": "Sea Emperor", + "id": "E20", + "apiId": "SHARD_SEA_EMPEROR" + }, + { + "name": "Reborn", + "shardName": "Prince", + "id": "E21", + "apiId": "SHARD_PRINCE" + }, + { + "name": "Echo of Essence", + "shardName": "Komodo Dragon", + "id": "E22", + "apiId": "SHARD_KOMODO_DRAGON" + }, + { + "name": "Faker", + "shardName": "Mimic", + "id": "E24", + "apiId": "SHARD_MIMIC" + }, + { + "name": "Shell", + "shardName": "Shellwise", + "id": "E26", + "apiId": "SHARD_SHELLWISE" + }, + { + "name": "Warrior", + "shardName": "Barbarian Duke X", + "id": "E27", + "apiId": "SHARD_BARBARIAN_DUKE_X" + }, + { + "name": "Why Not More", + "shardName": "Toucan", + "id": "E28", + "apiId": "SHARD_TOUCAN" + }, + { + "name": "Matriarch Cubs", + "shardName": "Hellwisp", + "id": "E29", + "apiId": "SHARD_HELLWISP" + }, + { + "name": "Echo of Ruler", + "shardName": "Caiman", + "id": "E30", + "apiId": "SHARD_CAIMAN" + }, + { + "name": "Solar Power", + "shardName": "Firefly", + "id": "E31", + "apiId": "SHARD_FIREFLY" + }, + { + "name": "Echo of Hunter", + "shardName": "Sea Serpent", + "id": "E32", + "apiId": "SHARD_SEA_SERPENT" + }, + { + "name": "Veil", + "shardName": "Ghost", + "id": "E33", + "apiId": "SHARD_GHOST" + }, + { + "name": "Mana Regeneration", + "shardName": "XYZ", + "id": "E34", + "apiId": "SHARD_XYZ" + }, + { + "name": "Hunt Wisdom", + "shardName": "Leatherback", + "id": "E35", + "apiId": "SHARD_LEATHERBACK" + }, + { + "name": "Cavern Wisdom", + "shardName": "Cavernshade", + "id": "E36", + "apiId": "SHARD_CAVERNSHADE" + }, + { + "name": "Garden Wisdom", + "shardName": "Dragonfly", + "id": "E37", + "apiId": "SHARD_DRAGONFLY" + }, + { + "name": "Shadow Elemental", + "shardName": "Tenebris", + "id": "L1", + "apiId": "SHARD_TENEBRIS" + }, + { + "name": "Snow Elemental", + "shardName": "Blizzard", + "id": "L2", + "apiId": "SHARD_BLIZZARD" + }, + { + "name": "Storm Elemental", + "shardName": "Tempest", + "id": "L3", + "apiId": "SHARD_TEMPEST" + }, + { + "name": "Reptiloid", + "shardName": "Chameleon", + "id": "L4", + "apiId": "SHARD_CHAMELEON" + }, + { + "name": "Echo of Echoes", + "shardName": "Tiamat", + "id": "L6", + "apiId": "SHARD_TIAMAT" + }, + { + "name": "Echo of Wisdom", + "shardName": "Wyvern", + "id": "L7", + "apiId": "SHARD_WYVERN" + }, + { + "name": "Cloak Improvement", + "shardName": "Tortoise", + "id": "L8", + "apiId": "SHARD_TORTOISE" + }, + { + "name": "Paramount Fortitude", + "shardName": "Endstone Protector", + "id": "L9", + "apiId": "SHARD_ENDSTONE_PROTECTOR" + }, + { |
