minecraft-src/net/minecraft/client/gui/screens/inventory/AbstractContainerScreen.java
2025-07-04 03:45:38 +03:00

737 lines
24 KiB
Java

package net.minecraft.client.gui.screens.inventory;
import com.google.common.collect.Sets;
import com.mojang.blaze3d.platform.InputConstants;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.ChatFormatting;
import net.minecraft.Util;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.BundleMouseActions;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.ItemSlotMouseAction;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent;
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.entity.player.Inventory;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.inventory.ClickType;
import net.minecraft.world.inventory.Slot;
import net.minecraft.world.item.ItemStack;
import org.jetbrains.annotations.Nullable;
@Environment(EnvType.CLIENT)
public abstract class AbstractContainerScreen<T extends AbstractContainerMenu> extends Screen implements MenuAccess<T> {
/**
* The location of the inventory background texture
*/
public static final ResourceLocation INVENTORY_LOCATION = ResourceLocation.withDefaultNamespace("textures/gui/container/inventory.png");
private static final ResourceLocation SLOT_HIGHLIGHT_BACK_SPRITE = ResourceLocation.withDefaultNamespace("container/slot_highlight_back");
private static final ResourceLocation SLOT_HIGHLIGHT_FRONT_SPRITE = ResourceLocation.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;
public static final int SLOT_ITEM_BLIT_OFFSET = 100;
private static final int HOVER_ITEM_BLIT_OFFSET = 200;
/**
* The X size of the inventory window in pixels.
*/
protected int imageWidth = 176;
/**
* The Y size of the inventory window in pixels.
*/
protected int imageHeight = 166;
protected int titleLabelX;
protected int titleLabelY;
protected int inventoryLabelX;
protected int inventoryLabelY;
private final List<ItemSlotMouseAction> itemSlotMouseActions;
/**
* A list of the players inventory slots
*/
protected final T menu;
protected final Component playerInventoryTitle;
/**
* Holds the slot currently hovered
*/
@Nullable
protected Slot hoveredSlot;
/**
* Used when touchscreen is enabled
*/
@Nullable
private Slot clickedSlot;
@Nullable
private Slot snapbackEnd;
@Nullable
private Slot quickdropSlot;
@Nullable
private Slot lastClickSlot;
/**
* Starting X position for the Gui. Inconsistent use for Gui backgrounds.
*/
protected int leftPos;
/**
* Starting Y position for the Gui. Inconsistent use for Gui backgrounds.
*/
protected int topPos;
/**
* Used when touchscreen is enabled.
*/
private boolean isSplittingStack;
/**
* Used when touchscreen is enabled
*/
private ItemStack draggingItem = ItemStack.EMPTY;
private int snapbackStartX;
private int snapbackStartY;
private long snapbackTime;
/**
* Used when touchscreen is enabled
*/
private ItemStack snapbackItem = ItemStack.EMPTY;
private long quickdropTime;
protected final Set<Slot> quickCraftSlots = Sets.<Slot>newHashSet();
protected boolean isQuickCrafting;
private int quickCraftingType;
private int quickCraftingButton;
private boolean skipNextRelease;
private int quickCraftingRemainder;
private long lastClickTime;
private int lastClickButton;
private boolean doubleclick;
private ItemStack lastQuickMoved = ItemStack.EMPTY;
public AbstractContainerScreen(T menu, Inventory playerInventory, Component title) {
super(title);
this.menu = menu;
this.playerInventoryTitle = playerInventory.getDisplayName();
this.skipNextRelease = true;
this.titleLabelX = 8;
this.titleLabelY = 6;
this.inventoryLabelX = 8;
this.inventoryLabelY = this.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 render(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) {
int i = this.leftPos;
int j = this.topPos;
super.render(guiGraphics, mouseX, mouseY, partialTick);
guiGraphics.pose().pushPose();
guiGraphics.pose().translate((float)i, (float)j, 0.0F);
Slot slot = this.hoveredSlot;
this.hoveredSlot = this.getHoveredSlot(mouseX, mouseY);
this.renderSlotHighlightBack(guiGraphics);
this.renderSlots(guiGraphics);
this.renderSlotHighlightFront(guiGraphics);
if (slot != null && slot != this.hoveredSlot) {
this.onStopHovering(slot);
}
this.renderLabels(guiGraphics, mouseX, mouseY);
ItemStack itemStack = this.draggingItem.isEmpty() ? this.menu.getCarried() : this.draggingItem;
if (!itemStack.isEmpty()) {
int k = 8;
int l = this.draggingItem.isEmpty() ? 8 : 16;
String string = null;
if (!this.draggingItem.isEmpty() && this.isSplittingStack) {
itemStack = itemStack.copyWithCount(Mth.ceil(itemStack.getCount() / 2.0F));
} else if (this.isQuickCrafting && this.quickCraftSlots.size() > 1) {
itemStack = itemStack.copyWithCount(this.quickCraftingRemainder);
if (itemStack.isEmpty()) {
string = ChatFormatting.YELLOW + "0";
}
}
this.renderFloatingItem(guiGraphics, itemStack, mouseX - i - 8, mouseY - j - l, string);
}
if (!this.snapbackItem.isEmpty()) {
float f = (float)(Util.getMillis() - this.snapbackTime) / 100.0F;
if (f >= 1.0F) {
f = 1.0F;
this.snapbackItem = ItemStack.EMPTY;
}
int l = this.snapbackEnd.x - this.snapbackStartX;
int m = this.snapbackEnd.y - this.snapbackStartY;
int n = this.snapbackStartX + (int)(l * f);
int o = this.snapbackStartY + (int)(m * f);
this.renderFloatingItem(guiGraphics, this.snapbackItem, n, o, null);
}
guiGraphics.pose().popPose();
}
protected void renderSlots(GuiGraphics guiGraphics) {
for (Slot slot : this.menu.slots) {
if (slot.isActive()) {
this.renderSlot(guiGraphics, slot);
}
}
}
@Override
public void renderBackground(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) {
this.renderTransparentBackground(guiGraphics);
this.renderBg(guiGraphics, partialTick, mouseX, mouseY);
}
@Override
public boolean mouseScrolled(double mouseX, double mouseY, double scrollX, double scrollY) {
if (this.hoveredSlot != null && this.hoveredSlot.hasItem()) {
for (ItemSlotMouseAction itemSlotMouseAction : this.itemSlotMouseActions) {
if (itemSlotMouseAction.matches(this.hoveredSlot)
&& itemSlotMouseAction.onMouseScrolled(scrollX, scrollY, this.hoveredSlot.index, this.hoveredSlot.getItem())) {
return true;
}
}
}
return false;
}
private void renderSlotHighlightBack(GuiGraphics guiGraphics) {
if (this.hoveredSlot != null && this.hoveredSlot.isHighlightable()) {
guiGraphics.blitSprite(RenderType::guiTextured, SLOT_HIGHLIGHT_BACK_SPRITE, this.hoveredSlot.x - 4, this.hoveredSlot.y - 4, 24, 24);
}
}
private void renderSlotHighlightFront(GuiGraphics guiGraphics) {
if (this.hoveredSlot != null && this.hoveredSlot.isHighlightable()) {
guiGraphics.blitSprite(RenderType::guiTexturedOverlay, SLOT_HIGHLIGHT_FRONT_SPRITE, this.hoveredSlot.x - 4, this.hoveredSlot.y - 4, 24, 24);
}
}
protected void renderTooltip(GuiGraphics guiGraphics, int x, int y) {
if (this.hoveredSlot != null && this.hoveredSlot.hasItem()) {
ItemStack itemStack = this.hoveredSlot.getItem();
if (this.menu.getCarried().isEmpty() || this.showTooltipWithItemInHand(itemStack)) {
guiGraphics.renderTooltip(
this.font, this.getTooltipFromContainerItem(itemStack), itemStack.getTooltipImage(), x, y, itemStack.get(DataComponents.TOOLTIP_STYLE)
);
}
}
}
private boolean showTooltipWithItemInHand(ItemStack stack) {
return (Boolean)stack.getTooltipImage().map(ClientTooltipComponent::create).map(ClientTooltipComponent::showTooltipWithItemInHand).orElse(false);
}
protected List<Component> getTooltipFromContainerItem(ItemStack stack) {
return getTooltipFromItem(this.minecraft, stack);
}
private void renderFloatingItem(GuiGraphics guiGraphics, ItemStack stack, int x, int y, @Nullable String text) {
guiGraphics.pose().pushPose();
guiGraphics.pose().translate(0.0F, 0.0F, 232.0F);
guiGraphics.renderItem(stack, x, y);
guiGraphics.renderItemDecorations(this.font, stack, x, y - (this.draggingItem.isEmpty() ? 0 : 8), text);
guiGraphics.pose().popPose();
}
protected void renderLabels(GuiGraphics guiGraphics, int mouseX, int mouseY) {
guiGraphics.drawString(this.font, this.title, this.titleLabelX, this.titleLabelY, 4210752, false);
guiGraphics.drawString(this.font, this.playerInventoryTitle, this.inventoryLabelX, this.inventoryLabelY, 4210752, false);
}
protected abstract void renderBg(GuiGraphics guiGraphics, float partialTick, int mouseX, int mouseY);
protected void renderSlot(GuiGraphics guiGraphics, Slot slot) {
int i = slot.x;
int j = slot.y;
ItemStack itemStack = slot.getItem();
boolean bl = false;
boolean bl2 = slot == this.clickedSlot && !this.draggingItem.isEmpty() && !this.isSplittingStack;
ItemStack itemStack2 = this.menu.getCarried();
String string = 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) && !itemStack2.isEmpty()) {
if (this.quickCraftSlots.size() == 1) {
return;
}
if (AbstractContainerMenu.canItemQuickReplace(slot, itemStack2, true) && this.menu.canDragTo(slot)) {
bl = true;
int k = Math.min(itemStack2.getMaxStackSize(), slot.getMaxStackSize(itemStack2));
int l = slot.getItem().isEmpty() ? 0 : slot.getItem().getCount();
int m = AbstractContainerMenu.getQuickCraftPlaceCount(this.quickCraftSlots, this.quickCraftingType, itemStack2) + l;
if (m > k) {
m = k;
string = ChatFormatting.YELLOW.toString() + k;
}
itemStack = itemStack2.copyWithCount(m);
} else {
this.quickCraftSlots.remove(slot);
this.recalculateQuickCraftRemaining();
}
}
guiGraphics.pose().pushPose();
guiGraphics.pose().translate(0.0F, 0.0F, 100.0F);
if (itemStack.isEmpty() && slot.isActive()) {
ResourceLocation resourceLocation = slot.getNoItemIcon();
if (resourceLocation != null) {
guiGraphics.blitSprite(RenderType::guiTextured, resourceLocation, i, j, 16, 16);
bl2 = true;
}
}
if (!bl2) {
if (bl) {
guiGraphics.fill(i, j, i + 16, j + 16, -2130706433);
}
int k = slot.x + slot.y * this.imageWidth;
if (slot.isFake()) {
guiGraphics.renderFakeItem(itemStack, i, j, k);
} else {
guiGraphics.renderItem(itemStack, i, j, k);
}
guiGraphics.renderItemDecorations(this.font, itemStack, i, j, string);
}
guiGraphics.pose().popPose();
}
private void recalculateQuickCraftRemaining() {
ItemStack itemStack = this.menu.getCarried();
if (!itemStack.isEmpty() && this.isQuickCrafting) {
if (this.quickCraftingType == 2) {
this.quickCraftingRemainder = itemStack.getMaxStackSize();
} else {
this.quickCraftingRemainder = itemStack.getCount();
for (Slot slot : this.quickCraftSlots) {
ItemStack itemStack2 = slot.getItem();
int i = itemStack2.isEmpty() ? 0 : itemStack2.getCount();
int j = Math.min(itemStack.getMaxStackSize(), slot.getMaxStackSize(itemStack));
int k = Math.min(AbstractContainerMenu.getQuickCraftPlaceCount(this.quickCraftSlots, this.quickCraftingType, itemStack) + i, j);
this.quickCraftingRemainder -= k - i;
}
}
}
}
@Nullable
private Slot getHoveredSlot(double mouseX, double mouseY) {
for (Slot slot : this.menu.slots) {
if (slot.isActive() && this.isHovering(slot, mouseX, mouseY)) {
return slot;
}
}
return null;
}
@Override
public boolean mouseClicked(double mouseX, double mouseY, int button) {
if (super.mouseClicked(mouseX, mouseY, button)) {
return true;
} else {
boolean bl = this.minecraft.options.keyPickItem.matchesMouse(button) && this.minecraft.player.hasInfiniteMaterials();
Slot slot = this.getHoveredSlot(mouseX, mouseY);
long l = Util.getMillis();
this.doubleclick = this.lastClickSlot == slot && l - this.lastClickTime < 250L && this.lastClickButton == button;
this.skipNextRelease = false;
if (button != 0 && button != 1 && !bl) {
this.checkHotbarMouseClicked(button);
} else {
int i = this.leftPos;
int j = this.topPos;
boolean bl2 = this.hasClickedOutside(mouseX, mouseY, i, j, button);
int k = -1;
if (slot != null) {
k = slot.index;
}
if (bl2) {
k = -999;
}
if (this.minecraft.options.touchscreen().get() && bl2 && this.menu.getCarried().isEmpty()) {
this.onClose();
return true;
}
if (k != -1) {
if (this.minecraft.options.touchscreen().get()) {
if (slot != null && slot.hasItem()) {
this.clickedSlot = slot;
this.draggingItem = ItemStack.EMPTY;
this.isSplittingStack = button == 1;
} else {
this.clickedSlot = null;
}
} else if (!this.isQuickCrafting) {
if (this.menu.getCarried().isEmpty()) {
if (bl) {
this.slotClicked(slot, k, button, ClickType.CLONE);
} else {
boolean bl3 = k != -999
&& (
InputConstants.isKeyDown(Minecraft.getInstance().getWindow().getWindow(), 340)
|| InputConstants.isKeyDown(Minecraft.getInstance().getWindow().getWindow(), 344)
);
ClickType clickType = ClickType.PICKUP;
if (bl3) {
this.lastQuickMoved = slot != null && slot.hasItem() ? slot.getItem().copy() : ItemStack.EMPTY;
clickType = ClickType.QUICK_MOVE;
} else if (k == -999) {
clickType = ClickType.THROW;
}
this.slotClicked(slot, k, button, clickType);
}
this.skipNextRelease = true;
} else {
this.isQuickCrafting = true;
this.quickCraftingButton = button;
this.quickCraftSlots.clear();
if (button == 0) {
this.quickCraftingType = 0;
} else if (button == 1) {
this.quickCraftingType = 1;
} else if (bl) {
this.quickCraftingType = 2;
}
}
}
}
}
this.lastClickSlot = slot;
this.lastClickTime = l;
this.lastClickButton = button;
return true;
}
}
private void checkHotbarMouseClicked(int keyCode) {
if (this.hoveredSlot != null && this.menu.getCarried().isEmpty()) {
if (this.minecraft.options.keySwapOffhand.matchesMouse(keyCode)) {
this.slotClicked(this.hoveredSlot, this.hoveredSlot.index, 40, ClickType.SWAP);
return;
}
for (int i = 0; i < 9; i++) {
if (this.minecraft.options.keyHotbarSlots[i].matchesMouse(keyCode)) {
this.slotClicked(this.hoveredSlot, this.hoveredSlot.index, i, ClickType.SWAP);
}
}
}
}
protected boolean hasClickedOutside(double mouseX, double mouseY, int guiLeft, int guiTop, int mouseButton) {
return mouseX < guiLeft || mouseY < guiTop || mouseX >= guiLeft + this.imageWidth || mouseY >= guiTop + this.imageHeight;
}
@Override
public boolean mouseDragged(double mouseX, double mouseY, int button, double dragX, double dragY) {
Slot slot = this.getHoveredSlot(mouseX, mouseY);
ItemStack itemStack = this.menu.getCarried();
if (this.clickedSlot != null && this.minecraft.options.touchscreen().get()) {
if (button == 0 || 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 l = Util.getMillis();
if (this.quickdropSlot == slot) {
if (l - this.quickdropTime > 500L) {
this.slotClicked(this.clickedSlot, this.clickedSlot.index, 0, ClickType.PICKUP);
this.slotClicked(slot, slot.index, 1, ClickType.PICKUP);
this.slotClicked(this.clickedSlot, this.clickedSlot.index, 0, ClickType.PICKUP);
this.quickdropTime = l + 750L;
this.draggingItem.shrink(1);
}
} else {
this.quickdropSlot = slot;
this.quickdropTime = l;
}
}
}
} else if (this.isQuickCrafting
&& slot != null
&& !itemStack.isEmpty()
&& (itemStack.getCount() > this.quickCraftSlots.size() || this.quickCraftingType == 2)
&& AbstractContainerMenu.canItemQuickReplace(slot, itemStack, true)
&& slot.mayPlace(itemStack)
&& this.menu.canDragTo(slot)) {
this.quickCraftSlots.add(slot);
this.recalculateQuickCraftRemaining();
}
return true;
}
@Override
public boolean mouseReleased(double mouseX, double mouseY, int button) {
Slot slot = this.getHoveredSlot(mouseX, mouseY);
int i = this.leftPos;
int j = this.topPos;
boolean bl = this.hasClickedOutside(mouseX, mouseY, i, j, button);
int k = -1;
if (slot != null) {
k = slot.index;
}
if (bl) {
k = -999;
}
if (this.doubleclick && slot != null && button == 0 && this.menu.canTakeItemForPickAll(ItemStack.EMPTY, slot)) {
if (hasShiftDown()) {
if (!this.lastQuickMoved.isEmpty()) {
for (Slot slot2 : this.menu.slots) {
if (slot2 != null
&& slot2.mayPickup(this.minecraft.player)
&& slot2.hasItem()
&& slot2.container == slot.container
&& AbstractContainerMenu.canItemQuickReplace(slot2, this.lastQuickMoved, true)) {
this.slotClicked(slot2, slot2.index, button, ClickType.QUICK_MOVE);
}
}
}
} else {
this.slotClicked(slot, k, button, ClickType.PICKUP_ALL);
}
this.doubleclick = false;
this.lastClickTime = 0L;
} else {
if (this.isQuickCrafting && this.quickCraftingButton != 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 (button == 0 || button == 1) {
if (this.draggingItem.isEmpty() && slot != this.clickedSlot) {
this.draggingItem = this.clickedSlot.getItem();
}
boolean bl2 = AbstractContainerMenu.canItemQuickReplace(slot, this.draggingItem, false);
if (k != -1 && !this.draggingItem.isEmpty() && bl2) {
this.slotClicked(this.clickedSlot, this.clickedSlot.index, button, ClickType.PICKUP);
this.slotClicked(slot, k, 0, ClickType.PICKUP);
if (this.menu.getCarried().isEmpty()) {
this.snapbackItem = ItemStack.EMPTY;
} else {
this.slotClicked(this.clickedSlot, this.clickedSlot.index, button, ClickType.PICKUP);
this.snapbackStartX = Mth.floor(mouseX - i);
this.snapbackStartY = Mth.floor(mouseY - j);
this.snapbackEnd = this.clickedSlot;
this.snapbackItem = this.draggingItem;
this.snapbackTime = Util.getMillis();
}
} else if (!this.draggingItem.isEmpty()) {
this.snapbackStartX = Mth.floor(mouseX - i);
this.snapbackStartY = Mth.floor(mouseY - j);
this.snapbackEnd = this.clickedSlot;
this.snapbackItem = this.draggingItem;
this.snapbackTime = Util.getMillis();
}
this.clearDraggingState();
}
} else if (this.isQuickCrafting && !this.quickCraftSlots.isEmpty()) {
this.slotClicked(null, -999, AbstractContainerMenu.getQuickcraftMask(0, this.quickCraftingType), ClickType.QUICK_CRAFT);
for (Slot slot2x : this.quickCraftSlots) {
this.slotClicked(slot2x, slot2x.index, AbstractContainerMenu.getQuickcraftMask(1, this.quickCraftingType), ClickType.QUICK_CRAFT);
}
this.slotClicked(null, -999, AbstractContainerMenu.getQuickcraftMask(2, this.quickCraftingType), ClickType.QUICK_CRAFT);
} else if (!this.menu.getCarried().isEmpty()) {
if (this.minecraft.options.keyPickItem.matchesMouse(button)) {
this.slotClicked(slot, k, button, ClickType.CLONE);
} else {
boolean bl2 = k != -999
&& (
InputConstants.isKeyDown(Minecraft.getInstance().getWindow().getWindow(), 340)
|| InputConstants.isKeyDown(Minecraft.getInstance().getWindow().getWindow(), 344)
);
if (bl2) {
this.lastQuickMoved = slot != null && slot.hasItem() ? slot.getItem().copy() : ItemStack.EMPTY;
}
this.slotClicked(slot, k, button, bl2 ? ClickType.QUICK_MOVE : ClickType.PICKUP);
}
}
}
if (this.menu.getCarried().isEmpty()) {
this.lastClickTime = 0L;
}
this.isQuickCrafting = false;
return true;
}
public void clearDraggingState() {
this.draggingItem = ItemStack.EMPTY;
this.clickedSlot = null;
}
private boolean isHovering(Slot slot, double mouseX, double mouseY) {
return this.isHovering(slot.x, slot.y, 16, 16, mouseX, mouseY);
}
protected boolean isHovering(int x, int y, int width, int height, double mouseX, double mouseY) {
int i = this.leftPos;
int j = this.topPos;
mouseX -= i;
mouseY -= j;
return mouseX >= x - 1 && mouseX < x + width + 1 && mouseY >= y - 1 && mouseY < y + height + 1;
}
private void onStopHovering(Slot slot) {
if (slot.hasItem()) {
for (ItemSlotMouseAction itemSlotMouseAction : this.itemSlotMouseActions) {
if (itemSlotMouseAction.matches(slot)) {
itemSlotMouseAction.onStopHovering(slot);
}
}
}
}
/**
* Called when the mouse is clicked over a slot or outside the gui.
*/
protected void slotClicked(Slot slot, int slotId, int mouseButton, ClickType type) {
if (slot != null) {
slotId = slot.index;
}
this.onMouseClickAction(slot, type);
this.minecraft.gameMode.handleInventoryMouseClick(this.menu.containerId, slotId, mouseButton, type, this.minecraft.player);
}
void onMouseClickAction(@Nullable Slot slot, ClickType type) {
if (slot != null && slot.hasItem()) {
for (ItemSlotMouseAction itemSlotMouseAction : this.itemSlotMouseActions) {
if (itemSlotMouseAction.matches(slot)) {
itemSlotMouseAction.onSlotClicked(slot, type);
}
}
}
}
protected void handleSlotStateChanged(int slotId, int containerId, boolean newState) {
this.minecraft.gameMode.handleSlotStateChanged(slotId, containerId, newState);
}
@Override
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
if (super.keyPressed(keyCode, scanCode, modifiers)) {
return true;
} else if (this.minecraft.options.keyInventory.matches(keyCode, scanCode)) {
this.onClose();
return true;
} else {
this.checkHotbarKeyPressed(keyCode, scanCode);
if (this.hoveredSlot != null && this.hoveredSlot.hasItem()) {
if (this.minecraft.options.keyPickItem.matches(keyCode, scanCode)) {
this.slotClicked(this.hoveredSlot, this.hoveredSlot.index, 0, ClickType.CLONE);
} else if (this.minecraft.options.keyDrop.matches(keyCode, scanCode)) {
this.slotClicked(this.hoveredSlot, this.hoveredSlot.index, hasControlDown() ? 1 : 0, ClickType.THROW);
}
}
return true;
}
}
protected boolean checkHotbarKeyPressed(int keyCode, int scanCode) {
if (this.menu.getCarried().isEmpty() && this.hoveredSlot != null) {
if (this.minecraft.options.keySwapOffhand.matches(keyCode, scanCode)) {
this.slotClicked(this.hoveredSlot, this.hoveredSlot.index, 40, ClickType.SWAP);
return true;
}
for (int i = 0; i < 9; i++) {
if (this.minecraft.options.keyHotbarSlots[i].matches(keyCode, scanCode)) {
this.slotClicked(this.hoveredSlot, this.hoveredSlot.index, i, ClickType.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 final void tick() {
super.tick();
if (this.minecraft.player.isAlive() && !this.minecraft.player.isRemoved()) {
this.containerTick();
} else {
this.minecraft.player.closeContainer();
}
}
protected void containerTick() {
}
@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();
}
}