AbstractContainerScreen.java
net.minecraft.client.gui.screens.inventory.AbstractContainerScreen
信息
- 全限定名:net.minecraft.client.gui.screens.inventory.AbstractContainerScreen
- 类型:public abstract class
- 包:net.minecraft.client.gui.screens.inventory
- 源码路径:src/main/java/net/minecraft/client/gui/screens/inventory/AbstractContainerScreen.java
- 起始行号:L33
- 继承:Screen
- 实现:MenuAccess
- 职责:
TODO
字段/常量
-
INVENTORY_LOCATION- 类型:
Identifier - 修饰符:
public static final - 源码定位:
L34 - 说明:
TODO
- 类型:
-
SLOT_HIGHLIGHT_BACK_SPRITE- 类型:
Identifier - 修饰符:
private static final - 源码定位:
L35 - 说明:
TODO
- 类型:
-
SLOT_HIGHLIGHT_FRONT_SPRITE- 类型:
Identifier - 修饰符:
private static final - 源码定位:
L36 - 说明:
TODO
- 类型:
-
BACKGROUND_TEXTURE_WIDTH- 类型:
int - 修饰符:
protected static final - 源码定位:
L37 - 说明:
TODO
- 类型:
-
BACKGROUND_TEXTURE_HEIGHT- 类型:
int - 修饰符:
protected static final - 源码定位:
L38 - 说明:
TODO
- 类型:
-
SNAPBACK_SPEED- 类型:
float - 修饰符:
private static final - 源码定位:
L39 - 说明:
TODO
- 类型:
-
QUICKDROP_DELAY- 类型:
int - 修饰符:
private static final - 源码定位:
L40 - 说明:
TODO
- 类型:
-
DEFAULT_IMAGE_WIDTH- 类型:
int - 修饰符:
protected static final - 源码定位:
L41 - 说明:
TODO
- 类型:
-
DEFAULT_IMAGE_HEIGHT- 类型:
int - 修饰符:
protected static final - 源码定位:
L42 - 说明:
TODO
- 类型:
-
imageWidth- 类型:
int - 修饰符:
protected final - 源码定位:
L43 - 说明:
TODO
- 类型:
-
imageHeight- 类型:
int - 修饰符:
protected final - 源码定位:
L44 - 说明:
TODO
- 类型:
-
titleLabelX- 类型:
int - 修饰符:
protected - 源码定位:
L45 - 说明:
TODO
- 类型:
-
titleLabelY- 类型:
int - 修饰符:
protected - 源码定位:
L46 - 说明:
TODO
- 类型:
-
inventoryLabelX- 类型:
int - 修饰符:
protected - 源码定位:
L47 - 说明:
TODO
- 类型:
-
inventoryLabelY- 类型:
int - 修饰符:
protected - 源码定位:
L48 - 说明:
TODO
- 类型:
-
itemSlotMouseActions- 类型:
List<ItemSlotMouseAction> - 修饰符:
private final - 源码定位:
L49 - 说明:
TODO
- 类型:
-
menu- 类型:
T - 修饰符:
protected final - 源码定位:
L50 - 说明:
TODO
- 类型:
-
playerInventoryTitle- 类型:
Component - 修饰符:
protected final - 源码定位:
L51 - 说明:
TODO
- 类型:
-
hoveredSlot- 类型:
Slot - 修饰符:
protected - 源码定位:
L52 - 说明:
TODO
- 类型:
-
clickedSlot- 类型:
Slot - 修饰符:
private - 源码定位:
L53 - 说明:
TODO
- 类型:
-
quickdropSlot- 类型:
Slot - 修饰符:
private - 源码定位:
L54 - 说明:
TODO
- 类型:
-
lastClickSlot- 类型:
Slot - 修饰符:
private - 源码定位:
L55 - 说明:
TODO
- 类型:
-
snapbackData- 类型:
AbstractContainerScreen.SnapbackData - 修饰符:
private - 源码定位:
L56 - 说明:
TODO
- 类型:
-
leftPos- 类型:
int - 修饰符:
protected - 源码定位:
L57 - 说明:
TODO
- 类型:
-
topPos- 类型:
int - 修饰符:
protected - 源码定位:
L58 - 说明:
TODO
- 类型:
-
isSplittingStack- 类型:
boolean - 修饰符:
private - 源码定位:
L59 - 说明:
TODO
- 类型:
-
draggingItem- 类型:
ItemStack - 修饰符:
private - 源码定位:
L60 - 说明:
TODO
- 类型:
-
quickdropTime- 类型:
long - 修饰符:
private - 源码定位:
L61 - 说明:
TODO
- 类型:
-
quickCraftSlots- 类型:
Set<Slot> - 修饰符:
protected final - 源码定位:
L62 - 说明:
TODO
- 类型:
-
isQuickCrafting- 类型:
boolean - 修饰符:
protected - 源码定位:
L63 - 说明:
TODO
- 类型:
-
quickCraftingType- 类型:
int - 修饰符:
private - 源码定位:
L64 - 说明:
TODO
- 类型:
-
quickCraftingButton- 类型:
int - 修饰符:
private - 源码定位:
L65 - 说明:
TODO
- 类型:
-
skipNextRelease- 类型:
boolean - 修饰符:
private - 源码定位:
L67 - 说明:
TODO
- 类型:
-
quickCraftingRemainder- 类型:
int - 修饰符:
private - 源码定位:
L68 - 说明:
TODO
- 类型:
-
doubleclick- 类型:
boolean - 修饰符:
private - 源码定位:
L69 - 说明:
TODO
- 类型:
-
lastQuickMoved- 类型:
ItemStack - 修饰符:
private - 源码定位:
L70 - 说明:
TODO
- 类型:
内部类/嵌套类型
net.minecraft.client.gui.screens.inventory.AbstractContainerScreen.SnapbackData- 类型:
record - 修饰符:
private - 源码定位:
L698 - 说明:
TODO
- 类型:
构造器
public AbstractContainerScreen(T menu, Inventory inventory, Component title) @ L72
- 构造器名:AbstractContainerScreen
- 源码定位:L72
- 修饰符:public
参数:
- menu: T
- inventory: Inventory
- title: Component
说明:
TODO
public AbstractContainerScreen(T menu, Inventory inventory, Component title, int imageWidth, int imageHeight) @ L76
- 构造器名:AbstractContainerScreen
- 源码定位:L76
- 修饰符:public
参数:
- menu: T
- inventory: Inventory
- title: Component
- imageWidth: int
- imageHeight: int
说明:
TODO
方法
下面的方法块按源码顺序生成。
protected void init() @ L90
- 方法名:init
- 源码定位:L90
- 返回类型:void
- 修饰符:protected
参数:
- 无
说明:
TODO
protected void addItemSlotMouseAction(ItemSlotMouseAction itemSlotMouseAction) @ L98
- 方法名:addItemSlotMouseAction
- 源码定位:L98
- 返回类型:void
- 修饰符:protected
参数:
- itemSlotMouseAction: ItemSlotMouseAction
说明:
TODO
public void extractRenderState(GuiGraphicsExtractor graphics, int mouseX, int mouseY, float a) @ L102
- 方法名:extractRenderState
- 源码定位:L102
- 返回类型:void
- 修饰符:public
参数:
- graphics: GuiGraphicsExtractor
- mouseX: int
- mouseY: int
- a: float
说明:
TODO
public void extractContents(GuiGraphicsExtractor graphics, int mouseX, int mouseY, float a) @ L110
- 方法名:extractContents
- 源码定位:L110
- 返回类型:void
- 修饰符:public
参数:
- graphics: GuiGraphicsExtractor
- mouseX: int
- mouseY: int
- a: float
说明:
TODO
public void extractCarriedItem(GuiGraphicsExtractor graphics, int mouseX, int mouseY) @ L129
- 方法名:extractCarriedItem
- 源码定位:L129
- 返回类型:void
- 修饰符:public
参数:
- graphics: GuiGraphicsExtractor
- mouseX: int
- mouseY: int
说明:
TODO
public void extractSnapbackItem(GuiGraphicsExtractor graphics) @ L149
- 方法名:extractSnapbackItem
- 源码定位:L149
- 返回类型:void
- 修饰符:public
参数:
- graphics: GuiGraphicsExtractor
说明:
TODO
protected void extractSlots(GuiGraphicsExtractor graphics, int mouseX, int mouseY) @ L164
- 方法名:extractSlots
- 源码定位:L164
- 返回类型:void
- 修饰符:protected
参数:
- graphics: GuiGraphicsExtractor
- mouseX: int
- mouseY: int
说明:
TODO
public boolean mouseScrolled(double x, double y, double scrollX, double scrollY) @ L172
- 方法名:mouseScrolled
- 源码定位:L172
- 返回类型:boolean
- 修饰符:public
参数:
- x: double
- y: double
- scrollX: double
- scrollY: double
说明:
TODO
private void extractSlotHighlightBack(GuiGraphicsExtractor graphics) @ L186
- 方法名:extractSlotHighlightBack
- 源码定位:L186
- 返回类型:void
- 修饰符:private
参数:
- graphics: GuiGraphicsExtractor
说明:
TODO
private void extractSlotHighlightFront(GuiGraphicsExtractor graphics) @ L192
- 方法名:extractSlotHighlightFront
- 源码定位:L192
- 返回类型:void
- 修饰符:private
参数:
- graphics: GuiGraphicsExtractor
说明:
TODO
protected void extractTooltip(GuiGraphicsExtractor graphics, int mouseX, int mouseY) @ L198
- 方法名:extractTooltip
- 源码定位:L198
- 返回类型:void
- 修饰符:protected
参数:
- graphics: GuiGraphicsExtractor
- mouseX: int
- mouseY: int
说明:
TODO
private boolean showTooltipWithItemInHand(ItemStack item) @ L209
- 方法名:showTooltipWithItemInHand
- 源码定位:L209
- 返回类型:boolean
- 修饰符:private
参数:
- item: ItemStack
说明:
TODO
protected List<Component> getTooltipFromContainerItem(ItemStack itemStack) @ L213
- 方法名:getTooltipFromContainerItem
- 源码定位:L213
- 返回类型:List
- 修饰符:protected
参数:
- itemStack: ItemStack
说明:
TODO
private void extractFloatingItem(GuiGraphicsExtractor graphics, ItemStack carried, int x, int y, String itemCount) @ L217
- 方法名:extractFloatingItem
- 源码定位:L217
- 返回类型:void
- 修饰符:private
参数:
- graphics: GuiGraphicsExtractor
- carried: ItemStack
- x: int
- y: int
- itemCount: String
说明:
TODO
protected void extractLabels(GuiGraphicsExtractor graphics, int xm, int ym) @ L222
- 方法名:extractLabels
- 源码定位:L222
- 返回类型:void
- 修饰符:protected
参数:
- graphics: GuiGraphicsExtractor
- xm: int
- ym: int
说明:
TODO
protected void extractSlot(GuiGraphicsExtractor graphics, Slot slot, int mouseX, int mouseY) @ L227
- 方法名:extractSlot
- 源码定位:L227
- 返回类型:void
- 修饰符:protected
参数:
- graphics: GuiGraphicsExtractor
- slot: Slot
- mouseX: int
- mouseY: int
说明:
TODO
private void recalculateQuickCraftRemaining() @ L283
- 方法名:recalculateQuickCraftRemaining
- 源码定位:L283
- 返回类型:void
- 修饰符:private
参数:
- 无
说明:
TODO
private Slot getHoveredSlot(double x, double y) @ L304
- 方法名:getHoveredSlot
- 源码定位:L304
- 返回类型:Slot
- 修饰符:private
参数:
- x: double
- y: double
说明:
TODO
public boolean mouseClicked(MouseButtonEvent event, boolean doubleClick) @ L314
- 方法名:mouseClicked
- 源码定位:L314
- 返回类型:boolean
- 修饰符:public
参数:
- event: MouseButtonEvent
- doubleClick: boolean
说明:
TODO
private void checkHotbarMouseClicked(MouseButtonEvent event) @ L391
- 方法名:checkHotbarMouseClicked
- 源码定位:L391
- 返回类型:void
- 修饰符:private
参数:
- event: MouseButtonEvent
说明:
TODO
protected boolean hasClickedOutside(double mx, double my, int xo, int yo) @ L406
- 方法名:hasClickedOutside
- 源码定位:L406
- 返回类型:boolean
- 修饰符:protected
参数:
- mx: double
- my: double
- xo: int
- yo: int
说明:
TODO
public boolean mouseDragged(MouseButtonEvent event, double dx, double dy) @ L410
- 方法名:mouseDragged
- 源码定位:L410
- 返回类型:boolean
- 修饰符:public
参数:
- event: MouseButtonEvent
- dx: double
- dy: double
说明:
TODO
public boolean mouseReleased(MouseButtonEvent event) @ L446
- 方法名:mouseReleased
- 源码定位:L446
- 返回类型:boolean
- 修饰符:public
参数:
- event: MouseButtonEvent
说明:
TODO
public void clearDraggingState() @ L544
- 方法名:clearDraggingState
- 源码定位:L544
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
private boolean isHovering(Slot slot, double xm, double ym) @ L549
- 方法名:isHovering
- 源码定位:L549
- 返回类型:boolean
- 修饰符:private
参数:
- slot: Slot
- xm: double
- ym: double
说明:
TODO
protected boolean isHovering(int left, int top, int w, int h, double xm, double ym) @ L553
- 方法名:isHovering
- 源码定位:L553
- 返回类型:boolean
- 修饰符:protected
参数:
- left: int
- top: int
- w: int
- h: int
- xm: double
- ym: double
说明:
TODO
private void onStopHovering(Slot slot) @ L561
- 方法名:onStopHovering
- 源码定位:L561
- 返回类型:void
- 修饰符:private
参数:
- slot: Slot
说明:
TODO
protected void slotClicked(Slot slot, int slotId, int buttonNum, ContainerInput containerInput) @ L571
- 方法名:slotClicked
- 源码定位:L571
- 返回类型:void
- 修饰符:protected
参数:
- slot: Slot
- slotId: int
- buttonNum: int
- containerInput: ContainerInput
说明:
TODO
void onMouseClickAction(Slot slot, ContainerInput containerInput) @ L580
- 方法名:onMouseClickAction
- 源码定位:L580
- 返回类型:void
- 修饰符:package-private
参数:
- slot: Slot
- containerInput: ContainerInput
说明:
TODO
protected void handleSlotStateChanged(int slotId, int containerId, boolean newState) @ L590
- 方法名:handleSlotStateChanged
- 源码定位:L590
- 返回类型:void
- 修饰符:protected
参数:
- slotId: int
- containerId: int
- newState: boolean
说明:
TODO
public boolean keyPressed(KeyEvent event) @ L594
- 方法名:keyPressed
- 源码定位:L594
- 返回类型:boolean
- 修饰符:public
参数:
- event: KeyEvent
说明:
TODO
protected boolean checkHotbarKeyPressed(KeyEvent event) @ L615
- 方法名:checkHotbarKeyPressed
- 源码定位:L615
- 返回类型:boolean
- 修饰符:protected
参数:
- event: KeyEvent
说明:
TODO
public void removed() @ L633
- 方法名:removed
- 源码定位:L633
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
public boolean isPauseScreen() @ L640
- 方法名:isPauseScreen
- 源码定位:L640
- 返回类型:boolean
- 修饰符:public
参数:
- 无
说明:
TODO
public boolean isInGameUi() @ L645
- 方法名:isInGameUi
- 源码定位:L645
- 返回类型:boolean
- 修饰符:public
参数:
- 无
说明:
TODO
public final void tick() @ L650
- 方法名:tick
- 源码定位:L650
- 返回类型:void
- 修饰符:public final
参数:
- 无
说明:
TODO
protected void containerTick() @ L660
- 方法名:containerTick
- 源码定位:L660
- 返回类型:void
- 修饰符:protected
参数:
- 无
说明:
TODO
private boolean shouldAddSlotToQuickCraft(Slot slot, ItemStack carried) @ L663
- 方法名:shouldAddSlotToQuickCraft
- 源码定位:L663
- 返回类型:boolean
- 修饰符:private
参数:
- slot: Slot
- carried: ItemStack
说明:
TODO
private void quickCraftToSlots() @ L672
- 方法名:quickCraftToSlots
- 源码定位:L672
- 返回类型:void
- 修饰符:private
参数:
- 无
说明:
TODO
public T getMenu() @ L682
- 方法名:getMenu
- 源码定位:L682
- 返回类型:T
- 修饰符:public
参数:
- 无
说明:
TODO
public void onClose() @ L687
- 方法名:onClose
- 源码定位:L687
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
代码
@OnlyIn(Dist.CLIENT)
public abstract class AbstractContainerScreen<T extends AbstractContainerMenu> extends Screen implements MenuAccess<T> {
public static final Identifier INVENTORY_LOCATION = Identifier.withDefaultNamespace("textures/gui/container/inventory.png");
private static final Identifier SLOT_HIGHLIGHT_BACK_SPRITE = Identifier.withDefaultNamespace("container/slot_highlight_back");
private static final Identifier SLOT_HIGHLIGHT_FRONT_SPRITE = Identifier.withDefaultNamespace("container/slot_highlight_front");
protected static final int BACKGROUND_TEXTURE_WIDTH = 256;
protected static final int BACKGROUND_TEXTURE_HEIGHT = 256;
private static final float SNAPBACK_SPEED = 100.0F;
private static final int QUICKDROP_DELAY = 500;
protected static final int DEFAULT_IMAGE_WIDTH = 176;
protected static final int DEFAULT_IMAGE_HEIGHT = 166;
protected final int imageWidth;
protected final int imageHeight;
protected int titleLabelX;
protected int titleLabelY;
protected int inventoryLabelX;
protected int inventoryLabelY;
private final List<ItemSlotMouseAction> itemSlotMouseActions;
protected final T menu;
protected final Component playerInventoryTitle;
protected @Nullable Slot hoveredSlot;
private @Nullable Slot clickedSlot;
private @Nullable Slot quickdropSlot;
private @Nullable Slot lastClickSlot;
private AbstractContainerScreen.@Nullable SnapbackData snapbackData;
protected int leftPos;
protected int topPos;
private boolean isSplittingStack;
private ItemStack draggingItem = ItemStack.EMPTY;
private long quickdropTime;
protected final Set<Slot> quickCraftSlots = Sets.newHashSet();
protected boolean isQuickCrafting;
private int quickCraftingType;
@MouseButtonInfo.MouseButton
private int quickCraftingButton;
private boolean skipNextRelease;
private int quickCraftingRemainder;
private boolean doubleclick;
private ItemStack lastQuickMoved = ItemStack.EMPTY;
public AbstractContainerScreen(T menu, Inventory inventory, Component title) {
this(menu, inventory, title, 176, 166);
}
public AbstractContainerScreen(T menu, Inventory inventory, Component title, int imageWidth, int imageHeight) {
super(title);
this.menu = menu;
this.playerInventoryTitle = inventory.getDisplayName();
this.imageWidth = imageWidth;
this.imageHeight = imageHeight;
this.skipNextRelease = true;
this.titleLabelX = 8;
this.titleLabelY = 6;
this.inventoryLabelX = 8;
this.inventoryLabelY = imageHeight - 94;
this.itemSlotMouseActions = new ArrayList<>();
}
@Override
protected void init() {
this.leftPos = (this.width - this.imageWidth) / 2;
this.topPos = (this.height - this.imageHeight) / 2;
this.itemSlotMouseActions.clear();
this.addItemSlotMouseAction(new BundleMouseActions(this.minecraft));
}
protected void addItemSlotMouseAction(ItemSlotMouseAction itemSlotMouseAction) {
this.itemSlotMouseActions.add(itemSlotMouseAction);
}
@Override
public void extractRenderState(GuiGraphicsExtractor graphics, int mouseX, int mouseY, float a) {
this.extractContents(graphics, mouseX, mouseY, a);
this.extractCarriedItem(graphics, mouseX, mouseY);
this.extractSnapbackItem(graphics);
this.extractTooltip(graphics, mouseX, mouseY);
}
public void extractContents(GuiGraphicsExtractor graphics, int mouseX, int mouseY, float a) {
int xo = this.leftPos;
int yo = this.topPos;
super.extractRenderState(graphics, mouseX, mouseY, a);
graphics.pose().pushMatrix();
graphics.pose().translate(xo, yo);
this.extractLabels(graphics, mouseX, mouseY);
Slot previouslyHoveredSlot = this.hoveredSlot;
this.hoveredSlot = this.getHoveredSlot(mouseX, mouseY);
this.extractSlotHighlightBack(graphics);
this.extractSlots(graphics, mouseX, mouseY);
this.extractSlotHighlightFront(graphics);
if (previouslyHoveredSlot != null && previouslyHoveredSlot != this.hoveredSlot) {
this.onStopHovering(previouslyHoveredSlot);
}
graphics.pose().popMatrix();
}
public void extractCarriedItem(GuiGraphicsExtractor graphics, int mouseX, int mouseY) {
ItemStack carried = this.draggingItem.isEmpty() ? this.menu.getCarried() : this.draggingItem;
if (!carried.isEmpty()) {
int xOffset = 8;
int yOffset = this.draggingItem.isEmpty() ? 8 : 16;
String itemCount = null;
if (!this.draggingItem.isEmpty() && this.isSplittingStack) {
carried = carried.copyWithCount(Mth.ceil(carried.getCount() / 2.0F));
} else if (this.isQuickCrafting && this.quickCraftSlots.size() > 1) {
carried = carried.copyWithCount(this.quickCraftingRemainder);
if (carried.isEmpty()) {
itemCount = ChatFormatting.YELLOW + "0";
}
}
graphics.nextStratum();
this.extractFloatingItem(graphics, carried, mouseX - 8, mouseY - yOffset, itemCount);
}
}
public void extractSnapbackItem(GuiGraphicsExtractor graphics) {
if (this.snapbackData != null) {
float snapbackProgress = Mth.clamp((float)(Util.getMillis() - this.snapbackData.time) / 100.0F, 0.0F, 1.0F);
int xd = this.snapbackData.end.x - this.snapbackData.start.x;
int yd = this.snapbackData.end.y - this.snapbackData.start.y;
int x = this.snapbackData.start.x + (int)(xd * snapbackProgress);
int y = this.snapbackData.start.y + (int)(yd * snapbackProgress);
graphics.nextStratum();
this.extractFloatingItem(graphics, this.snapbackData.item, x, y, null);
if (snapbackProgress >= 1.0F) {
this.snapbackData = null;
}
}
}
protected void extractSlots(GuiGraphicsExtractor graphics, int mouseX, int mouseY) {
for (Slot slot : this.menu.slots) {
if (slot.isActive()) {
this.extractSlot(graphics, slot, mouseX, mouseY);
}
}
}
@Override
public boolean mouseScrolled(double x, double y, double scrollX, double scrollY) {
if (this.hoveredSlot != null && this.hoveredSlot.hasItem()) {
for (ItemSlotMouseAction itemMouseAction : this.itemSlotMouseActions) {
if (itemMouseAction.matches(this.hoveredSlot)
&& itemMouseAction.onMouseScrolled(scrollX, scrollY, this.hoveredSlot.index, this.hoveredSlot.getItem())) {
return true;
}
}
}
return false;
}
private void extractSlotHighlightBack(GuiGraphicsExtractor graphics) {
if (this.hoveredSlot != null && this.hoveredSlot.isHighlightable()) {
graphics.blitSprite(RenderPipelines.GUI_TEXTURED, SLOT_HIGHLIGHT_BACK_SPRITE, this.hoveredSlot.x - 4, this.hoveredSlot.y - 4, 24, 24);
}
}
private void extractSlotHighlightFront(GuiGraphicsExtractor graphics) {
if (this.hoveredSlot != null && this.hoveredSlot.isHighlightable()) {
graphics.blitSprite(RenderPipelines.GUI_TEXTURED, SLOT_HIGHLIGHT_FRONT_SPRITE, this.hoveredSlot.x - 4, this.hoveredSlot.y - 4, 24, 24);
}
}
protected void extractTooltip(GuiGraphicsExtractor graphics, int mouseX, int mouseY) {
if (this.hoveredSlot != null && this.hoveredSlot.hasItem()) {
ItemStack item = this.hoveredSlot.getItem();
if (this.menu.getCarried().isEmpty() || this.showTooltipWithItemInHand(item)) {
graphics.setTooltipForNextFrame(
this.font, this.getTooltipFromContainerItem(item), item.getTooltipImage(), mouseX, mouseY, item.get(DataComponents.TOOLTIP_STYLE)
);
}
}
}
private boolean showTooltipWithItemInHand(ItemStack item) {
return item.getTooltipImage().map(ClientTooltipComponent::create).map(ClientTooltipComponent::showTooltipWithItemInHand).orElse(false);
}
protected List<Component> getTooltipFromContainerItem(ItemStack itemStack) {
return getTooltipFromItem(this.minecraft, itemStack);
}
private void extractFloatingItem(GuiGraphicsExtractor graphics, ItemStack carried, int x, int y, @Nullable String itemCount) {
graphics.item(carried, x, y);
graphics.itemDecorations(this.font, carried, x, y - (this.draggingItem.isEmpty() ? 0 : 8), itemCount);
}
protected void extractLabels(GuiGraphicsExtractor graphics, int xm, int ym) {
graphics.text(this.font, this.title, this.titleLabelX, this.titleLabelY, -12566464, false);
graphics.text(this.font, this.playerInventoryTitle, this.inventoryLabelX, this.inventoryLabelY, -12566464, false);
}
protected void extractSlot(GuiGraphicsExtractor graphics, Slot slot, int mouseX, int mouseY) {
int x = slot.x;
int y = slot.y;
ItemStack itemStack = slot.getItem();
boolean quickCraftStack = false;
boolean done = slot == this.clickedSlot && !this.draggingItem.isEmpty() && !this.isSplittingStack;
ItemStack carried = this.menu.getCarried();
String itemCount = null;
if (slot == this.clickedSlot && !this.draggingItem.isEmpty() && this.isSplittingStack && !itemStack.isEmpty()) {
itemStack = itemStack.copyWithCount(itemStack.getCount() / 2);
} else if (this.isQuickCrafting && this.quickCraftSlots.contains(slot) && !carried.isEmpty()) {
if (this.quickCraftSlots.size() == 1) {
return;
}
if (AbstractContainerMenu.canItemQuickReplace(slot, carried, true) && this.menu.canDragTo(slot)) {
quickCraftStack = true;
int maxSize = Math.min(carried.getMaxStackSize(), slot.getMaxStackSize(carried));
int carry = slot.getItem().isEmpty() ? 0 : slot.getItem().getCount();
int newCount = AbstractContainerMenu.getQuickCraftPlaceCount(this.quickCraftSlots.size(), this.quickCraftingType, carried) + carry;
if (newCount > maxSize) {
newCount = maxSize;
itemCount = ChatFormatting.YELLOW.toString() + maxSize;
}
itemStack = carried.copyWithCount(newCount);
} else {
this.quickCraftSlots.remove(slot);
this.recalculateQuickCraftRemaining();
}
}
if (itemStack.isEmpty() && slot.isActive()) {
Identifier icon = slot.getNoItemIcon();
if (icon != null) {
graphics.blitSprite(RenderPipelines.GUI_TEXTURED, icon, x, y, 16, 16);
done = true;
}
}
if (!done) {
if (quickCraftStack) {
graphics.fill(x, y, x + 16, y + 16, -2130706433);
}
int seed = slot.x + slot.y * this.imageWidth;
if (slot.isFake()) {
graphics.fakeItem(itemStack, x, y, seed);
} else {
graphics.item(itemStack, x, y, seed);
}
graphics.itemDecorations(this.font, itemStack, x, y, itemCount);
}
}
private void recalculateQuickCraftRemaining() {
ItemStack carried = this.menu.getCarried();
if (!carried.isEmpty() && this.isQuickCrafting) {
if (this.quickCraftingType == 2) {
this.quickCraftingRemainder = carried.getMaxStackSize();
} else {
this.quickCraftingRemainder = carried.getCount();
for (Slot slot : this.quickCraftSlots) {
ItemStack slotItemStack = slot.getItem();
int carry = slotItemStack.isEmpty() ? 0 : slotItemStack.getCount();
int maxSize = Math.min(carried.getMaxStackSize(), slot.getMaxStackSize(carried));
int newCount = Math.min(
AbstractContainerMenu.getQuickCraftPlaceCount(this.quickCraftSlots.size(), this.quickCraftingType, carried) + carry, maxSize
);
this.quickCraftingRemainder -= newCount - carry;
}
}
}
}
private @Nullable Slot getHoveredSlot(double x, double y) {
for (Slot slot : this.menu.slots) {
if (slot.isActive() && this.isHovering(slot, x, y)) {
return slot;
}
}
return null;
}
@Override
public boolean mouseClicked(MouseButtonEvent event, boolean doubleClick) {
if (super.mouseClicked(event, doubleClick)) {
return true;
} else {
boolean cloning = this.minecraft.options.keyPickItem.matchesMouse(event) && this.minecraft.player.hasInfiniteMaterials();
Slot slot = this.getHoveredSlot(event.x(), event.y());
this.doubleclick = this.lastClickSlot == slot && doubleClick;
this.skipNextRelease = false;
if (event.button() != 0 && event.button() != 1 && !cloning) {
this.checkHotbarMouseClicked(event);
} else {
int xo = this.leftPos;
int yo = this.topPos;
boolean clickedOutside = this.hasClickedOutside(event.x(), event.y(), xo, yo);
int slotId = -1;
if (slot != null) {
slotId = slot.index;
}
if (clickedOutside) {
slotId = -999;
}
if (this.minecraft.options.touchscreen().get() && clickedOutside && this.menu.getCarried().isEmpty()) {
this.onClose();
return true;
}
if (slotId != -1) {
if (this.minecraft.options.touchscreen().get()) {
if (slot != null && slot.hasItem()) {
this.clickedSlot = slot;
this.draggingItem = ItemStack.EMPTY;
this.isSplittingStack = event.button() == 1;
} else {
this.clickedSlot = null;
}
} else if (!this.isQuickCrafting) {
if (this.menu.getCarried().isEmpty()) {
if (cloning) {
this.slotClicked(slot, slotId, event.button(), ContainerInput.CLONE);
} else {
boolean quickKey = slotId != -999 && event.hasShiftDown();
ContainerInput containerInput = ContainerInput.PICKUP;
if (quickKey) {
this.lastQuickMoved = slot != null && slot.hasItem() ? slot.getItem().copy() : ItemStack.EMPTY;
containerInput = ContainerInput.QUICK_MOVE;
} else if (slotId == -999) {
containerInput = ContainerInput.THROW;
}
this.slotClicked(slot, slotId, event.button(), containerInput);
}
this.skipNextRelease = true;
} else {
this.isQuickCrafting = true;
this.quickCraftingButton = event.button();
this.quickCraftSlots.clear();
if (event.button() == 0) {
this.quickCraftingType = 0;
} else if (event.button() == 1) {
this.quickCraftingType = 1;
} else if (cloning) {
this.quickCraftingType = 2;
}
}
}
}
}
this.lastClickSlot = slot;
return true;
}
}
private void checkHotbarMouseClicked(MouseButtonEvent event) {
if (this.hoveredSlot != null && this.menu.getCarried().isEmpty()) {
if (this.minecraft.options.keySwapOffhand.matchesMouse(event)) {
this.slotClicked(this.hoveredSlot, this.hoveredSlot.index, 40, ContainerInput.SWAP);
return;
}
for (int i = 0; i < 9; i++) {
if (this.minecraft.options.keyHotbarSlots[i].matchesMouse(event)) {
this.slotClicked(this.hoveredSlot, this.hoveredSlot.index, i, ContainerInput.SWAP);
}
}
}
}
protected boolean hasClickedOutside(double mx, double my, int xo, int yo) {
return mx < xo || my < yo || mx >= xo + this.imageWidth || my >= yo + this.imageHeight;
}
@Override
public boolean mouseDragged(MouseButtonEvent event, double dx, double dy) {
Slot slot = this.getHoveredSlot(event.x(), event.y());
ItemStack carried = this.menu.getCarried();
if (this.clickedSlot != null && this.minecraft.options.touchscreen().get()) {
if (event.button() == 0 || event.button() == 1) {
if (this.draggingItem.isEmpty()) {
if (slot != this.clickedSlot && !this.clickedSlot.getItem().isEmpty()) {
this.draggingItem = this.clickedSlot.getItem().copy();
}
} else if (this.draggingItem.getCount() > 1 && slot != null && AbstractContainerMenu.canItemQuickReplace(slot, this.draggingItem, false)) {
long time = Util.getMillis();
if (this.quickdropSlot == slot) {
if (time - this.quickdropTime > 500L) {
this.slotClicked(this.clickedSlot, this.clickedSlot.index, 0, ContainerInput.PICKUP);
this.slotClicked(slot, slot.index, 1, ContainerInput.PICKUP);
this.slotClicked(this.clickedSlot, this.clickedSlot.index, 0, ContainerInput.PICKUP);
this.quickdropTime = time + 750L;
this.draggingItem.shrink(1);
}
} else {
this.quickdropSlot = slot;
this.quickdropTime = time;
}
}
}
return true;
} else if (slot != null && this.shouldAddSlotToQuickCraft(slot, carried) && this.quickCraftSlots.add(slot)) {
this.recalculateQuickCraftRemaining();
return true;
} else {
return slot == null && this.menu.getCarried().isEmpty() ? super.mouseDragged(event, dx, dy) : true;
}
}
@Override
public boolean mouseReleased(MouseButtonEvent event) {
Slot slot = this.getHoveredSlot(event.x(), event.y());
int xo = this.leftPos;
int yo = this.topPos;
boolean clickedOutside = this.hasClickedOutside(event.x(), event.y(), xo, yo);
int slotId = -1;
if (slot != null) {
slotId = slot.index;
}
if (clickedOutside) {
slotId = -999;
}
if (this.doubleclick && slot != null && event.button() == 0 && this.menu.canTakeItemForPickAll(ItemStack.EMPTY, slot)) {
if (event.hasShiftDown()) {
if (!this.lastQuickMoved.isEmpty()) {
for (Slot target : this.menu.slots) {
if (target != null
&& target.mayPickup(this.minecraft.player)
&& target.hasItem()
&& target.container == slot.container
&& AbstractContainerMenu.canItemQuickReplace(target, this.lastQuickMoved, true)) {
this.slotClicked(target, target.index, event.button(), ContainerInput.QUICK_MOVE);
}
}
}
} else {
this.slotClicked(slot, slotId, event.button(), ContainerInput.PICKUP_ALL);
}
this.doubleclick = false;
} else {
if (this.isQuickCrafting && this.quickCraftingButton != event.button()) {
this.isQuickCrafting = false;
this.quickCraftSlots.clear();
this.skipNextRelease = true;
return true;
}
if (this.skipNextRelease) {
this.skipNextRelease = false;
return true;
}
if (this.clickedSlot != null && this.minecraft.options.touchscreen().get()) {
if (event.button() == 0 || event.button() == 1) {
if (this.draggingItem.isEmpty() && slot != this.clickedSlot) {
this.draggingItem = this.clickedSlot.getItem();
}
boolean canReplace = AbstractContainerMenu.canItemQuickReplace(slot, this.draggingItem, false);
if (slotId != -1 && !this.draggingItem.isEmpty() && canReplace) {
this.slotClicked(this.clickedSlot, this.clickedSlot.index, event.button(), ContainerInput.PICKUP);
this.slotClicked(slot, slotId, 0, ContainerInput.PICKUP);
if (this.menu.getCarried().isEmpty()) {
this.snapbackData = null;
} else {
this.slotClicked(this.clickedSlot, this.clickedSlot.index, event.button(), ContainerInput.PICKUP);
this.snapbackData = new AbstractContainerScreen.SnapbackData(
this.draggingItem,
new Vector2i((int)event.x(), (int)event.y()),
new Vector2i(this.clickedSlot.x + xo, this.clickedSlot.y + yo),
Util.getMillis()
);
}
} else if (!this.draggingItem.isEmpty()) {
this.snapbackData = new AbstractContainerScreen.SnapbackData(
this.draggingItem,
new Vector2i((int)event.x(), (int)event.y()),
new Vector2i(this.clickedSlot.x + xo, this.clickedSlot.y + yo),
Util.getMillis()
);
}
this.clearDraggingState();
}
} else if (this.isQuickCrafting && !this.quickCraftSlots.isEmpty()) {
this.quickCraftToSlots();
} else if (!this.menu.getCarried().isEmpty()) {
if (this.minecraft.options.keyPickItem.matchesMouse(event)) {
this.slotClicked(slot, slotId, event.button(), ContainerInput.CLONE);
} else {
boolean quickKey = slotId != -999 && event.hasShiftDown();
if (quickKey) {
this.lastQuickMoved = slot != null && slot.hasItem() ? slot.getItem().copy() : ItemStack.EMPTY;
}
this.slotClicked(slot, slotId, event.button(), quickKey ? ContainerInput.QUICK_MOVE : ContainerInput.PICKUP);
}
}
}
this.isQuickCrafting = false;
return super.mouseReleased(event);
}
public void clearDraggingState() {
this.draggingItem = ItemStack.EMPTY;
this.clickedSlot = null;
}
private boolean isHovering(Slot slot, double xm, double ym) {
return this.isHovering(slot.x, slot.y, 16, 16, xm, ym);
}
protected boolean isHovering(int left, int top, int w, int h, double xm, double ym) {
int xo = this.leftPos;
int yo = this.topPos;
xm -= xo;
ym -= yo;
return xm >= left - 1 && xm < left + w + 1 && ym >= top - 1 && ym < top + h + 1;
}
private void onStopHovering(Slot slot) {
if (slot.hasItem()) {
for (ItemSlotMouseAction itemMouseAction : this.itemSlotMouseActions) {
if (itemMouseAction.matches(slot)) {
itemMouseAction.onStopHovering(slot);
}
}
}
}
protected void slotClicked(Slot slot, int slotId, int buttonNum, ContainerInput containerInput) {
if (slot != null) {
slotId = slot.index;
}
this.onMouseClickAction(slot, containerInput);
this.minecraft.gameMode.handleContainerInput(this.menu.containerId, slotId, buttonNum, containerInput, this.minecraft.player);
}
void onMouseClickAction(@Nullable Slot slot, ContainerInput containerInput) {
if (slot != null && slot.hasItem()) {
for (ItemSlotMouseAction itemMouseAction : this.itemSlotMouseActions) {
if (itemMouseAction.matches(slot)) {
itemMouseAction.onSlotClicked(slot, containerInput);
}
}
}
}
protected void handleSlotStateChanged(int slotId, int containerId, boolean newState) {
this.minecraft.gameMode.handleSlotStateChanged(slotId, containerId, newState);
}
@Override
public boolean keyPressed(KeyEvent event) {
if (super.keyPressed(event)) {
return true;
} else if (this.minecraft.options.keyInventory.matches(event)) {
this.onClose();
return true;
} else {
this.checkHotbarKeyPressed(event);
if (this.hoveredSlot != null && this.hoveredSlot.hasItem()) {
if (this.minecraft.options.keyPickItem.matches(event)) {
this.slotClicked(this.hoveredSlot, this.hoveredSlot.index, 0, ContainerInput.CLONE);
} else if (this.minecraft.options.keyDrop.matches(event)) {
this.slotClicked(this.hoveredSlot, this.hoveredSlot.index, event.hasControlDown() ? 1 : 0, ContainerInput.THROW);
}
}
return false;
}
}
protected boolean checkHotbarKeyPressed(KeyEvent event) {
if (this.menu.getCarried().isEmpty() && this.hoveredSlot != null) {
if (this.minecraft.options.keySwapOffhand.matches(event)) {
this.slotClicked(this.hoveredSlot, this.hoveredSlot.index, 40, ContainerInput.SWAP);
return true;
}
for (int i = 0; i < 9; i++) {
if (this.minecraft.options.keyHotbarSlots[i].matches(event)) {
this.slotClicked(this.hoveredSlot, this.hoveredSlot.index, i, ContainerInput.SWAP);
return true;
}
}
}
return false;
}
@Override
public void removed() {
if (this.minecraft.player != null) {
this.menu.removed(this.minecraft.player);
}
}
@Override
public boolean isPauseScreen() {
return false;
}
@Override
public boolean isInGameUi() {
return true;
}
@Override
public final void tick() {
super.tick();
if (this.minecraft.player.isAlive() && !this.minecraft.player.isRemoved()) {
this.containerTick();
} else {
this.minecraft.player.closeContainer();
}
}
protected void containerTick() {
}
private boolean shouldAddSlotToQuickCraft(Slot slot, ItemStack carried) {
return this.isQuickCrafting
&& !carried.isEmpty()
&& (carried.getCount() > this.quickCraftSlots.size() || this.quickCraftingType == 2)
&& AbstractContainerMenu.canItemQuickReplace(slot, carried, true)
&& slot.mayPlace(carried)
&& this.menu.canDragTo(slot);
}
private void quickCraftToSlots() {
this.slotClicked(null, -999, AbstractContainerMenu.getQuickcraftMask(0, this.quickCraftingType), ContainerInput.QUICK_CRAFT);
for (Slot quickSlot : this.quickCraftSlots) {
this.slotClicked(quickSlot, quickSlot.index, AbstractContainerMenu.getQuickcraftMask(1, this.quickCraftingType), ContainerInput.QUICK_CRAFT);
}
this.slotClicked(null, -999, AbstractContainerMenu.getQuickcraftMask(2, this.quickCraftingType), ContainerInput.QUICK_CRAFT);
}
@Override
public T getMenu() {
return this.menu;
}
@Override
public void onClose() {
this.minecraft.player.closeContainer();
if (this.hoveredSlot != null) {
this.onStopHovering(this.hoveredSlot);
}
super.onClose();
}
@OnlyIn(Dist.CLIENT)
private record SnapbackData(ItemStack item, Vector2i start, Vector2i end, long time) {
}
}引用的其他类
-
- 引用位置:
构造调用 - 关联成员:
BundleMouseActions()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数/字段
- 引用位置:
-
- 引用位置:
继承
- 引用位置:
-
- 引用位置:
实现
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数/字段/返回值
- 引用位置:
-
- 引用位置:
字段/方法调用 - 关联成员:
Identifier.withDefaultNamespace()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Mth.ceil(), Mth.clamp()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Util.getMillis()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
AbstractContainerMenu.canItemQuickReplace(), AbstractContainerMenu.getQuickCraftPlaceCount(), AbstractContainerMenu.getQuickcraftMask()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数/字段/返回值
- 引用位置:
-
- 引用位置:
参数/字段
- 引用位置: