aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java122
-rw-r--r--src/main/java/de/hysky/skyblocker/config/configs/GeneralConfig.java23
-rw-r--r--src/main/java/de/hysky/skyblocker/mixins/HandledScreenMixin.java8
-rw-r--r--src/main/java/de/hysky/skyblocker/mixins/InGameHudMixin.java10
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/auction/widgets/RarityWidget.java4
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/item/ItemRarityBackgrounds.java105
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/item/background/ColoredItemBackground.java102
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/item/background/ItemBackgroundManager.java52
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/item/background/adders/ItemRarityBackground.java99
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/item/background/adders/JacobMedalBackground.java71
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/BackpackPreview.java7
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/profileviewer/inventory/Inventory.java7
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/profileviewer/inventory/PlayerInventory.java7
13 files changed, 422 insertions, 195 deletions
diff --git a/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java
index 24cd4974..3f799cd0 100644
--- a/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java
+++ b/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java
@@ -205,7 +205,7 @@ public class GeneralCategory {
() -> config.general.itemTooltip.enableCraftingCost,
newValue -> config.general.itemTooltip.enableCraftingCost = newValue)
.addListener((ignored, event) -> {
- if (event == OptionEventListener.Event.STATE_CHANGE) CraftPriceTooltip.clearCache();
+ if (event == OptionEventListener.Event.STATE_CHANGE) CraftPriceTooltip.clearCache();
})
.controller(ConfigUtils::createEnumCyclingListController)
.build())
@@ -283,34 +283,42 @@ public class GeneralCategory {
.build())
.build())
- //Item Info Display
- .group(OptionGroup.createBuilder()
- .name(Text.translatable("skyblocker.config.general.itemInfoDisplay"))
- .collapsed(true)
- .option(Option.<Boolean>createBuilder()
- .name(Text.translatable("skyblocker.config.general.itemInfoDisplay.itemRarityBackgrounds"))
- .description(OptionDescription.of(Text.translatable("skyblocker.config.general.itemInfoDisplay.itemRarityBackgrounds.@Tooltip")))
- .binding(defaults.general.itemInfoDisplay.itemRarityBackgrounds,
- () -> config.general.itemInfoDisplay.itemRarityBackgrounds,
- newValue -> config.general.itemInfoDisplay.itemRarityBackgrounds = newValue)
- .controller(ConfigUtils::createBooleanController)
- .build())
- .option(Option.<GeneralConfig.RarityBackgroundStyle>createBuilder()
- .name(Text.translatable("skyblocker.config.general.itemInfoDisplay.itemRarityBackgroundStyle"))
- .description(OptionDescription.of(Text.translatable("skyblocker.config.general.itemInfoDisplay.itemRarityBackgroundStyle.@Tooltip")))
- .binding(defaults.general.itemInfoDisplay.itemRarityBackgroundStyle,
- () -> config.general.itemInfoDisplay.itemRarityBackgroundStyle,
- newValue -> config.general.itemInfoDisplay.itemRarityBackgroundStyle = newValue)
- .controller(ConfigUtils::createEnumCyclingListController)
- .build())
- .option(Option.<Float>createBuilder()
- .name(Text.translatable("skyblocker.config.general.itemInfoDisplay.itemRarityBackgroundsOpacity"))
- .binding(defaults.general.itemInfoDisplay.itemRarityBackgroundsOpacity,
- () -> config.general.itemInfoDisplay.itemRarityBackgroundsOpacity,
- newValue -> config.general.itemInfoDisplay.itemRarityBackgroundsOpacity = newValue)
- .controller(opt -> FloatSliderControllerBuilder.create(opt).range(0f, 1f).step(0.05f).formatValue(ConfigUtils.FLOAT_TWO_FORMATTER))
- .build())
- .build())
+ //Item Info Display
+ .group(OptionGroup.createBuilder()
+ .name(Text.translatable("skyblocker.config.general.itemInfoDisplay"))
+ .collapsed(true)
+ .option(Option.<GeneralConfig.ItemBackgroundStyle>createBuilder()
+ .name(Text.translatable("skyblocker.config.general.itemInfoDisplay.itemBackgroundStyle"))
+ .description(OptionDescription.of(Text.translatable("skyblocker.config.general.itemInfoDisplay.itemBackgroundStyle.@Tooltip")))
+ .binding(defaults.general.itemInfoDisplay.itemBackgroundStyle,
+ () -> config.general.itemInfoDisplay.itemBackgroundStyle,
+ newValue -> config.general.itemInfoDisplay.itemBackgroundStyle = newValue)
+ .controller(ConfigUtils::createEnumCyclingListController)
+ .build())
+ .option(Option.<Float>createBuilder()
+ .name(Text.translatable("skyblocker.config.general.itemInfoDisplay.itemBackgroundOpacity"))
+ .binding(defaults.general.itemInfoDisplay.itemBackgroundOpacity,
+ () -> config.general.itemInfoDisplay.itemBackgroundOpacity,
+ newValue -> config.general.itemInfoDisplay.itemBackgroundOpacity = newValue)
+ .controller(opt -> FloatSliderControllerBuilder.create(opt).range(0f, 1f).step(0.05f).formatValue(ConfigUtils.FLOAT_TWO_FORMATTER))
+ .build())
+ .option(Option.<Boolean>createBuilder()
+ .name(Text.translatable("skyblocker.config.general.itemInfoDisplay.itemRarityBackgrounds"))
+ .description(OptionDescription.of(Text.translatable("skyblocker.config.general.itemInfoDisplay.itemRarityBackgrounds.@Tooltip")))
+ .binding(defaults.general.itemInfoDisplay.itemRarityBackgrounds,
+ () -> config.general.itemInfoDisplay.itemRarityBackgrounds,
+ newValue -> config.general.itemInfoDisplay.itemRarityBackgrounds = newValue)
+ .controller(ConfigUtils::createBooleanController)
+ .build())
+ .option(Option.<Boolean>createBuilder()
+ .name(Text.translatable("skyblocker.config.general.itemInfoDisplay.jacobMedalBackgrounds"))
+ .description(OptionDescription.of(Text.translatable("skyblocker.config.general.itemInfoDisplay.jacobMedalBackgrounds.@Tooltip")))
+ .binding(defaults.general.itemInfoDisplay.jacobMedalBackgrounds,
+ () -> config.general.itemInfoDisplay.jacobMedalBackgrounds,
+ newValue -> config.general.itemInfoDisplay.jacobMedalBackgrounds = newValue)
+ .controller(ConfigUtils::createBooleanController)
+ .build())
+ .build())
//Item Protection
.group(OptionGroup.createBuilder()
@@ -325,13 +333,13 @@ public class GeneralCategory {
.controller(ConfigUtils::createEnumCyclingListController)
.build())
.option(Option.<Boolean>createBuilder()
- .name(Text.translatable("skyblocker.config.general.itemProtection.protectValuableConsumables"))
- .description(OptionDescription.of(Text.translatable("skyblocker.config.general.itemProtection.protectValuableConsumables.@Tooltip")))
- .binding(defaults.general.itemProtection.protectValuableConsumables,
- () -> config.general.itemProtection.protectValuableConsumables,
- newValue -> config.general.itemProtection.protectValuableConsumables = newValue)
- .controller(ConfigUtils::createBooleanController)
- .build())
+ .name(Text.translatable("skyblocker.config.general.itemProtection.protectValuableConsumables"))
+ .description(OptionDescription.of(Text.translatable("skyblocker.config.general.itemProtection.protectValuableConsumables.@Tooltip")))
+ .binding(defaults.general.itemProtection.protectValuableConsumables,
+ () -> config.general.itemProtection.protectValuableConsumables,
+ newValue -> config.general.itemProtection.protectValuableConsumables = newValue)
+ .controller(ConfigUtils::createBooleanController)
+ .build())
.build())
//Wiki Lookup
@@ -379,24 +387,24 @@ public class GeneralCategory {
.build())
.build())
- //Hitboxes
- .group(OptionGroup.createBuilder()
- .name(Text.translatable("skyblocker.config.general.hitbox"))
- .collapsed(true)
- .option(Option.<Boolean>createBuilder()
- .name(Text.translatable("skyblocker.config.general.hitbox.oldFarmlandHitbox"))
- .binding(defaults.general.hitbox.oldFarmlandHitbox,
- () -> config.general.hitbox.oldFarmlandHitbox,
- newValue -> config.general.hitbox.oldFarmlandHitbox = newValue)
- .controller(ConfigUtils::createBooleanController)
- .build())
- .option(Option.<Boolean>createBuilder()
- .name(Text.translatable("skyblocker.config.general.hitbox.oldLeverHitbox"))
- .binding(defaults.general.hitbox.oldLeverHitbox,
- () -> config.general.hitbox.oldLeverHitbox,
- newValue -> config.general.hitbox.oldLeverHitbox = newValue)
- .controller(ConfigUtils::createBooleanController)
- .build())
+ //Hitboxes
+ .group(OptionGroup.createBuilder()
+ .name(Text.translatable("skyblocker.config.general.hitbox"))
+ .collapsed(true)
+ .option(Option.<Boolean>createBuilder()
+ .name(Text.translatable("skyblocker.config.general.hitbox.oldFarmlandHitbox"))
+ .binding(defaults.general.hitbox.oldFarmlandHitbox,
+ () -> config.general.hitbox.oldFarmlandHitbox,
+ newValue -> config.general.hitbox.oldFarmlandHitbox = newValue)
+ .controller(ConfigUtils::createBooleanController)
+ .build())
+ .option(Option.<Boolean>createBuilder()
+ .name(Text.translatable("skyblocker.config.general.hitbox.oldLeverHitbox"))
+ .binding(defaults.general.hitbox.oldLeverHitbox,
+ () -> config.general.hitbox.oldLeverHitbox,
+ newValue -> config.general.hitbox.oldLeverHitbox = newValue)
+ .controller(ConfigUtils::createBooleanController)
+ .build())
.option(Option.<Boolean>createBuilder()
.name(Text.translatable("skyblocker.config.general.hitbox.oldMushroomHitbox"))
.binding(defaults.general.hitbox.oldMushroomHitbox,
@@ -404,8 +412,8 @@ public class GeneralCategory {
newValue -> config.general.hitbox.oldMushroomHitbox = newValue)
.controller(ConfigUtils::createBooleanController)
.build())
- .build())
+ .build())
- .build();
- }
+ .build();
+ }
}
diff --git a/src/main/java/de/hysky/skyblocker/config/configs/GeneralConfig.java b/src/main/java/de/hysky/skyblocker/config/configs/GeneralConfig.java
index e79ea878..2605d5ef 100644
--- a/src/main/java/de/hysky/skyblocker/config/configs/GeneralConfig.java
+++ b/src/main/java/de/hysky/skyblocker/config/configs/GeneralConfig.java
@@ -195,29 +195,32 @@ public class GeneralConfig {
@SerialEntry
public boolean attributeShardInfo = true;
- @SerialEntry
- public boolean itemRarityBackgrounds = true;
+ @SerialEntry
+ public ItemBackgroundStyle itemBackgroundStyle = ItemBackgroundStyle.SQUARE;
- @SerialEntry
- public RarityBackgroundStyle itemRarityBackgroundStyle = RarityBackgroundStyle.SQUARE;
+ @SerialEntry
+ public float itemBackgroundOpacity = 0.5f;
@SerialEntry
- public float itemRarityBackgroundsOpacity = 1f;
+ public boolean itemRarityBackgrounds = true;
+
+ @SerialEntry
+ public boolean jacobMedalBackgrounds = true;
}
- public enum RarityBackgroundStyle {
- CIRCULAR(Identifier.of(SkyblockerMod.NAMESPACE, "item_rarity_background_circular")),
- SQUARE(Identifier.of(SkyblockerMod.NAMESPACE, "item_rarity_background_square"));
+ public enum ItemBackgroundStyle {
+ CIRCULAR(Identifier.of(SkyblockerMod.NAMESPACE, "item_background_circular")),
+ SQUARE(Identifier.of(SkyblockerMod.NAMESPACE, "item_background_square"));
public final Identifier tex;
- RarityBackgroundStyle(Identifier tex) {
+ ItemBackgroundStyle(Identifier tex) {
this.tex = tex;
}
@Override
public String toString() {
- return I18n.translate("skyblocker.config.general.itemInfoDisplay.itemRarityBackgroundStyle.style." + name());
+ return I18n.translate("skyblocker.config.general.itemInfoDisplay.itemBackgroundStyle.style." + name());
}
}
diff --git a/src/main/java/de/hysky/skyblocker/mixins/HandledScreenMixin.java b/src/main/java/de/hysky/skyblocker/mixins/HandledScreenMixin.java
index f3707406..d5734e63 100644
--- a/src/main/java/de/hysky/skyblocker/mixins/HandledScreenMixin.java
+++ b/src/main/java/de/hysky/skyblocker/mixins/HandledScreenMixin.java
@@ -11,6 +11,7 @@ import de.hysky.skyblocker.skyblock.experiment.SuperpairsSolver;
import de.hysky.skyblocker.skyblock.experiment.UltrasequencerSolver;
import de.hysky.skyblocker.skyblock.garden.visitor.VisitorHelper;
import de.hysky.skyblocker.skyblock.item.*;
+import de.hysky.skyblocker.skyblock.item.background.ItemBackgroundManager;
import de.hysky.skyblocker.skyblock.item.slottext.SlotTextManager;
import de.hysky.skyblocker.skyblock.item.tooltip.BackpackPreview;
import de.hysky.skyblocker.skyblock.item.tooltip.CompactorDeletorPreview;
@@ -329,12 +330,15 @@ public abstract class HandledScreenMixin<T extends ScreenHandler> extends Screen
@Inject(method = "drawSlot", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawItem(Lnet/minecraft/item/ItemStack;III)V"))
private void skyblocker$drawOnItem(DrawContext context, Slot slot, CallbackInfo ci) {
- if (Utils.isOnSkyblock() && SkyblockerConfigManager.get().general.itemInfoDisplay.itemRarityBackgrounds)
- ItemRarityBackgrounds.tryDraw(slot.getStack(), context, slot.x, slot.y);
+ if (Utils.isOnSkyblock()) {
+ ItemBackgroundManager.drawBackgrounds(slot.getStack(), context, slot.x, slot.y);
+ }
+
// Item Protection
if (ItemProtection.isItemProtected(slot.getStack())) {
context.drawTexture(RenderLayer::getGuiTextured, ItemProtection.ITEM_PROTECTION_TEX, slot.x, slot.y, 0, 0, 16, 16, 16, 16);
}
+
// Search
// Darken the slots
if (InventorySearch.isSearching() && !InventorySearch.slotMatches(slot)) {
diff --git a/src/main/java/de/hysky/skyblocker/mixins/InGameHudMixin.java b/src/main/java/de/hysky/skyblocker/mixins/InGameHudMixin.java
index d9520ce4..192cfedd 100644
--- a/src/main/java/de/hysky/skyblocker/mixins/InGameHudMixin.java
+++ b/src/main/java/de/hysky/skyblocker/mixins/InGameHudMixin.java
@@ -8,7 +8,7 @@ import de.hysky.skyblocker.skyblock.fancybars.FancyStatusBars;
import de.hysky.skyblocker.skyblock.item.HotbarSlotLock;
import de.hysky.skyblocker.skyblock.item.ItemCooldowns;
import de.hysky.skyblocker.skyblock.item.ItemProtection;
-import de.hysky.skyblocker.skyblock.item.ItemRarityBackgrounds;
+import de.hysky.skyblocker.skyblock.item.background.ItemBackgroundManager;
import de.hysky.skyblocker.skyblock.tabhud.TabHud;
import de.hysky.skyblocker.skyblock.tabhud.config.WidgetsConfigurationScreen;
import de.hysky.skyblocker.utils.Utils;
@@ -52,13 +52,15 @@ public abstract class InGameHudMixin {
private MinecraftClient client;
@Inject(method = "renderHotbar", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/hud/InGameHud;renderHotbarItem(Lnet/minecraft/client/gui/DrawContext;IILnet/minecraft/client/render/RenderTickCounter;Lnet/minecraft/entity/player/PlayerEntity;Lnet/minecraft/item/ItemStack;I)V", ordinal = 0))
- public void skyblocker$renderHotbarItemLockOrRarityBg(CallbackInfo ci, @Local(argsOnly = true) DrawContext context, @Local(ordinal = 4, name = "m") int index, @Local(ordinal = 5, name = "n") int x, @Local(ordinal = 6, name = "o") int y, @Local PlayerEntity player) {
+ public void skyblocker$renderHotbarItemLockOrBackground(CallbackInfo ci, @Local(argsOnly = true) DrawContext context, @Local(ordinal = 4, name = "m") int index, @Local(ordinal = 5, name = "n") int x, @Local(ordinal = 6, name = "o") int y, @Local PlayerEntity player) {
if (Utils.isOnSkyblock()) {
- // slot lock
- if (SkyblockerConfigManager.get().general.itemInfoDisplay.itemRarityBackgrounds) ItemRarityBackgrounds.tryDraw(player.getInventory().getMainStacks().get(index), context, x, y);
+ ItemBackgroundManager.drawBackgrounds(player.getInventory().getMainStacks().get(index), context, x, y);
+
+ // slot lock
if (HotbarSlotLock.isLocked(index)) {
context.drawTexture(RenderLayer::getGuiTextured, SLOT_LOCK_ICON.get(), x, y, 0, 0, 16, 16, 16, 16);
}
+
//item protection
if (ItemProtection.isItemProtected(player.getInventory().getMainStacks().get(index))) {
context.drawTexture(RenderLayer::getGuiTextured, ItemProtection.ITEM_PROTECTION_TEX, x, y, 0, 0, 16, 16, 16, 16);
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/auction/widgets/RarityWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/auction/widgets/RarityWidget.java
index 483fd458..0f4b309b 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/auction/widgets/RarityWidget.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/auction/widgets/RarityWidget.java
@@ -2,8 +2,8 @@ package de.hysky.skyblocker.skyblock.auction.widgets;
import de.hysky.skyblocker.SkyblockerMod;
import de.hysky.skyblocker.skyblock.auction.SlotClickHandler;
-import de.hysky.skyblocker.skyblock.item.ItemRarityBackgrounds;
import de.hysky.skyblocker.skyblock.item.SkyblockItemRarity;
+import de.hysky.skyblocker.skyblock.item.background.adders.ItemRarityBackground;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.DrawContext;
@@ -84,7 +84,7 @@ public class RarityWidget extends ClickableWidget {
public void setText(List<Text> tooltip, String current) {
this.tooltip = tooltip;
this.current = current;
- for (Map.Entry<String, SkyblockItemRarity> rarity : ItemRarityBackgrounds.LORE_RARITIES.entrySet()) {
+ for (Map.Entry<String, SkyblockItemRarity> rarity : ItemRarityBackground.LORE_RARITIES.entrySet()) {
if (current.toUpperCase().contains(rarity.getKey())) {
this.color = rarity.getValue().color | 0xFF000000;
return;
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/ItemRarityBackgrounds.java b/src/main/java/de/hysky/skyblocker/skyblock/item/ItemRarityBackgrounds.java
deleted file mode 100644
index e778191f..00000000
--- a/src/main/java/de/hysky/skyblocker/skyblock/item/ItemRarityBackgrounds.java
+++ /dev/null
@@ -1,105 +0,0 @@
-package de.hysky.skyblocker.skyblock.item;
-
-import com.google.common.collect.ImmutableMap;
-import de.hysky.skyblocker.annotations.Init;
-import de.hysky.skyblocker.config.SkyblockerConfigManager;
-import de.hysky.skyblocker.config.configs.GeneralConfig;
-import de.hysky.skyblocker.utils.ItemUtils;
-import de.hysky.skyblocker.utils.Utils;
-import de.hysky.skyblocker.utils.scheduler.Scheduler;
-import it.unimi.dsi.fastutil.ints.Int2ReferenceOpenHashMap;
-import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents;
-import net.minecraft.client.MinecraftClient;
-import net.minecraft.client.gui.DrawContext;
-import net.minecraft.client.render.RenderLayer;
-import net.minecraft.client.texture.Sprite;
-import net.minecraft.item.ItemStack;
-import net.minecraft.text.Text;
-import net.minecraft.util.math.ColorHelper;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.function.Supplier;
-
-public class ItemRarityBackgrounds {
- private static final GeneralConfig.ItemInfoDisplay CONFIG = SkyblockerConfigManager.get().general.itemInfoDisplay;
- private static final Supplier<Sprite> SPRITE = () -> MinecraftClient.getInstance().getGuiAtlasManager().getSprite(CONFIG.itemRarityBackgroundStyle.tex);
- public static final ImmutableMap<String, SkyblockItemRarity> LORE_RARITIES = ImmutableMap.ofEntries(
- Map.entry("ADMIN", SkyblockItemRarity.ADMIN),
- Map.entry("ULTIMATE", SkyblockItemRarity.ULTIMATE),
- Map.entry("SPECIAL", SkyblockItemRarity.SPECIAL), //Very special is the same color so this will cover it
- Map.entry("DIVINE", SkyblockItemRarity.DIVINE),
- Map.entry("MYTHIC", SkyblockItemRarity.MYTHIC),
- Map.entry("LEGENDARY", SkyblockItemRarity.LEGENDARY),
- Map.entry("LEGENJERRY", SkyblockItemRarity.LEGENDARY),
- Map.entry("EPIC", SkyblockItemRarity.EPIC),
- Map.entry("RARE", SkyblockItemRarity.RARE),
- Map.entry("UNCOMMON", SkyblockItemRarity.UNCOMMON),
- Map.entry("COMMON", SkyblockItemRarity.COMMON));
- private static final Int2ReferenceOpenHashMap<SkyblockItemRarity> CACHE = new Int2ReferenceOpenHashMap<>();
-
- @Init
- public static void init() {
- //Clear the cache every 5 minutes, ints are very compact!
- Scheduler.INSTANCE.scheduleCyclic(CACHE::clear, 4800);
-
- //Clear cache after a screen where items can be upgraded in rarity closes
- ScreenEvents.BEFORE_INIT.register((client, screen, scaledWidth, scaledHeight) -> {
- String title = screen.getTitle().getString();
-
- if (Utils.isOnSkyblock() && (title.contains("The Hex") || title.equals("Craft Item") || title.equals("Anvil") || title.equals("Reforge Anvil"))) {
- ScreenEvents.remove(screen).register(screen1 -> CACHE.clear());
- }
- });
- }
-
- public static void tryDraw(ItemStack stack, DrawContext context, int x, int y) {
- SkyblockItemRarity itemRarity = getItemRarity(stack);
- if (itemRarity != null)
- draw(context, x, y, itemRarity);
- }
-
- private static SkyblockItemRarity getItemRarity(ItemStack stack) {
- if (stack == null || stack.isEmpty()) return null;
-
- String itemUuid = stack.getUuid();
-
- //If the item has an uuid, then use the hash code of the uuid otherwise use the identity hash code of the stack
- int hashCode = itemUuid.isEmpty() ? System.identityHashCode(stack) : itemUuid.hashCode();
-
- if (CACHE.containsKey(hashCode)) return CACHE.get(hashCode);
-
- //For regular items check the lore, for pets we use the rarity in the petInfo so that the rarity background work in the pets menu
- if (!stack.getSkyblockId().equals("PET")) {
- List<Text> lore = ItemUtils.getLore(stack);
- String[] stringifiedTooltip = lore.stream().map(Text::getString).toArray(String[]::new);
-
- for (String rarityString : LORE_RARITIES.keySet()) {
- if (Arrays.stream(stringifiedTooltip).anyMatch(line -> line.contains(rarityString))) {
- SkyblockItemRarity rarity = LORE_RARITIES.get(rarityString);
-
- CACHE.put(hashCode, rarity);
- return rarity;
- }
- }
- } else {
- PetInfo info = stack.getPetInfo();
- if (!info.isEmpty()) {
- SkyblockItemRarity rarity = info.rarity();
- if (info.item().isPresent() && info.item().get().equals("PET_ITEM_TIER_BOOST")) {
- rarity = rarity.next();
- }
- CACHE.put(hashCode, rarity);
- return rarity;
- }
- }
-
- CACHE.put(hashCode, null);
- return null;
- }
-
- private static void draw(DrawContext context, int x, int y, SkyblockItemRarity rarity) {
- context.drawSpriteStretched(RenderLayer::getGuiTextured, SPRITE.get(), x, y, 16, 16, ColorHelper.fromFloats(SkyblockerConfigManager.get().general.itemInfoDisplay.itemRarityBackgroundsOpacity, rarity.r, rarity.g, rarity.b));
- }
-}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/background/ColoredItemBackground.java b/src/main/java/de/hysky/skyblocker/skyblock/item/background/ColoredItemBackground.java
new file mode 100644
index 00000000..9c69ca78
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/skyblock/item/background/ColoredItemBackground.java
@@ -0,0 +1,102 @@
+package de.hysky.skyblocker.skyblock.item.background;
+
+import de.hysky.skyblocker.config.SkyblockerConfigManager;
+import it.unimi.dsi.fastutil.ints.Int2ReferenceOpenHashMap;
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.gui.DrawContext;
+import net.minecraft.client.gui.screen.Screen;
+import net.minecraft.client.texture.Sprite;
+import net.minecraft.item.ItemStack;
+
+import java.util.function.Supplier;
+
+/**
+ * Base class for rendering colored backgrounds behind Minecraft items.
+ * Subclasses should implement {@link #getColorKey}, {@link #draw}, and optionally
+ * {@link #onScreenChange} and {@link #isEnabled} for per-background logic.
+ *
+ * @param <T> The key type used to determine what color to render, e.g. an enum or Integer RGB.
+ */
+public abstract class ColoredItemBackground<T> {
+
+ private final Int2ReferenceOpenHashMap<T> cache = new Int2ReferenceOpenHashMap<>();
+ private final Supplier<Sprite> sprite;
+
+ protected ColoredItemBackground() {
+ this.sprite = () -> MinecraftClient.getInstance()
+ .getGuiAtlasManager()
+ .getSprite(SkyblockerConfigManager.get().general.itemInfoDisplay.itemBackgroundStyle.tex);
+ }
+
+ /**
+ * Called when a new screen is initialized. Subclasses can use this to register
+ * screen-specific behavior when the screen is opened.
+ *
+ * @param title The screen's title text
+ * @param screen The {@link Screen screen} instance itself
+ */
+ protected void onScreenChange(String title, Screen screen) {
+ // Default implementation does nothing
+ }
+
+ /**
+ * Determines the color key (e.g. {@link de.hysky.skyblocker.skyblock.item.SkyblockItemRarity} enum or RGB int)
+ * to use for the given item.
+ *
+ * @param stack The item to inspect
+ * @param cache The internal cache used to store/reuse results
+ * @return A non-null color key if a background should be drawn, or null to skip rendering
+ */
+ protected abstract T getColorKey(ItemStack stack, Int2ReferenceOpenHashMap<T> cache);
+
+ /**
+ * Performs the actual background rendering using the resolved color key.
+ *
+ * @param context The rendering context
+ * @param x Slot x position
+ * @param y Slot y position
+ * @param colorKey The color key, e.g. an enum or RGB integer
+ */
+ protected abstract void draw(DrawContext context, int x, int y, T colorKey);
+
+ /**
+ * Whether this background renderer is enabled.
+ *
+ * @return True if the background should be rendered, false otherwise.
+ */
+ public boolean isEnabled() {
+ return true;
+ }
+
+ /**
+ * Attempts to draw a background for the given {@link ItemStack} if a valid color
+ * key is found.
+ *
+ * @param stack The {@link ItemStack} to check
+ * @param context The rendering context
+ * @param x The slot's x position
+ * @param y The slot's y position
+ */
+ public final void tryDraw(ItemStack stack, DrawContext context, int x, int y) {
+ T value = getColorKey(stack, cache);
+ if (value != null) {
+ draw(context, x, y, value);
+ }
+ }
+
+ /**
+ * Clears the internal cache manually.
+ */
+ protected final void clearCache() {
+ cache.clear();
+ }
+
+ /**
+ * Returns the current background sprite for this renderer.
+ *
+ * @return The sprite to render with
+ */
+ protected final Sprite getSprite() {
+ return sprite.get();
+ }
+}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/background/ItemBackgroundManager.java b/src/main/java/de/hysky/skyblocker/skyblock/item/background/ItemBackgroundManager.java
new file mode 100644
index 00000000..aa23ef79
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/skyblock/item/background/ItemBackgroundManager.java
@@ -0,0 +1,52 @@
+package de.hysky.skyblocker.skyblock.item.background;
+
+import de.hysky.skyblocker.annotations.Init;
+import de.hysky.skyblocker.skyblock.item.background.adders.ItemRarityBackground;
+import de.hysky.skyblocker.skyblock.item.background.adders.JacobMedalBackground;
+import de.hysky.skyblocker.utils.scheduler.Scheduler;
+import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents;
+import net.minecraft.client.gui.DrawContext;
+import net.minecraft.item.ItemStack;
+
+import java.util.List;
+
+public class ItemBackgroundManager {
+
+ private static final List<ColoredItemBackground<?>> BACKGROUNDS = List.of(
+ new ItemRarityBackground(),
+ new JacobMedalBackground()
+ );
+
+ @Init
+ public static void init() {
+ // Clear the cache of every background every 5 minutes
+ for (ColoredItemBackground<?> background : BACKGROUNDS) {
+ Scheduler.INSTANCE.scheduleCyclic(background::clearCache, 6000);
+ }
+
+ // Hook into screen changes for per-background logic
+ ScreenEvents.BEFORE_INIT.register((client, screen, width, height) -> {
+ String title = screen.getTitle().getString();
+
+ for (ColoredItemBackground<?> background : BACKGROUNDS) {
+ background.onScreenChange(title, screen);
+ }
+ });
+ }
+
+ /**
+ * Attempts to draw all enabled item backgrounds on a single {@link ItemStack}.
+ *
+ * @param stack The {@link ItemStack} to check
+ * @param context The {@link DrawContext} to use for rendering
+ * @param x X position of the item
+ * @param y Y position of the item
+ */
+ public static void drawBackgrounds(ItemStack stack, DrawContext context, int x, int y) {
+ for (ColoredItemBackground<?> background : BACKGROUNDS) {
+ if (background.isEnabled()) {
+ background.tryDraw(stack, context, x, y);
+ }
+ }
+ }
+}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/background/adders/ItemRarityBackground.java b/src/main/java/de/hysky/skyblocker/skyblock/item/background/adders/ItemRarityBackground.java
new file mode 100644
index 00000000..54b72d52
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/skyblock/item/background/adders/ItemRarityBackground.java
@@ -0,0 +1,99 @@
+package de.hysky.skyblocker.skyblock.item.background.adders;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import de.hysky.skyblocker.config.SkyblockerConfigManager;
+import de.hysky.skyblocker.skyblock.item.PetInfo;
+import de.hysky.skyblocker.skyblock.item.SkyblockItemRarity;
+import de.hysky.skyblocker.skyblock.item.background.ColoredItemBackground;
+import de.hysky.skyblocker.utils.ItemUtils;
+import de.hysky.skyblocker.utils.Utils;
+import it.unimi.dsi.fastutil.ints.Int2ReferenceOpenHashMap;
+import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents;
+import net.minecraft.client.gui.DrawContext;
+import net.minecraft.client.gui.screen.Screen;
+import net.minecraft.client.render.RenderLayer;
+import net.minecraft.item.ItemStack;
+import net.minecraft.text.Text;
+import net.minecraft.util.math.ColorHelper;
+
+import java.util.List;
+import java.util.Map;
+import java.util.function.Predicate;
+
+public class ItemRarityBackground extends ColoredItemBackground<SkyblockItemRarity> {
+
+ public static final ImmutableMap<String, SkyblockItemRarity> LORE_RARITIES = ImmutableMap.ofEntries(
+ Map.entry("ADMIN", SkyblockItemRarity.ADMIN),
+ Map.entry("ULTIMATE", SkyblockItemRarity.ULTIMATE),
+ Map.entry("SPECIAL", SkyblockItemRarity.SPECIAL), //Very special is the same color so this will cover it
+ Map.entry("DIVINE", SkyblockItemRarity.DIVINE),
+ Map.entry("MYTHIC", SkyblockItemRarity.MYTHIC),
+ Map.entry("LEGENDARY", SkyblockItemRarity.LEGENDARY),
+ Map.entry("LEGENJERRY", SkyblockItemRarity.LEGENDARY),
+ Map.entry("EPIC", SkyblockItemRarity.EPIC),
+ Map.entry("RARE", SkyblockItemRarity.RARE),
+ Map.entry("UNCOMMON", SkyblockItemRarity.UNCOMMON),
+ Map.entry("COMMON", SkyblockItemRarity.COMMON)
+ );
+
+ private static final ImmutableList<Predicate<String>> INVENTORY_TITLES = ImmutableList.of(
+ title -> title.contains("The Hex"),
+ title -> title.equals("Craft Item"),
+ title -> title.equals("Anvil"),
+ title -> title.equals("Reforge Anvil")
+ );
+
+ @Override
+ public boolean isEnabled() {
+ return SkyblockerConfigManager.get().general.itemInfoDisplay.itemRarityBackgrounds;
+ }
+
+ @Override
+ protected SkyblockItemRarity getColorKey(ItemStack stack, Int2ReferenceOpenHashMap<SkyblockItemRarity> cache) {
+ if (stack == null || stack.isEmpty()) return null;
+
+ int hashCode = stack.getUuid().isEmpty() ? System.identityHashCode(stack) : stack.getUuid().hashCode();
+ if (cache.containsKey(hashCode)) return cache.get(hashCode);
+
+ if (!stack.getSkyblockId().equals("PET")) {
+ List<Text> lore = ItemUtils.getLore(stack);
+ List<String> tooltip = lore.stream().map(Text::getString).toList();
+ for (String key : LORE_RARITIES.keySet()) {
+ if (tooltip.stream().anyMatch(line -> line.contains(key))) {
+ SkyblockItemRarity rarity = LORE_RARITIES.get(key);
+ cache.put(hashCode, rarity);
+ return rarity;
+ }
+ }
+ } else {
+ PetInfo info = stack.getPetInfo();
+ if (!info.isEmpty()) {
+ SkyblockItemRarity rarity = info.item().isPresent() && info.item().get().equals("PET_ITEM_TIER_BOOST") ? info.rarity().next() : info.rarity();
+ cache.put(hashCode, rarity);
+ return rarity;
+ }
+ }
+
+ cache.put(hashCode, null);
+ return null;
+ }
+
+ @Override
+ protected void draw(DrawContext context, int x, int y, SkyblockItemRarity rarity) {
+ context.drawSpriteStretched(RenderLayer::getGuiTextured, getSprite(), x, y, 16, 16,
+ ColorHelper.fromFloats(
+ SkyblockerConfigManager.get().general.itemInfoDisplay.itemBackgroundOpacity,
+ rarity.r, rarity.g, rarity.b
+ )
+ );
+ }
+
+ @Override
+ protected void onScreenChange(String title, Screen screen) {
+ if (Utils.isOnSkyblock() && INVENTORY_TITLES.stream().anyMatch(predicate -> predicate.test(title))) {
+ ScreenEvents.remove(screen).register(s -> clearCache());
+ }
+ }
+}
+
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/background/adders/JacobMedalBackground.java b/src/main/java/de/hysky/skyblocker/skyblock/item/background/adders/JacobMedalBackground.java
new file mode 100644
index 00000000..b340ffa2
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/skyblock/item/background/adders/JacobMedalBackground.java
@@ -0,0 +1,71 @@
+package de.hysky.skyblocker.skyblock.item.background.adders;
+
+import de.hysky.skyblocker.config.SkyblockerConfigManager;
+import de.hysky.skyblocker.skyblock.item.background.ColoredItemBackground;
+import de.hysky.skyblocker.utils.ItemUtils;
+import it.unimi.dsi.fastutil.ints.Int2ReferenceOpenHashMap;
+import net.minecraft.client.gui.DrawContext;
+import net.minecraft.client.render.RenderLayer;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.Formatting;
+import net.minecraft.util.math.ColorHelper;
+
+import java.util.Map;
+import java.util.Objects;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class