LoomScreen.java

net.minecraft.client.gui.screens.inventory.LoomScreen

信息

  • 全限定名:net.minecraft.client.gui.screens.inventory.LoomScreen
  • 类型:public class
  • 包:net.minecraft.client.gui.screens.inventory
  • 源码路径:src/main/java/net/minecraft/client/gui/screens/inventory/LoomScreen.java
  • 起始行号:L35
  • 继承:AbstractContainerScreen
  • 职责:

    TODO

字段/常量

  • BANNER_SLOT_SPRITE

    • 类型: Identifier
    • 修饰符: private static final
    • 源码定位: L36
    • 说明:

      TODO

  • DYE_SLOT_SPRITE

    • 类型: Identifier
    • 修饰符: private static final
    • 源码定位: L37
    • 说明:

      TODO

  • PATTERN_SLOT_SPRITE

    • 类型: Identifier
    • 修饰符: private static final
    • 源码定位: L38
    • 说明:

      TODO

  • SCROLLER_SPRITE

    • 类型: Identifier
    • 修饰符: private static final
    • 源码定位: L39
    • 说明:

      TODO

  • SCROLLER_DISABLED_SPRITE

    • 类型: Identifier
    • 修饰符: private static final
    • 源码定位: L40
    • 说明:

      TODO

  • PATTERN_SELECTED_SPRITE

    • 类型: Identifier
    • 修饰符: private static final
    • 源码定位: L41
    • 说明:

      TODO

  • PATTERN_HIGHLIGHTED_SPRITE

    • 类型: Identifier
    • 修饰符: private static final
    • 源码定位: L42
    • 说明:

      TODO

  • PATTERN_SPRITE

    • 类型: Identifier
    • 修饰符: private static final
    • 源码定位: L43
    • 说明:

      TODO

  • ERROR_SPRITE

    • 类型: Identifier
    • 修饰符: private static final
    • 源码定位: L44
    • 说明:

      TODO

  • BG_LOCATION

    • 类型: Identifier
    • 修饰符: private static final
    • 源码定位: L45
    • 说明:

      TODO

  • PATTERN_COLUMNS

    • 类型: int
    • 修饰符: private static final
    • 源码定位: L46
    • 说明:

      TODO

  • PATTERN_ROWS

    • 类型: int
    • 修饰符: private static final
    • 源码定位: L47
    • 说明:

      TODO

  • SCROLLER_WIDTH

    • 类型: int
    • 修饰符: private static final
    • 源码定位: L48
    • 说明:

      TODO

  • SCROLLER_HEIGHT

    • 类型: int
    • 修饰符: private static final
    • 源码定位: L49
    • 说明:

      TODO

  • PATTERN_IMAGE_SIZE

    • 类型: int
    • 修饰符: private static final
    • 源码定位: L50
    • 说明:

      TODO

  • SCROLLER_FULL_HEIGHT

    • 类型: int
    • 修饰符: private static final
    • 源码定位: L51
    • 说明:

      TODO

  • PATTERNS_X

    • 类型: int
    • 修饰符: private static final
    • 源码定位: L52
    • 说明:

      TODO

  • PATTERNS_Y

    • 类型: int
    • 修饰符: private static final
    • 源码定位: L53
    • 说明:

      TODO

  • BANNER_PATTERN_TEXTURE_SIZE

    • 类型: float
    • 修饰符: private static final
    • 源码定位: L54
    • 说明:

      TODO

  • BANNER_PATTERN_WIDTH

    • 类型: float
    • 修饰符: private static final
    • 源码定位: L55
    • 说明:

      TODO

  • BANNER_PATTERN_HEIGHT

    • 类型: float
    • 修饰符: private static final
    • 源码定位: L56
    • 说明:

      TODO

  • flag

    • 类型: BannerFlagModel
    • 修饰符: private
    • 源码定位: L57
    • 说明:

      TODO

  • resultBannerPatterns

    • 类型: BannerPatternLayers
    • 修饰符: private
    • 源码定位: L58
    • 说明:

      TODO

  • bannerStack

    • 类型: ItemStack
    • 修饰符: private
    • 源码定位: L59
    • 说明:

      TODO

  • dyeStack

    • 类型: ItemStack
    • 修饰符: private
    • 源码定位: L60
    • 说明:

      TODO

  • patternStack

    • 类型: ItemStack
    • 修饰符: private
    • 源码定位: L61
    • 说明:

      TODO

  • displayPatterns

    • 类型: boolean
    • 修饰符: private
    • 源码定位: L62
    • 说明:

      TODO

  • hasMaxPatterns

    • 类型: boolean
    • 修饰符: private
    • 源码定位: L63
    • 说明:

      TODO

  • scrollOffs

    • 类型: float
    • 修饰符: private
    • 源码定位: L64
    • 说明:

      TODO

  • scrolling

    • 类型: boolean
    • 修饰符: private
    • 源码定位: L65
    • 说明:

      TODO

  • startRow

    • 类型: int
    • 修饰符: private
    • 源码定位: L66
    • 说明:

      TODO

内部类/嵌套类型

构造器

public LoomScreen(LoomMenu menu, Inventory inventory, Component title) @ L68

  • 构造器名:LoomScreen
  • 源码定位:L68
  • 修饰符:public

参数:

  • menu: LoomMenu
  • inventory: Inventory
  • title: Component

说明:

TODO

方法

下面的方法块按源码顺序生成。

protected void init() @ L74

  • 方法名:init
  • 源码定位:L74
  • 返回类型:void
  • 修饰符:protected

参数:

说明:

TODO

private int totalRowCount() @ L81

  • 方法名:totalRowCount
  • 源码定位:L81
  • 返回类型:int
  • 修饰符:private

参数:

说明:

TODO

public void extractBackground(GuiGraphicsExtractor graphics, int mouseX, int mouseY, float a) @ L85

  • 方法名:extractBackground
  • 源码定位:L85
  • 返回类型:void
  • 修饰符:public

参数:

  • graphics: GuiGraphicsExtractor
  • mouseX: int
  • mouseY: int
  • a: float

说明:

TODO

private boolean isScrollBarActive() @ L169

  • 方法名:isScrollBarActive
  • 源码定位:L169
  • 返回类型:boolean
  • 修饰符:private

参数:

说明:

TODO

private void extractBannerOnButton(GuiGraphicsExtractor graphics, int posX, int posY, TextureAtlasSprite bannerPatternSprite) @ L173

  • 方法名:extractBannerOnButton
  • 源码定位:L173
  • 返回类型:void
  • 修饰符:private

参数:

  • graphics: GuiGraphicsExtractor
  • posX: int
  • posY: int
  • bannerPatternSprite: TextureAtlasSprite

说明:

TODO

public boolean mouseClicked(MouseButtonEvent event, boolean doubleClick) @ L188

  • 方法名:mouseClicked
  • 源码定位:L188
  • 返回类型:boolean
  • 修饰符:public

参数:

  • event: MouseButtonEvent
  • doubleClick: boolean

说明:

TODO

public boolean mouseDragged(MouseButtonEvent event, double dx, double dy) @ L218

  • 方法名:mouseDragged
  • 源码定位:L218
  • 返回类型:boolean
  • 修饰符:public

参数:

  • event: MouseButtonEvent
  • dx: double
  • dy: double

说明:

TODO

public boolean mouseReleased(MouseButtonEvent event) @ L233

  • 方法名:mouseReleased
  • 源码定位:L233
  • 返回类型:boolean
  • 修饰符:public

参数:

  • event: MouseButtonEvent

说明:

TODO

public boolean mouseScrolled(double x, double y, double scrollX, double scrollY) @ L239

  • 方法名:mouseScrolled
  • 源码定位:L239
  • 返回类型:boolean
  • 修饰符:public

参数:

  • x: double
  • y: double
  • scrollX: double
  • scrollY: double

说明:

TODO

protected boolean hasClickedOutside(double mx, double my, int xo, int yo) @ L255

  • 方法名:hasClickedOutside
  • 源码定位:L255
  • 返回类型:boolean
  • 修饰符:protected

参数:

  • mx: double
  • my: double
  • xo: int
  • yo: int

说明:

TODO

private void containerChanged() @ L260

  • 方法名:containerChanged
  • 源码定位:L260
  • 返回类型:void
  • 修饰符:private

参数:

说明:

TODO

代码

@OnlyIn(Dist.CLIENT)
public class LoomScreen extends AbstractContainerScreen<LoomMenu> {
    private static final Identifier BANNER_SLOT_SPRITE = Identifier.withDefaultNamespace("container/slot/banner");
    private static final Identifier DYE_SLOT_SPRITE = Identifier.withDefaultNamespace("container/slot/dye");
    private static final Identifier PATTERN_SLOT_SPRITE = Identifier.withDefaultNamespace("container/slot/banner_pattern");
    private static final Identifier SCROLLER_SPRITE = Identifier.withDefaultNamespace("container/loom/scroller");
    private static final Identifier SCROLLER_DISABLED_SPRITE = Identifier.withDefaultNamespace("container/loom/scroller_disabled");
    private static final Identifier PATTERN_SELECTED_SPRITE = Identifier.withDefaultNamespace("container/loom/pattern_selected");
    private static final Identifier PATTERN_HIGHLIGHTED_SPRITE = Identifier.withDefaultNamespace("container/loom/pattern_highlighted");
    private static final Identifier PATTERN_SPRITE = Identifier.withDefaultNamespace("container/loom/pattern");
    private static final Identifier ERROR_SPRITE = Identifier.withDefaultNamespace("container/loom/error");
    private static final Identifier BG_LOCATION = Identifier.withDefaultNamespace("textures/gui/container/loom.png");
    private static final int PATTERN_COLUMNS = 4;
    private static final int PATTERN_ROWS = 4;
    private static final int SCROLLER_WIDTH = 12;
    private static final int SCROLLER_HEIGHT = 15;
    private static final int PATTERN_IMAGE_SIZE = 14;
    private static final int SCROLLER_FULL_HEIGHT = 56;
    private static final int PATTERNS_X = 60;
    private static final int PATTERNS_Y = 13;
    private static final float BANNER_PATTERN_TEXTURE_SIZE = 64.0F;
    private static final float BANNER_PATTERN_WIDTH = 21.0F;
    private static final float BANNER_PATTERN_HEIGHT = 40.0F;
    private BannerFlagModel flag;
    private @Nullable BannerPatternLayers resultBannerPatterns;
    private ItemStack bannerStack = ItemStack.EMPTY;
    private ItemStack dyeStack = ItemStack.EMPTY;
    private ItemStack patternStack = ItemStack.EMPTY;
    private boolean displayPatterns;
    private boolean hasMaxPatterns;
    private float scrollOffs;
    private boolean scrolling;
    private int startRow;
 
    public LoomScreen(LoomMenu menu, Inventory inventory, Component title) {
        super(menu, inventory, title);
        menu.registerUpdateListener(this::containerChanged);
        this.titleLabelY -= 2;
    }
 
    @Override
    protected void init() {
        super.init();
        ModelPart modelPart = this.minecraft.getEntityModels().bakeLayer(ModelLayers.STANDING_BANNER_FLAG);
        this.flag = new BannerFlagModel(modelPart);
    }
 
    private int totalRowCount() {
        return Mth.positiveCeilDiv(this.menu.getSelectablePatterns().size(), 4);
    }
 
    @Override
    public void extractBackground(GuiGraphicsExtractor graphics, int mouseX, int mouseY, float a) {
        super.extractBackground(graphics, mouseX, mouseY, a);
        int xo = this.leftPos;
        int yo = this.topPos;
        graphics.blit(RenderPipelines.GUI_TEXTURED, BG_LOCATION, xo, yo, 0.0F, 0.0F, this.imageWidth, this.imageHeight, 256, 256);
        Slot bannerSlot = this.menu.getBannerSlot();
        Slot dyeSlot = this.menu.getDyeSlot();
        Slot patternSlot = this.menu.getPatternSlot();
        Slot resultSlot = this.menu.getResultSlot();
        if (!bannerSlot.hasItem()) {
            graphics.blitSprite(RenderPipelines.GUI_TEXTURED, BANNER_SLOT_SPRITE, xo + bannerSlot.x, yo + bannerSlot.y, 16, 16);
        }
 
        if (!dyeSlot.hasItem()) {
            graphics.blitSprite(RenderPipelines.GUI_TEXTURED, DYE_SLOT_SPRITE, xo + dyeSlot.x, yo + dyeSlot.y, 16, 16);
        }
 
        if (!patternSlot.hasItem()) {
            graphics.blitSprite(RenderPipelines.GUI_TEXTURED, PATTERN_SLOT_SPRITE, xo + patternSlot.x, yo + patternSlot.y, 16, 16);
        }
 
        int sy = (int)(41.0F * this.scrollOffs);
        Identifier sprite = this.isScrollBarActive() ? SCROLLER_SPRITE : SCROLLER_DISABLED_SPRITE;
        int scrollerX = xo + 119;
        int scrollerY = yo + 13;
        graphics.blitSprite(RenderPipelines.GUI_TEXTURED, sprite, scrollerX, scrollerY + sy, 12, 15);
        if (mouseX >= scrollerX && mouseX < scrollerX + 12 && mouseY >= scrollerY && mouseY < scrollerY + 56) {
            if (this.isScrollBarActive()) {
                graphics.requestCursor(this.scrolling ? CursorTypes.RESIZE_NS : CursorTypes.POINTING_HAND);
            } else {
                graphics.requestCursor(CursorTypes.NOT_ALLOWED);
            }
        }
 
        if (this.resultBannerPatterns != null && !this.hasMaxPatterns) {
            DyeColor baseColor = ((BannerItem)resultSlot.getItem().getItem()).getColor();
            int x0 = xo + 141;
            int y0 = yo + 8;
            graphics.bannerPattern(this.flag, baseColor, this.resultBannerPatterns, x0, y0, x0 + 20, y0 + 40);
        } else if (this.hasMaxPatterns) {
            graphics.blitSprite(RenderPipelines.GUI_TEXTURED, ERROR_SPRITE, xo + resultSlot.x - 5, yo + resultSlot.y - 5, 26, 26);
        }
 
        if (this.displayPatterns) {
            int x = xo + 60;
            int y = yo + 13;
            List<Holder<BannerPattern>> selectablePatterns = this.menu.getSelectablePatterns();
 
            label82:
            for (int row = 0; row < 4; row++) {
                for (int column = 0; column < 4; column++) {
                    int actualRow = row + this.startRow;
                    int index = actualRow * 4 + column;
                    if (index >= selectablePatterns.size()) {
                        break label82;
                    }
 
                    int posX = x + column * 14;
                    int posY = y + row * 14;
                    Holder<BannerPattern> pattern = selectablePatterns.get(index);
                    boolean isHighlighted = mouseX >= posX && mouseY >= posY && mouseX < posX + 14 && mouseY < posY + 14;
                    Identifier buttonSprite;
                    if (index == this.menu.getSelectedBannerPatternIndex()) {
                        buttonSprite = PATTERN_SELECTED_SPRITE;
                    } else if (isHighlighted) {
                        buttonSprite = PATTERN_HIGHLIGHTED_SPRITE;
                        DyeColor patternColor = this.dyeStack.getOrDefault(DataComponents.DYE, DyeColor.WHITE);
                        graphics.setTooltipForNextFrame(Component.translatable(pattern.value().translationKey() + "." + patternColor.getName()), mouseX, mouseY);
                        graphics.requestCursor(CursorTypes.POINTING_HAND);
                    } else {
                        buttonSprite = PATTERN_SPRITE;
                    }
 
                    graphics.blitSprite(RenderPipelines.GUI_TEXTURED, buttonSprite, posX, posY, 14, 14);
                    TextureAtlasSprite bannerPatternSprite = graphics.getSprite(Sheets.getBannerSprite(pattern));
                    this.extractBannerOnButton(graphics, posX, posY, bannerPatternSprite);
                }
            }
        }
 
        Minecraft.getInstance().gameRenderer.getLighting().setupFor(Lighting.Entry.ITEMS_3D);
    }
 
    private boolean isScrollBarActive() {
        return this.displayPatterns && this.menu.getSelectablePatterns().size() > 16;
    }
 
    private void extractBannerOnButton(GuiGraphicsExtractor graphics, int posX, int posY, TextureAtlasSprite bannerPatternSprite) {
        graphics.pose().pushMatrix();
        graphics.pose().translate(posX + 4, posY + 2);
        float patternU0 = bannerPatternSprite.getU0();
        float patternU1 = patternU0 + (bannerPatternSprite.getU1() - bannerPatternSprite.getU0()) * 21.0F / 64.0F;
        float patternVSpan = bannerPatternSprite.getV1() - bannerPatternSprite.getV0();
        float patternV0 = bannerPatternSprite.getV0() + patternVSpan / 64.0F;
        float patternV1 = patternV0 + patternVSpan * 40.0F / 64.0F;
        int bannerWidth = 5;
        int bannerHeight = 10;
        graphics.fill(0, 0, 5, 10, DyeColor.GRAY.getTextureDiffuseColor());
        graphics.blit(bannerPatternSprite.atlasLocation(), 0, 0, 5, 10, patternU0, patternU1, patternV0, patternV1);
        graphics.pose().popMatrix();
    }
 
    @Override
    public boolean mouseClicked(MouseButtonEvent event, boolean doubleClick) {
        if (this.displayPatterns) {
            int xo = this.leftPos + 60;
            int yo = this.topPos + 13;
 
            for (int row = 0; row < 4; row++) {
                for (int column = 0; column < 4; column++) {
                    double xx = event.x() - (xo + column * 14);
                    double yy = event.y() - (yo + row * 14);
                    int actualRow = row + this.startRow;
                    int index = actualRow * 4 + column;
                    if (xx >= 0.0 && yy >= 0.0 && xx < 14.0 && yy < 14.0 && this.menu.clickMenuButton(this.minecraft.player, index)) {
                        Minecraft.getInstance().getSoundManager().play(SimpleSoundInstance.forUI(SoundEvents.UI_LOOM_SELECT_PATTERN, 1.0F));
                        this.minecraft.gameMode.handleInventoryButtonClick(this.menu.containerId, index);
                        return true;
                    }
                }
            }
 
            xo = this.leftPos + 119;
            yo = this.topPos + 9;
            if (event.x() >= xo && event.x() < xo + 12 && event.y() >= yo && event.y() < yo + 56) {
                this.scrolling = true;
            }
        }
 
        return super.mouseClicked(event, doubleClick);
    }
 
    @Override
    public boolean mouseDragged(MouseButtonEvent event, double dx, double dy) {
        int offscreenRows = this.totalRowCount() - 4;
        if (this.scrolling && this.displayPatterns && offscreenRows > 0) {
            int yscr = this.topPos + 13;
            int yscr2 = yscr + 56;
            this.scrollOffs = ((float)event.y() - yscr - 7.5F) / (yscr2 - yscr - 15.0F);
            this.scrollOffs = Mth.clamp(this.scrollOffs, 0.0F, 1.0F);
            this.startRow = Math.max((int)(this.scrollOffs * offscreenRows + 0.5), 0);
            return true;
        } else {
            return super.mouseDragged(event, dx, dy);
        }
    }
 
    @Override
    public boolean mouseReleased(MouseButtonEvent event) {
        this.scrolling = false;
        return super.mouseReleased(event);
    }
 
    @Override
    public boolean mouseScrolled(double x, double y, double scrollX, double scrollY) {
        if (super.mouseScrolled(x, y, scrollX, scrollY)) {
            return true;
        } else {
            int offscreenRows = this.totalRowCount() - 4;
            if (this.displayPatterns && offscreenRows > 0) {
                float scrolledDelta = (float)scrollY / offscreenRows;
                this.scrollOffs = Mth.clamp(this.scrollOffs - scrolledDelta, 0.0F, 1.0F);
                this.startRow = Math.max((int)(this.scrollOffs * offscreenRows + 0.5F), 0);
            }
 
            return true;
        }
    }
 
    @Override
    protected boolean hasClickedOutside(double mx, double my, int xo, int yo) {
        return mx < xo || my < yo || mx >= xo + this.imageWidth || my >= yo + this.imageHeight;
    }
 
    private void containerChanged() {
        ItemStack resultStack = this.menu.getResultSlot().getItem();
        if (resultStack.isEmpty()) {
            this.resultBannerPatterns = null;
        } else {
            this.resultBannerPatterns = resultStack.getOrDefault(DataComponents.BANNER_PATTERNS, BannerPatternLayers.EMPTY);
        }
 
        ItemStack bannerStack = this.menu.getBannerSlot().getItem();
        ItemStack dyeStack = this.menu.getDyeSlot().getItem();
        ItemStack patternStack = this.menu.getPatternSlot().getItem();
        BannerPatternLayers patterns = bannerStack.getOrDefault(DataComponents.BANNER_PATTERNS, BannerPatternLayers.EMPTY);
        this.hasMaxPatterns = patterns.layers().size() >= 6;
        if (this.hasMaxPatterns) {
            this.resultBannerPatterns = null;
        }
 
        if (!ItemStack.matches(bannerStack, this.bannerStack)
            || !ItemStack.matches(dyeStack, this.dyeStack)
            || !ItemStack.matches(patternStack, this.patternStack)) {
            this.displayPatterns = !bannerStack.isEmpty() && !dyeStack.isEmpty() && !this.hasMaxPatterns && !this.menu.getSelectablePatterns().isEmpty();
        }
 
        if (this.startRow >= this.totalRowCount()) {
            this.startRow = 0;
            this.scrollOffs = 0.0F;
        }
 
        this.bannerStack = bannerStack.copy();
        this.dyeStack = dyeStack.copy();
        this.patternStack = patternStack.copy();
    }
}

引用的其他类