201 lines
8 KiB
Java
201 lines
8 KiB
Java
package net.minecraft.client.gui.screens.inventory.tooltip;
|
|
|
|
import java.util.List;
|
|
import net.fabricmc.api.EnvType;
|
|
import net.fabricmc.api.Environment;
|
|
import net.minecraft.client.gui.Font;
|
|
import net.minecraft.client.gui.GuiGraphics;
|
|
import net.minecraft.client.renderer.RenderType;
|
|
import net.minecraft.core.component.DataComponents;
|
|
import net.minecraft.network.chat.Component;
|
|
import net.minecraft.resources.ResourceLocation;
|
|
import net.minecraft.util.Mth;
|
|
import net.minecraft.world.item.ItemStack;
|
|
import net.minecraft.world.item.component.BundleContents;
|
|
import org.apache.commons.lang3.math.Fraction;
|
|
import org.jetbrains.annotations.Nullable;
|
|
|
|
@Environment(EnvType.CLIENT)
|
|
public class ClientBundleTooltip implements ClientTooltipComponent {
|
|
private static final ResourceLocation PROGRESSBAR_BORDER_SPRITE = ResourceLocation.withDefaultNamespace("container/bundle/bundle_progressbar_border");
|
|
private static final ResourceLocation PROGRESSBAR_FILL_SPRITE = ResourceLocation.withDefaultNamespace("container/bundle/bundle_progressbar_fill");
|
|
private static final ResourceLocation PROGRESSBAR_FULL_SPRITE = ResourceLocation.withDefaultNamespace("container/bundle/bundle_progressbar_full");
|
|
private static final ResourceLocation SLOT_HIGHLIGHT_BACK_SPRITE = ResourceLocation.withDefaultNamespace("container/bundle/slot_highlight_back");
|
|
private static final ResourceLocation SLOT_HIGHLIGHT_FRONT_SPRITE = ResourceLocation.withDefaultNamespace("container/bundle/slot_highlight_front");
|
|
private static final ResourceLocation SLOT_BACKGROUND_SPRITE = ResourceLocation.withDefaultNamespace("container/bundle/slot_background");
|
|
private static final int SLOT_MARGIN = 4;
|
|
private static final int SLOT_SIZE = 24;
|
|
private static final int GRID_WIDTH = 96;
|
|
private static final int PROGRESSBAR_HEIGHT = 13;
|
|
private static final int PROGRESSBAR_WIDTH = 96;
|
|
private static final int PROGRESSBAR_BORDER = 1;
|
|
private static final int PROGRESSBAR_FILL_MAX = 94;
|
|
private static final int PROGRESSBAR_MARGIN_Y = 4;
|
|
private static final Component BUNDLE_FULL_TEXT = Component.translatable("item.minecraft.bundle.full");
|
|
private static final Component BUNDLE_EMPTY_TEXT = Component.translatable("item.minecraft.bundle.empty");
|
|
private static final Component BUNDLE_EMPTY_DESCRIPTION = Component.translatable("item.minecraft.bundle.empty.description");
|
|
private final BundleContents contents;
|
|
|
|
public ClientBundleTooltip(BundleContents contents) {
|
|
this.contents = contents;
|
|
}
|
|
|
|
@Override
|
|
public int getHeight(Font font) {
|
|
return this.contents.isEmpty() ? getEmptyBundleBackgroundHeight(font) : this.backgroundHeight();
|
|
}
|
|
|
|
@Override
|
|
public int getWidth(Font font) {
|
|
return 96;
|
|
}
|
|
|
|
@Override
|
|
public boolean showTooltipWithItemInHand() {
|
|
return true;
|
|
}
|
|
|
|
private static int getEmptyBundleBackgroundHeight(Font font) {
|
|
return getEmptyBundleDescriptionTextHeight(font) + 13 + 8;
|
|
}
|
|
|
|
private int backgroundHeight() {
|
|
return this.itemGridHeight() + 13 + 8;
|
|
}
|
|
|
|
private int itemGridHeight() {
|
|
return this.gridSizeY() * 24;
|
|
}
|
|
|
|
private int getContentXOffset(int width) {
|
|
return (width - 96) / 2;
|
|
}
|
|
|
|
private int gridSizeY() {
|
|
return Mth.positiveCeilDiv(this.slotCount(), 4);
|
|
}
|
|
|
|
private int slotCount() {
|
|
return Math.min(12, this.contents.size());
|
|
}
|
|
|
|
@Override
|
|
public void renderImage(Font font, int x, int y, int width, int height, GuiGraphics guiGraphics) {
|
|
if (this.contents.isEmpty()) {
|
|
this.renderEmptyBundleTooltip(font, x, y, width, height, guiGraphics);
|
|
} else {
|
|
this.renderBundleWithItemsTooltip(font, x, y, width, height, guiGraphics);
|
|
}
|
|
}
|
|
|
|
private void renderEmptyBundleTooltip(Font font, int x, int y, int width, int height, GuiGraphics guiGraphics) {
|
|
drawEmptyBundleDescriptionText(x + this.getContentXOffset(width), y, font, guiGraphics);
|
|
this.drawProgressbar(x + this.getContentXOffset(width), y + getEmptyBundleDescriptionTextHeight(font) + 4, font, guiGraphics);
|
|
}
|
|
|
|
private void renderBundleWithItemsTooltip(Font font, int x, int y, int width, int height, GuiGraphics guiGraphics) {
|
|
boolean bl = this.contents.size() > 12;
|
|
List<ItemStack> list = this.getShownItems(this.contents.getNumberOfItemsToShow());
|
|
int i = x + this.getContentXOffset(width) + 96;
|
|
int j = y + this.gridSizeY() * 24;
|
|
int k = 1;
|
|
|
|
for (int l = 1; l <= this.gridSizeY(); l++) {
|
|
for (int m = 1; m <= 4; m++) {
|
|
int n = i - m * 24;
|
|
int o = j - l * 24;
|
|
if (shouldRenderSurplusText(bl, m, l)) {
|
|
renderCount(n, o, this.getAmountOfHiddenItems(list), font, guiGraphics);
|
|
} else if (shouldRenderItemSlot(list, k)) {
|
|
this.renderSlot(k, n, o, list, k, font, guiGraphics);
|
|
k++;
|
|
}
|
|
}
|
|
}
|
|
|
|
this.drawSelectedItemTooltip(font, guiGraphics, x, y, width);
|
|
this.drawProgressbar(x + this.getContentXOffset(width), y + this.itemGridHeight() + 4, font, guiGraphics);
|
|
}
|
|
|
|
private List<ItemStack> getShownItems(int itemsToShow) {
|
|
int i = Math.min(this.contents.size(), itemsToShow);
|
|
return this.contents.itemCopyStream().toList().subList(0, i);
|
|
}
|
|
|
|
private static boolean shouldRenderSurplusText(boolean hasEnoughItems, int cellX, int cellY) {
|
|
return hasEnoughItems && cellX * cellY == 1;
|
|
}
|
|
|
|
private static boolean shouldRenderItemSlot(List<ItemStack> shownItems, int slotIndex) {
|
|
return shownItems.size() >= slotIndex;
|
|
}
|
|
|
|
private int getAmountOfHiddenItems(List<ItemStack> shownItems) {
|
|
return this.contents.itemCopyStream().skip(shownItems.size()).mapToInt(ItemStack::getCount).sum();
|
|
}
|
|
|
|
private void renderSlot(int slotIndex, int x, int y, List<ItemStack> shownItems, int seed, Font font, GuiGraphics guiGraphics) {
|
|
int i = shownItems.size() - slotIndex;
|
|
boolean bl = i == this.contents.getSelectedItem();
|
|
ItemStack itemStack = (ItemStack)shownItems.get(i);
|
|
if (bl) {
|
|
guiGraphics.blitSprite(RenderType::guiTextured, SLOT_HIGHLIGHT_BACK_SPRITE, x, y, 24, 24);
|
|
} else {
|
|
guiGraphics.blitSprite(RenderType::guiTextured, SLOT_BACKGROUND_SPRITE, x, y, 24, 24);
|
|
}
|
|
|
|
guiGraphics.renderItem(itemStack, x + 4, y + 4, seed);
|
|
guiGraphics.renderItemDecorations(font, itemStack, x + 4, y + 4);
|
|
if (bl) {
|
|
guiGraphics.blitSprite(RenderType::guiTexturedOverlay, SLOT_HIGHLIGHT_FRONT_SPRITE, x, y, 24, 24);
|
|
}
|
|
}
|
|
|
|
private static void renderCount(int slotX, int slotY, int count, Font font, GuiGraphics guiGraphics) {
|
|
guiGraphics.drawCenteredString(font, "+" + count, slotX + 12, slotY + 10, 16777215);
|
|
}
|
|
|
|
private void drawSelectedItemTooltip(Font font, GuiGraphics guiGraphics, int x, int y, int width) {
|
|
if (this.contents.hasSelectedItem()) {
|
|
ItemStack itemStack = this.contents.getItemUnsafe(this.contents.getSelectedItem());
|
|
Component component = itemStack.getStyledHoverName();
|
|
int i = font.width(component.getVisualOrderText());
|
|
int j = x + width / 2 - 12;
|
|
guiGraphics.renderTooltip(font, component, j - i / 2, y - 15, itemStack.get(DataComponents.TOOLTIP_STYLE));
|
|
}
|
|
}
|
|
|
|
private void drawProgressbar(int x, int y, Font font, GuiGraphics guiGraphics) {
|
|
guiGraphics.blitSprite(RenderType::guiTextured, this.getProgressBarTexture(), x + 1, y, this.getProgressBarFill(), 13);
|
|
guiGraphics.blitSprite(RenderType::guiTextured, PROGRESSBAR_BORDER_SPRITE, x, y, 96, 13);
|
|
Component component = this.getProgressBarFillText();
|
|
if (component != null) {
|
|
guiGraphics.drawCenteredString(font, component, x + 48, y + 3, 16777215);
|
|
}
|
|
}
|
|
|
|
private static void drawEmptyBundleDescriptionText(int x, int y, Font font, GuiGraphics guiGraphics) {
|
|
guiGraphics.drawWordWrap(font, BUNDLE_EMPTY_DESCRIPTION, x, y, 96, 11184810);
|
|
}
|
|
|
|
private static int getEmptyBundleDescriptionTextHeight(Font font) {
|
|
return font.split(BUNDLE_EMPTY_DESCRIPTION, 96).size() * 9;
|
|
}
|
|
|
|
private int getProgressBarFill() {
|
|
return Mth.clamp(Mth.mulAndTruncate(this.contents.weight(), 94), 0, 94);
|
|
}
|
|
|
|
private ResourceLocation getProgressBarTexture() {
|
|
return this.contents.weight().compareTo(Fraction.ONE) >= 0 ? PROGRESSBAR_FULL_SPRITE : PROGRESSBAR_FILL_SPRITE;
|
|
}
|
|
|
|
@Nullable
|
|
private Component getProgressBarFillText() {
|
|
if (this.contents.isEmpty()) {
|
|
return BUNDLE_EMPTY_TEXT;
|
|
} else {
|
|
return this.contents.weight().compareTo(Fraction.ONE) >= 0 ? BUNDLE_FULL_TEXT : null;
|
|
}
|
|
}
|
|
}
|