Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ protected void init() {

if (categoryTabWidgets.isEmpty())
for (int i = 0; i < 6; i++) {
CategoryTabWidget categoryTabWidget = new CategoryTabWidget(new ItemStack(Items.SPONGE), this::clickSlot);
CategoryTabWidget categoryTabWidget = new CategoryTabWidget(new ItemStack(Items.SPONGE), this::clickSlot, i);
categoryTabWidgets.add(categoryTabWidget);
addWidget(categoryTabWidget); // This method only makes it clickable, does not add it to the drawables list
// manually rendered in the render method to have it not render behind the durability bars
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,38 @@
package de.hysky.skyblocker.skyblock.auction.widgets;

import de.hysky.skyblocker.SkyblockerMod;
import de.hysky.skyblocker.skyblock.auction.SlotClickHandler;
import de.hysky.skyblocker.utils.render.gui.SideTabButtonWidget;
import de.hysky.skyblocker.utils.render.texture.FallbackedTexture;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.components.WidgetSprites;
import net.minecraft.client.gui.screens.recipebook.RecipeBookTabButton;
import net.minecraft.client.input.MouseButtonEvent;
import net.minecraft.world.item.Item.TooltipContext;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.TooltipFlag;
import org.jspecify.annotations.Nullable;

public class CategoryTabWidget extends SideTabButtonWidget {
@SuppressWarnings("unchecked")
private static final @Nullable FallbackedTexture<WidgetSprites>[] SPRITES = new FallbackedTexture[6];
private final SlotClickHandler slotClick;
private int slotId = -1;

public CategoryTabWidget(ItemStack icon, SlotClickHandler slotClick) {
super(0, 0, false, icon);
private static WidgetSprites getSprites(int index) {
FallbackedTexture<WidgetSprites> sprite = SPRITES[index];
if (sprite == null) return (SPRITES[index] = FallbackedTexture.ofWidgetSprites(
new WidgetSprites(
SkyblockerMod.id("auctions_gui/category_tab_" + (index + 1)),
SkyblockerMod.id("auctions_gui/category_tab_selected" + (index + 1))
),
RecipeBookTabButton.SPRITES)).get();
return sprite.get();
}

public CategoryTabWidget(ItemStack icon, SlotClickHandler slotClick, int id) {
super(0, 0, false, getSprites(id), icon);
this.slotClick = slotClick;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import de.hysky.skyblocker.annotations.Init;
import de.hysky.skyblocker.debug.Debug;
import de.hysky.skyblocker.utils.ItemUtils;
import de.hysky.skyblocker.utils.render.texture.FallbackedTexture;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
import net.minecraft.ChatFormatting;
import net.minecraft.client.Minecraft;
Expand Down Expand Up @@ -46,7 +47,9 @@

public class PartyFinderScreen extends Screen {
protected static final Logger LOGGER = LoggerFactory.getLogger(PartyFinderScreen.class);
protected static final Identifier BACKGROUND_TEXTURE = Identifier.withDefaultNamespace("social_interactions/background");
protected static final FallbackedTexture<Identifier> BACKGROUND_TEXTURE = FallbackedTexture.ofGuiSprite(
SkyblockerMod.id("party_finder/background"),
Identifier.withDefaultNamespace("social_interactions/background"));
protected static final Identifier SEARCH_ICON_TEXTURE = Identifier.withDefaultNamespace("icon/search");
protected static final Component SEARCH_TEXT = Component.translatable("gui.socialInteractions.search_hint").withStyle(ChatFormatting.ITALIC).withStyle(ChatFormatting.GRAY);
public static boolean isInKuudraPartyFinder = false;
Expand Down Expand Up @@ -284,7 +287,7 @@ public void render(GuiGraphics context, int mouseX, int mouseY, float delta) {
public void renderBackground(GuiGraphics context, int mouseX, int mouseY, float delta) {
this.renderTransparentBackground(context);
int i = partyEntryListWidget.getRowWidth() + 16 + 6;
context.blitSprite(RenderPipelines.GUI_TEXTURED, BACKGROUND_TEXTURE, partyEntryListWidget.getRowLeft() - 8, partyEntryListWidget.getY() - 12 - 8, i, partyEntryListWidget.getBottom() - partyEntryListWidget.getY() + 16 + 12);
context.blitSprite(RenderPipelines.GUI_TEXTURED, BACKGROUND_TEXTURE.get(), partyEntryListWidget.getRowLeft() - 8, partyEntryListWidget.getY() - 12 - 8, i, partyEntryListWidget.getBottom() - partyEntryListWidget.getY() + 16 + 12);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import de.hysky.skyblocker.SkyblockerMod;
import de.hysky.skyblocker.skyblock.itemlist.recipebook.SkyblockRecipeBookWidget;
import java.time.Duration;

import de.hysky.skyblocker.utils.render.texture.FallbackedTexture;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.components.ImageButton;
import net.minecraft.client.gui.components.Tooltip;
Expand All @@ -20,7 +22,12 @@
import net.minecraft.world.item.Items;

public class SkyblockCraftingTableScreen extends AbstractContainerScreen<SkyblockCraftingTableScreenHandler> {
private static final Identifier TEXTURE = Identifier.withDefaultNamespace("textures/gui/container/crafting_table.png");
private static final FallbackedTexture<Identifier> TEXTURE = FallbackedTexture.ofTexture(
SkyblockerMod.id("textures/gui/container/skyblock_crafting_table.png"),
Identifier.withDefaultNamespace("textures/gui/container/crafting_table.png"));
private static final FallbackedTexture<Identifier> MIRRORVERSE_TEXTURE = FallbackedTexture.ofTexture(
SkyblockerMod.id("textures/gui/container/skyblock_crafting_table.png"),
Identifier.withDefaultNamespace("textures/gui/container/crafting_table.png"));
protected static final WidgetSprites MORE_CRAFTS_TEXTURES = new WidgetSprites(
SkyblockerMod.id("quick_craft/more_button"),
SkyblockerMod.id("quick_craft/more_button_disabled"),
Expand Down Expand Up @@ -96,9 +103,9 @@ protected void renderSlot(GuiGraphics context, Slot slot, int mouseX, int mouseY
protected void renderBg(GuiGraphics context, float delta, int mouseX, int mouseY) {
int i = this.leftPos;
int j = (this.height - this.imageHeight) / 2;
context.blit(RenderPipelines.GUI_TEXTURED, TEXTURE, i, j, 0, 0, this.imageWidth, this.imageHeight, 256, 256);
context.blit(RenderPipelines.GUI_TEXTURED, menu.mirrorverse ? MIRRORVERSE_TEXTURE.get() : TEXTURE.get(), i, j, 0, 0, this.imageWidth, this.imageHeight, 256, 256);
//4 px of margin to allow some space for custom resource packs that have size differences on the crafting table/inventory textures
if (!menu.mirrorverse) context.blit(RenderPipelines.GUI_TEXTURED, QUICK_CRAFT, i + 143, j - 3, 0, 0, 37, 90, 37, 90);
if (TEXTURE.isUsingFallback() && !menu.mirrorverse) context.blit(RenderPipelines.GUI_TEXTURED, QUICK_CRAFT, i + 143, j - 3, 0, 0, 37, 90, 37, 90);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import de.hysky.skyblocker.skyblock.item.wikilookup.WikiLookupManager;
import de.hysky.skyblocker.utils.ItemUtils;
import de.hysky.skyblocker.utils.Utils;
import de.hysky.skyblocker.utils.render.texture.FallbackedTexture;
import de.hysky.skyblocker.utils.scheduler.MessageScheduler;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
import net.minecraft.client.Minecraft;
Expand Down Expand Up @@ -63,6 +64,9 @@ public class SkyblockInventoryScreen extends InventoryScreen implements HoveredI
private static final Identifier SLOT_TEXTURE = Identifier.withDefaultNamespace("container/slot");
private static final Identifier EMPTY_SLOT = SkyblockerMod.id("equipment/empty_icon");
private static final Path FOLDER = SkyblockerMod.CONFIG_DIR.resolve("equipment");
private static final FallbackedTexture<Identifier> BACKGROUND = FallbackedTexture.ofTexture(
SkyblockerMod.id("textures/gui/container/skyblock_inventory.png"),
INVENTORY_LOCATION);

private final Slot[] equipmentSlots = new Slot[4];
private ItemStack hoveredItem;
Expand Down Expand Up @@ -189,7 +193,15 @@ public void removed() {

@Override
protected void renderBg(GuiGraphics context, float delta, int mouseX, int mouseY) {
super.renderBg(context, delta, mouseX, mouseY);
if (BACKGROUND.isUsingFallback()) {
super.renderBg(context, delta, mouseX, mouseY);
} else {
int x = this.leftPos;
int y = this.topPos;
context.blit(RenderPipelines.GUI_TEXTURED, BACKGROUND.get(), x, y, 0.0F, 0.0F, this.imageWidth, this.imageHeight, 256, 256);
renderEntityInInventoryFollowsMouse(context, x + 26, y + 8, x + 75, y + 78, 30, 0.0625F, mouseX, mouseY, this.minecraft.player);
return;
}
for (int i = 0; i < 3; i++) {
context.blitSprite(RenderPipelines.GUI_TEXTURED, SLOT_TEXTURE, leftPos + 76, topPos + 7 + i * 18, 18, 18);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package de.hysky.skyblocker.skyblock.museum;

import com.google.common.collect.Lists;
import de.hysky.skyblocker.SkyblockerMod;
import de.hysky.skyblocker.utils.hoveredItem.HoveredItemStackProvider;
import com.mojang.datafixers.util.Either;
import de.hysky.skyblocker.skyblock.item.wikilookup.WikiLookupManager;
Expand Down Expand Up @@ -37,7 +38,7 @@
public class MuseumManager extends AbstractWidget implements HoveredItemStackProvider {
private static final Minecraft CLIENT = Minecraft.getInstance();
private static final Font TEXT_RENDERER = CLIENT.font;
private static final Identifier BACKGROUND_TEXTURE = Identifier.withDefaultNamespace("textures/gui/recipe_book.png");
private static final Identifier BACKGROUND_TEXTURE = SkyblockerMod.id("background");
public static final int BACKGROUND_WIDTH = 147;
public static final int BACKGROUND_HEIGHT = 160;
public static final int SPACING = 2;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import de.hysky.skyblocker.mixins.accessors.PopupScreenAccessor;
import de.hysky.skyblocker.utils.Constants;
import de.hysky.skyblocker.utils.render.gui.AbstractPopupScreen;
import de.hysky.skyblocker.utils.render.texture.FallbackedTexture;
import de.hysky.skyblocker.utils.scheduler.MessageScheduler;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
Expand Down Expand Up @@ -36,6 +37,8 @@
@Environment(value = EnvType.CLIENT)
public class QuickNavButton extends AbstractWidget {
private static final long TOGGLE_DURATION = 1000;
@SuppressWarnings("unchecked")
private static final @Nullable FallbackedTexture<Identifier>[] TAB_TEXTURES = new FallbackedTexture[14];

private final int index;
private final boolean toggled;
Expand Down Expand Up @@ -178,8 +181,7 @@ public void renderWidget(GuiGraphics context, int mouseX, int mouseY, float delt
alpha = Math.min(alpha + 10, 255);
}

// Construct the texture identifier based on the index and toggled state
Identifier tabTexture = Identifier.withDefaultNamespace("container/creative_inventory/tab_" + (isTopTab() ? "top" : "bottom") + "_" + (renderInFront ? "selected" : "unselected") + "_" + (index % 7 + 1));
Identifier tabTexture = getTexture();

// Render the button texture, always with full alpha if it's not rendering in front
context.blitSprite(RenderPipelines.GUI_TEXTURED, tabTexture, this.getX(), this.getY(), this.width, this.height, renderInFront ? ARGB.color(alpha, -1) : -1);
Expand All @@ -190,6 +192,16 @@ public void renderWidget(GuiGraphics context, int mouseX, int mouseY, float delt
this.handleCursor(context);
}

private Identifier getTexture() {
FallbackedTexture<Identifier> texture = TAB_TEXTURES[index];
if (texture != null) return texture.get();
// Construct the texture identifier based on the index and toggled state
return (TAB_TEXTURES[index] = FallbackedTexture.ofGuiSprite(
SkyblockerMod.id("quick_nav/tab_" + (isTopTab() ? "top" : "bottom") + "_" + (renderInFront ? "selected" : "unselected") + "_" + (index % 7 + 1)),
Identifier.withDefaultNamespace("container/creative_inventory/tab_" + (isTopTab() ? "top" : "bottom") + "_" + (renderInFront ? "selected" : "unselected") + "_" + (index % 7 + 1))
)).get();
}

@Override
protected void updateWidgetNarration(NarrationElementOutput builder) {}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package de.hysky.skyblocker.skyblock.searchoverlay;

import de.hysky.skyblocker.SkyblockerMod;
import de.hysky.skyblocker.config.SkyblockerConfigManager;
import de.hysky.skyblocker.utils.render.texture.FallbackedTexture;
import net.minecraft.ChatFormatting;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.components.Button;
Expand All @@ -23,7 +25,9 @@ public class OverlayScreen extends Screen {

protected static final Identifier SEARCH_ICON_TEXTURE = Identifier.withDefaultNamespace("icon/search");
protected static final Identifier DELETE_ICON_TEXTURE = Identifier.withDefaultNamespace("textures/gui/sprites/pending_invite/reject.png");
private static final Identifier BACKGROUND_TEXTURE = Identifier.withDefaultNamespace("social_interactions/background");
private static final FallbackedTexture<Identifier> BACKGROUND_TEXTURE = FallbackedTexture.ofGuiSprite(
SkyblockerMod.id("search_overlay/background"),
Identifier.withDefaultNamespace("social_interactions/background"));
private static final int rowHeight = 20;
private static final int specialButtonSize = rowHeight;
private EditBox searchField;
Expand Down Expand Up @@ -219,7 +223,7 @@ public void renderBackground(GuiGraphics context, int mouseX, int mouseY, float
if (historyButtons.length > 0) { //add space for history label if it could exist
maxHeight += (int) (rowHeight * 0.75);
}
context.blitSprite(RenderPipelines.GUI_TEXTURED, BACKGROUND_TEXTURE, searchField.getX() - 8, searchField.getY() - 8, (int) (this.width * 0.4) + 16, maxHeight + 16);
context.blitSprite(RenderPipelines.GUI_TEXTURED, BACKGROUND_TEXTURE.get(), searchField.getX() - 8, searchField.getY() - 8, (int) (this.width * 0.4) + 16, maxHeight + 16);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.components.ImageButton;
import net.minecraft.client.gui.components.WidgetSprites;
import net.minecraft.client.gui.screens.recipebook.RecipeBookTabButton;
import net.minecraft.client.input.MouseButtonEvent;
import net.minecraft.client.renderer.RenderPipelines;
Expand All @@ -16,14 +17,17 @@ public void setIcon(ItemStack icon) {
this.icon = icon.copy();
}

public SideTabButtonWidget(int x, int y, boolean toggled, ItemStack icon) {
super(x, y, 35, 27, RecipeBookTabButton.SPRITES, _ignored -> {});
public SideTabButtonWidget(int x, int y, boolean toggled, WidgetSprites sprites, ItemStack icon) {
super(x, y, 35, 27, sprites, _ignored -> {});
this.icon = icon.copy();
}

public SideTabButtonWidget(int x, int y, boolean toggled, ItemStack icon) {
this(x, y, toggled, RecipeBookTabButton.SPRITES, icon);
}

@Override
public void renderContents(GuiGraphics context, int mouseX, int mouseY, float delta) {
if (sprites == null) return;
Identifier identifier = sprites.get(true, this.selected);
int x = getX();
if (this.selected) x -= 2;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package de.hysky.skyblocker.utils.render.texture;

import com.mojang.datafixers.util.Unit;
import de.hysky.skyblocker.SkyblockerMod;
import de.hysky.skyblocker.annotations.Init;
import net.fabricmc.fabric.api.resource.v1.ResourceLoader;
import net.fabricmc.fabric.api.resource.v1.reloader.ResourceReloaderKeys;
import net.minecraft.client.gui.components.WidgetSprites;
import net.minecraft.data.AtlasIds;
import net.minecraft.resources.Identifier;
import net.minecraft.server.packs.PackType;
import org.jspecify.annotations.Nullable;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.function.Supplier;

/**
* A texture reference that will default back to another one if it doesn't exist.
*/
public interface FallbackedTexture<T> extends Supplier<T> {
List<Runnable> UPDATE_CALLBACKS = new ArrayList<>();

boolean isUsingFallback();

/**
* @param id the texture that may or may not be specified by a resource pack
* @param fallback the fallback if {@code id} doesn't exist
* @param atlas the to look in, pass null if the texture isn't in any atlas.
* @return a fallbacked texture supplier
*/
static FallbackedTexture<Identifier> of(Identifier id, Identifier fallback, @Nullable Identifier atlas) {
IdentifierTexture identifierTexture = new IdentifierTexture(id, fallback, atlas);
UPDATE_CALLBACKS.add(identifierTexture::update);
return identifierTexture;
}

/**
* For textures in the {@code gui/sprites} folder.
*/
static FallbackedTexture<Identifier> ofGuiSprite(Identifier id, Identifier fallback) {
return of(id, fallback, AtlasIds.GUI);
}

/**
* For textures that aren't in any atlas (usually backgrounds)
*/
static FallbackedTexture<Identifier> ofTexture(Identifier id, Identifier fallback) {
return of(id, fallback, null);
}

/**
* WidgetSprites, used for buttons.
*/
static FallbackedTexture<WidgetSprites> ofWidgetSprites(WidgetSprites sprites, WidgetSprites fallback) {
List<IdentifierTexture> textures = new ArrayList<>(4);
WidgetSpritesFallback.Helper helper = new WidgetSpritesFallback.Helper(sprites, fallback);
helper.populate(textures, WidgetSprites::enabled);
helper.populate(textures, WidgetSprites::disabled);
helper.populate(textures, WidgetSprites::enabledFocused);
helper.populate(textures, WidgetSprites::disabledFocused);
WidgetSpritesFallback spritesFallback = new WidgetSpritesFallback(textures.get(0), textures.get(1), textures.get(2), textures.get(3));
UPDATE_CALLBACKS.add(spritesFallback::update);
return spritesFallback;
}


@Init
static void init() {
Identifier id = SkyblockerMod.id("fallback_texture_reloader");
ResourceLoader.get(PackType.CLIENT_RESOURCES).registerReloader(id,
(sharedState, executor, preparationBarrier, executor2) -> CompletableFuture
.supplyAsync(() -> Unit.INSTANCE, executor)
.thenCompose(preparationBarrier::wait)
.thenAcceptAsync(unit -> UPDATE_CALLBACKS.forEach(Runnable::run)));
ResourceLoader.get(PackType.CLIENT_RESOURCES).addReloaderOrdering(ResourceReloaderKeys.AFTER_VANILLA, id);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package de.hysky.skyblocker.utils.render.texture;

import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.texture.TextureAtlas;
import net.minecraft.resources.Identifier;
import net.minecraft.server.packs.resources.Resource;
import org.jspecify.annotations.Nullable;

import java.util.Optional;

class IdentifierTexture implements FallbackedTexture<Identifier> {

protected final Identifier texture;
protected final Identifier fallback;
private final @Nullable Identifier atlas;
private Identifier currentTexture;

protected IdentifierTexture(Identifier texture, Identifier fallback, @Nullable Identifier atlas) {
this.texture = texture;
this.fallback = fallback;
this.atlas = atlas;
this.currentTexture = texture;
if (Minecraft.getInstance().isGameLoadFinished()) update();
}

@Override
public boolean isUsingFallback() {
return currentTexture == fallback;
}

@Override
public Identifier get() {
return currentTexture;
}

void update() {
Minecraft minecraft = Minecraft.getInstance();
if (atlas != null) {
TextureAtlas textureAtlas = minecraft.getAtlasManager().getAtlasOrThrow(atlas);
if (textureAtlas.missingSprite().equals(textureAtlas.getSprite(texture))) currentTexture = fallback;
else currentTexture = texture;
} else {
Optional<Resource> resource = minecraft.getResourceManager().getResource(texture);
if (resource.isEmpty()) currentTexture = fallback;
else currentTexture = texture;
}
}
}
Loading
Loading