aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLulonaut <67191924+Lulonaut@users.noreply.github.com>2022-08-13 10:14:39 +0200
committerGitHub <noreply@github.com>2022-08-13 18:14:39 +1000
commit2641d9a09af3a7c3cdb130de34c5561a9b30f7d4 (patch)
treee3a0c605abf9bbd787b29cd602d45c87efade9a5
parent3571d2bba813a0f260f0d0356da0dd0c19660b00 (diff)
downloadNotEnoughUpdates-2641d9a09af3a7c3cdb130de34c5561a9b30f7d4.tar.gz
NotEnoughUpdates-2641d9a09af3a7c3cdb130de34c5561a9b30f7d4.tar.bz2
NotEnoughUpdates-2641d9a09af3a7c3cdb130de34c5561a9b30f7d4.zip
quiver info in pv (#210)
Co-authored-by: nopo <noahogno@gmail.com> Co-authored-by: NopoTheGamer <40329022+NopoTheGamer@users.noreply.github.com>
-rw-r--r--Update Notes/2.1.md1
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/BazaarSacksProfit.java8
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java93
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/InventoriesPage.java36
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/PlayerStats.java95
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/info/QuiverInfo.java62
6 files changed, 202 insertions, 93 deletions
diff --git a/Update Notes/2.1.md b/Update Notes/2.1.md
index c41b9ccb..774ce075 100644
--- a/Update Notes/2.1.md
+++ b/Update Notes/2.1.md
@@ -35,6 +35,7 @@
- Fixed minion tiers crafted by coop members not showing up in /pv - Lulonaut
- Fixed crash in /pv when the player had a pet that is not saved in the repo - Lulonaut
- Added senither and lily weight - CrypticPlasma
+ - Added info about the Quiver when hovering over the arrow in the inventory tab of /pv - Lulonaut
### **Minor Changes:**
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/BazaarSacksProfit.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/BazaarSacksProfit.java
index c323cd2e..3137fb90 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/BazaarSacksProfit.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/BazaarSacksProfit.java
@@ -146,6 +146,8 @@ public class BazaarSacksProfit {
map.put("§a" + formatter.format(amount) + "§7x §f" + name + " §7for §6" + priceFormat + " coins", extraPrice);
}
+
+ event.toolTip.add(4, "");
if (showSellOrderPrice) {
event.toolTip.add(4, "§7Sell order price: §6" + formatter.format(totalPrice));
} else {
@@ -153,14 +155,18 @@ public class BazaarSacksProfit {
}
event.toolTip.add(4, "");
+ event.toolTip.removeIf(line -> line.equals("§5§o"));
+ int index = 4;
for (String name : invalidNames) {
+ index++;
event.toolTip.add(4, name + " §cMissing repo data!");
}
for (String text : TrophyRewardOverlay.sortByValue(map).keySet()) {
+ index++;
event.toolTip.add(4, text);
}
+ event.toolTip.add(index, "");
- event.toolTip.add("");
if (!showSellOrderPrice) {
event.toolTip.add("§8[Press SHIFT to show sell order price]");
} else {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java
index 0ab67595..5093b036 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java
@@ -29,17 +29,6 @@ import io.github.moulberry.notenoughupdates.profileviewer.bestiary.BestiaryPage;
import io.github.moulberry.notenoughupdates.profileviewer.trophy.TrophyFishPage;
import io.github.moulberry.notenoughupdates.util.Constants;
import io.github.moulberry.notenoughupdates.util.Utils;
-import java.awt.*;
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.text.NumberFormat;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Optional;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityOtherPlayerMP;
import net.minecraft.client.gui.GuiScreen;
@@ -61,6 +50,18 @@ import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL14;
import org.lwjgl.opengl.GL20;
+import java.awt.*;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.text.NumberFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Optional;
+
public class GuiProfileViewer extends GuiScreen {
public static final ResourceLocation pv_dropdown = new ResourceLocation("notenoughupdates:pv_dropdown.png");
@@ -354,8 +355,8 @@ public class GuiProfileViewer extends GuiScreen {
} else {
showBingoPage =
currProfileInfo != null &&
- currProfileInfo.has("game_mode") &&
- currProfileInfo.get("game_mode").getAsString().equals("bingo");
+ currProfileInfo.has("game_mode") &&
+ currProfileInfo.get("game_mode").getAsString().equals("bingo");
}
if (!showBingoPage && currentPage == ProfileViewerPage.BINGO) currentPage = ProfileViewerPage.BASIC;
@@ -407,8 +408,8 @@ public class GuiProfileViewer extends GuiScreen {
//ironman icon
if (
currProfileInfo != null &&
- currProfileInfo.has("game_mode") &&
- currProfileInfo.get("game_mode").getAsString().equals("ironman")
+ currProfileInfo.has("game_mode") &&
+ currProfileInfo.get("game_mode").getAsString().equals("ironman")
) {
GlStateManager.color(1, 1, 1, 1);
Minecraft.getMinecraft().getTextureManager().bindTexture(pv_ironman);
@@ -417,8 +418,8 @@ public class GuiProfileViewer extends GuiScreen {
//bingo! icon
if (
currProfileInfo != null &&
- currProfileInfo.has("game_mode") &&
- currProfileInfo.get("game_mode").getAsString().equals("bingo")
+ currProfileInfo.has("game_mode") &&
+ currProfileInfo.get("game_mode").getAsString().equals("bingo")
) {
GlStateManager.color(1, 1, 1, 1);
Minecraft.getMinecraft().getTextureManager().bindTexture(pv_bingo);
@@ -427,8 +428,8 @@ public class GuiProfileViewer extends GuiScreen {
//stranded icon
if (
currProfileInfo != null &&
- currProfileInfo.has("game_mode") &&
- currProfileInfo.get("game_mode").getAsString().equals("island")
+ currProfileInfo.has("game_mode") &&
+ currProfileInfo.get("game_mode").getAsString().equals("island")
) {
GlStateManager.color(1, 1, 1, 1);
Minecraft.getMinecraft().getTextureManager().bindTexture(pv_stranded);
@@ -437,10 +438,10 @@ public class GuiProfileViewer extends GuiScreen {
//icon if game mode is unknown
if (
currProfileInfo != null &&
- currProfileInfo.has("game_mode") &&
- !currProfileInfo.get("game_mode").getAsString().equals("island") &&
- !currProfileInfo.get("game_mode").getAsString().equals("bingo") &&
- !currProfileInfo.get("game_mode").getAsString().equals("ironman")
+ currProfileInfo.has("game_mode") &&
+ !currProfileInfo.get("game_mode").getAsString().equals("island") &&
+ !currProfileInfo.get("game_mode").getAsString().equals("bingo") &&
+ !currProfileInfo.get("game_mode").getAsString().equals("ironman")
) {
GlStateManager.color(1, 1, 1, 1);
Minecraft.getMinecraft().getTextureManager().bindTexture(pv_unknown);
@@ -505,8 +506,8 @@ public class GuiProfileViewer extends GuiScreen {
currProfileInfo = profile.getProfileInformation(otherProfileId);
if (
currProfileInfo != null &&
- currProfileInfo.has("game_mode") &&
- currProfileInfo.get("game_mode").getAsString().equals("ironman")
+ currProfileInfo.has("game_mode") &&
+ currProfileInfo.get("game_mode").getAsString().equals("ironman")
) {
GlStateManager.color(1, 1, 1, 1);
Minecraft.getMinecraft().getTextureManager().bindTexture(pv_ironman);
@@ -520,8 +521,8 @@ public class GuiProfileViewer extends GuiScreen {
}
if (
currProfileInfo != null &&
- currProfileInfo.has("game_mode") &&
- currProfileInfo.get("game_mode").getAsString().equals("bingo")
+ currProfileInfo.has("game_mode") &&
+ currProfileInfo.get("game_mode").getAsString().equals("bingo")
) {
GlStateManager.color(1, 1, 1, 1);
Minecraft.getMinecraft().getTextureManager().bindTexture(pv_bingo);
@@ -535,8 +536,8 @@ public class GuiProfileViewer extends GuiScreen {
}
if (
currProfileInfo != null &&
- currProfileInfo.has("game_mode") &&
- currProfileInfo.get("game_mode").getAsString().equals("island")
+ currProfileInfo.has("game_mode") &&
+ currProfileInfo.get("game_mode").getAsString().equals("island")
) {
GlStateManager.color(1, 1, 1, 1);
Minecraft.getMinecraft().getTextureManager().bindTexture(pv_stranded);
@@ -550,10 +551,10 @@ public class GuiProfileViewer extends GuiScreen {
}
if (
currProfileInfo != null &&
- currProfileInfo.has("game_mode") &&
- !currProfileInfo.get("game_mode").getAsString().equals("island") &&
- !currProfileInfo.get("game_mode").getAsString().equals("bingo") &&
- !currProfileInfo.get("game_mode").getAsString().equals("ironman")
+ currProfileInfo.has("game_mode") &&
+ !currProfileInfo.get("game_mode").getAsString().equals("island") &&
+ !currProfileInfo.get("game_mode").getAsString().equals("bingo") &&
+ !currProfileInfo.get("game_mode").getAsString().equals("ironman")
) {
GlStateManager.color(1, 1, 1, 1);
Minecraft.getMinecraft().getTextureManager().bindTexture(pv_unknown);
@@ -671,9 +672,9 @@ public class GuiProfileViewer extends GuiScreen {
if (timeDiff > 1800000) {
Utils.drawStringCentered(
EnumChatFormatting.RED +
- "" +
- EnumChatFormatting.BOLD +
- "You don't know what's gonna happen to you",
+ "" +
+ EnumChatFormatting.BOLD +
+ "You don't know what's gonna happen to you",
Minecraft.getMinecraft().fontRendererObj,
guiLeft + sizeX / 2f,
guiTop + 191,
@@ -692,9 +693,9 @@ public class GuiProfileViewer extends GuiScreen {
if (timeDiff > 3300000) {
Utils.drawStringCentered(
EnumChatFormatting.DARK_RED +
- "" +
- EnumChatFormatting.BOLD +
- "OW LORD FORGIVE ME FOR THIS",
+ "" +
+ EnumChatFormatting.BOLD +
+ "OW LORD FORGIVE ME FOR THIS",
Minecraft.getMinecraft().fontRendererObj,
guiLeft + sizeX / 2f,
guiTop + 71,
@@ -856,10 +857,10 @@ public class GuiProfileViewer extends GuiScreen {
}
if (
mouseX > guiLeft + 106 &&
- mouseX < guiLeft + 106 + 100 &&
- profile != null &&
- !profile.getProfileNames().isEmpty() &&
- profileId != null
+ mouseX < guiLeft + 106 + 100 &&
+ profile != null &&
+ !profile.getProfileNames().isEmpty() &&
+ profileId != null
) {
if (mouseY > guiTop + sizeY + 3 && mouseY < guiTop + sizeY + 23) {
try {
@@ -997,9 +998,9 @@ public class GuiProfileViewer extends GuiScreen {
int maxXp = (int) levelObj.maxXpForLevel;
levelStr =
EnumChatFormatting.DARK_PURPLE +
- shortNumberFormat(Math.round((level % 1) * maxXp), 0) +
- "/" +
- shortNumberFormat(maxXp, 0);
+ shortNumberFormat(Math.round((level % 1) * maxXp), 0) +
+ "/" +
+ shortNumberFormat(maxXp, 0);
}
if (totalXpStr != null) {
tooltipToDisplay = Utils.createList(levelStr, totalXpStr);
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/InventoriesPage.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/InventoriesPage.java
index 4c60a8ca..8bba9c76 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/InventoriesPage.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/InventoriesPage.java
@@ -19,24 +19,12 @@
package io.github.moulberry.notenoughupdates.profileviewer;
-import static io.github.moulberry.notenoughupdates.profileviewer.GuiProfileViewer.pv_elements;
-
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.profileviewer.info.QuiverInfo;
import io.github.moulberry.notenoughupdates.util.Utils;
-import java.awt.*;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.renderer.GlStateManager;
@@ -52,6 +40,20 @@ import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.GL11;
+import java.awt.*;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import static io.github.moulberry.notenoughupdates.profileviewer.GuiProfileViewer.pv_elements;
+
public class InventoriesPage extends GuiProfileViewerPage {
public static final ResourceLocation pv_invs = new ResourceLocation("notenoughupdates:pv_invs.png");
@@ -334,8 +336,12 @@ public class InventoriesPage extends GuiProfileViewerPage {
if (mouseX > guiLeft + 173 && mouseX < guiLeft + 173 + 16) {
if (mouseY > guiTop + 101 && mouseY < guiTop + 137 + 16) {
if (mouseY < guiTop + 101 + 17) {
- getInstance().tooltipToDisplay =
- Utils.createList(EnumChatFormatting.WHITE + "Arrow " + EnumChatFormatting.GRAY + "x" + arrowCount);
+ QuiverInfo quiverInfo = PlayerStats.getQuiverInfo(inventoryInfo, profile.getProfileInformation(profileId));
+ if (quiverInfo == null) {
+ getInstance().tooltipToDisplay = Utils.createList(EnumChatFormatting.RED + "Error checking Quiver");
+ } else {
+ getInstance().tooltipToDisplay = quiverInfo.generateProfileViewerTooltip();
+ }
} else if (mouseY < guiTop + 119 + 17) {
getInstance().tooltipToDisplay =
Utils.createList(EnumChatFormatting.GREEN + "Green Candy " + EnumChatFormatting.GRAY + "x" + greenCandyCount);
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/PlayerStats.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/PlayerStats.java
index b32aad61..b0cc930a 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/PlayerStats.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/PlayerStats.java
@@ -24,9 +24,18 @@ import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.profileviewer.info.QuiverInfo;
import io.github.moulberry.notenoughupdates.util.Constants;
import io.github.moulberry.notenoughupdates.util.JsonUtils;
import io.github.moulberry.notenoughupdates.util.Utils;
+import net.minecraft.nbt.CompressedStreamTools;
+import net.minecraft.nbt.JsonToNBT;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.nbt.NBTTagList;
+import net.minecraft.util.EnumChatFormatting;
+import org.apache.commons.lang3.StringUtils;
+import org.jetbrains.annotations.Nullable;
+
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.AbstractMap;
@@ -41,14 +50,6 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
-import net.minecraft.nbt.CompressedStreamTools;
-import net.minecraft.nbt.JsonToNBT;
-import net.minecraft.nbt.NBTTagCompound;
-import net.minecraft.nbt.NBTTagList;
-import net.minecraft.util.EnumChatFormatting;
-import org.apache.commons.lang3.StringUtils;
-import org.jetbrains.annotations.Nullable;
-
public class PlayerStats {
public static final String HEALTH = "health";
@@ -300,12 +301,12 @@ public class PlayerStats {
bonuses.addStat(HEALTH, 60);
break;
case "EMERALD_ARMOR_":
- {
- int bonus = (int) Math.floor(Utils.getElementAsFloat(Utils.getElement(collectionInfo, "EMERALD"), 0) / 3000);
- bonuses.addStat(HEALTH, bonus);
- bonuses.addStat(DEFENCE, bonus);
- }
- break;
+ {
+ int bonus = (int) Math.floor(Utils.getElementAsFloat(Utils.getElement(collectionInfo, "EMERALD"), 0) / 3000);
+ bonuses.addStat(HEALTH, bonus);
+ bonuses.addStat(DEFENCE, bonus);
+ }
+ break;
case "FAIRY_":
bonuses.addStat(HEALTH, Utils.getElementAsFloat(Utils.getElement(profile, "fairy_souls_collected"), 0));
break;
@@ -457,18 +458,18 @@ public class PlayerStats {
if (
petsInfo != null &&
- petsInfo.has("active_pet") &&
- petsInfo.get("active_pet") != null &&
- petsInfo.get("active_pet").isJsonObject()
+ petsInfo.has("active_pet") &&
+ petsInfo.get("active_pet") != null &&
+ petsInfo.get("active_pet").isJsonObject()
) {
JsonObject pet = petsInfo.get("active_pet").getAsJsonObject();
if (
pet.has("type") &&
- pet.get("type") != null &&
- pet.has("tier") &&
- pet.get("tier") != null &&
- pet.has("exp") &&
- pet.get("exp") != null
+ pet.get("type") != null &&
+ pet.has("tier") &&
+ pet.get("tier") != null &&
+ pet.has("exp") &&
+ pet.get("exp") != null
) {
String petname = pet.get("type").getAsString();
String tier = pet.get("tier").getAsString();
@@ -484,8 +485,8 @@ public class PlayerStats {
if (
pet.has("heldItem") &&
- !pet.get("heldItem").isJsonNull() &&
- pet.get("heldItem").getAsString().equals("PET_ITEM_TIER_BOOST")
+ !pet.get("heldItem").isJsonNull() &&
+ pet.get("heldItem").getAsString().equals("PET_ITEM_TIER_BOOST")
) {
tierNum = "" + (Integer.parseInt(tierNum) + 1);
}
@@ -601,8 +602,8 @@ public class PlayerStats {
for (Map.Entry<String, JsonElement> statEntry : stats.statsJson.entrySet()) {
if (
statEntry.getKey().equals(CRIT_DAMAGE) ||
- statEntry.getKey().equals(INTELLIGENCE) ||
- statEntry.getKey().equals(BONUS_ATTACK_SPEED)
+ statEntry.getKey().equals(INTELLIGENCE) ||
+ statEntry.getKey().equals(BONUS_ATTACK_SPEED)
) continue;
stats.statsJson.add(statEntry.getKey(), new JsonPrimitive(Math.max(0, statEntry.getValue().getAsFloat())));
}
@@ -662,7 +663,7 @@ public class PlayerStats {
}
Map<String, Integer> accessories = JsonUtils.getJsonArrayAsStream(inventoryInfo.get("talisman_bag").getAsJsonArray())
- .map(o -> {
+ .map(o -> {
try {
return JsonToNBT.getTagFromJson(o.getAsJsonObject().get("nbttag").getAsString());
} catch (Exception ignored) {
@@ -680,7 +681,7 @@ public class PlayerStats {
tag.getCompoundTag("ExtraAttributes").getString("id"),
Utils.getRarityFromLore(lastElementJsonArray)
);
- }).sorted(Comparator.comparingInt(e -> -e.getValue())).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (v1,v2)->v1, LinkedHashMap::new));
+ }).sorted(Comparator.comparingInt(e -> -e.getValue())).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (v1, v2)->v1, LinkedHashMap::new));
Set<String> ignoredTalismans = new HashSet<>();
int powderAmount = 0;
@@ -742,9 +743,9 @@ public class PlayerStats {
if (
profileInfo == null ||
- !profileInfo.has(abs) ||
- !profileInfo.get(abs).isJsonObject() ||
- !profileInfo.get(abs).getAsJsonObject().has("selected_power")
+ !profileInfo.has(abs) ||
+ !profileInfo.get(abs).isJsonObject() ||
+ !profileInfo.get(abs).getAsJsonObject().has("selected_power")
) {
return null;
}
@@ -752,6 +753,38 @@ public class PlayerStats {
return selectedPower.substring(0, 1).toUpperCase() + selectedPower.substring(1);
}
+ public static @Nullable QuiverInfo getQuiverInfo(JsonObject inventoryInfo, JsonObject profileInfo) {
+ if (inventoryInfo == null
+ || !inventoryInfo.has("quiver")
+ || !inventoryInfo.get("quiver").isJsonArray()) {
+ return null;
+ }
+ QuiverInfo quiverInfo = new QuiverInfo();
+ quiverInfo.arrows = new HashMap<>();
+
+ JsonArray quiver = inventoryInfo.getAsJsonArray("quiver");
+ for (JsonElement quiverEntry : quiver) {
+ if (quiverEntry == null || quiverEntry.isJsonNull() || !quiverEntry.isJsonObject()) {
+ continue;
+ }
+ JsonObject stack = quiverEntry.getAsJsonObject();
+ if (!stack.has("internalname") || !stack.has("count")) {
+ continue;
+ }
+ String internalName = stack.get("internalname").getAsString();
+ int count = stack.get("count").getAsInt();
+
+ quiverInfo.arrows.computeIfPresent(internalName, (key, existing) -> existing + count);
+ quiverInfo.arrows.putIfAbsent(internalName, count);
+ }
+
+ if (profileInfo.has("favorite_arrow")) {
+ quiverInfo.selectedArrow = profileInfo.get("favorite_arrow").getAsString();
+ }
+
+ return quiverInfo;
+ }
+
public static class Stats {
JsonObject statsJson = new JsonObject();
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/info/QuiverInfo.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/info/QuiverInfo.java
new file mode 100644
index 00000000..b4d92325
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/info/QuiverInfo.java
@@ -0,0 +1,62 @@
+/*
+ * 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.profileviewer.info;
+
+import com.google.gson.JsonObject;
+import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import net.minecraft.util.EnumChatFormatting;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+public class QuiverInfo {
+ public String selectedArrow;
+ public Map<String, Integer> arrows;
+
+ public List<String> generateProfileViewerTooltip() {
+ List<String> list = new ArrayList<>();
+ int totalCount = 0;
+ list.add(EnumChatFormatting.AQUA + "Quiver:");
+ for (Map.Entry<String, Integer> arrow : arrows.entrySet()) {
+ JsonObject repoInfo = NotEnoughUpdates.INSTANCE.manager.getItemInformation().get(arrow.getKey());
+ if (repoInfo == null || repoInfo.isJsonNull()) {
+ continue;
+ }
+ list.add(
+ " " + repoInfo.get("displayname").getAsString() + EnumChatFormatting.RESET + ": " + EnumChatFormatting.GREEN +
+ EnumChatFormatting.BOLD + arrow.getValue());
+ totalCount += arrow.getValue();
+ }
+
+ list.add("");
+ list.add(EnumChatFormatting.AQUA + "Total: " + EnumChatFormatting.GREEN + EnumChatFormatting.BOLD + totalCount);
+ if (selectedArrow != null) {
+ JsonObject repoInfo = NotEnoughUpdates.INSTANCE.manager.getItemInformation().get(selectedArrow);
+ if (repoInfo == null) {
+ list.add(EnumChatFormatting.AQUA + "Selected Arrow: " + EnumChatFormatting.RED + "ERROR");
+ } else {
+ list.add(EnumChatFormatting.AQUA + "Selected Arrow: " + repoInfo.get("displayname").getAsString());
+ }
+ }
+
+ return list;
+ }
+}