minecraft-src/net/minecraft/world/inventory/InventoryMenu.java
2025-07-04 01:41:11 +03:00

233 lines
7.6 KiB
Java

package net.minecraft.world.inventory;
import com.mojang.datafixers.util.Pair;
import java.util.Map;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.Container;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.player.StackedContents;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.CraftingInput;
import net.minecraft.world.item.crafting.CraftingRecipe;
import net.minecraft.world.item.crafting.RecipeHolder;
public class InventoryMenu extends RecipeBookMenu<CraftingInput, CraftingRecipe> {
public static final int CONTAINER_ID = 0;
public static final int RESULT_SLOT = 0;
public static final int CRAFT_SLOT_START = 1;
public static final int CRAFT_SLOT_COUNT = 4;
public static final int CRAFT_SLOT_END = 5;
public static final int ARMOR_SLOT_START = 5;
public static final int ARMOR_SLOT_COUNT = 4;
public static final int ARMOR_SLOT_END = 9;
public static final int INV_SLOT_START = 9;
public static final int INV_SLOT_END = 36;
public static final int USE_ROW_SLOT_START = 36;
public static final int USE_ROW_SLOT_END = 45;
public static final int SHIELD_SLOT = 45;
public static final ResourceLocation BLOCK_ATLAS = ResourceLocation.withDefaultNamespace("textures/atlas/blocks.png");
public static final ResourceLocation EMPTY_ARMOR_SLOT_HELMET = ResourceLocation.withDefaultNamespace("item/empty_armor_slot_helmet");
public static final ResourceLocation EMPTY_ARMOR_SLOT_CHESTPLATE = ResourceLocation.withDefaultNamespace("item/empty_armor_slot_chestplate");
public static final ResourceLocation EMPTY_ARMOR_SLOT_LEGGINGS = ResourceLocation.withDefaultNamespace("item/empty_armor_slot_leggings");
public static final ResourceLocation EMPTY_ARMOR_SLOT_BOOTS = ResourceLocation.withDefaultNamespace("item/empty_armor_slot_boots");
public static final ResourceLocation EMPTY_ARMOR_SLOT_SHIELD = ResourceLocation.withDefaultNamespace("item/empty_armor_slot_shield");
private static final Map<EquipmentSlot, ResourceLocation> TEXTURE_EMPTY_SLOTS = Map.of(
EquipmentSlot.FEET,
EMPTY_ARMOR_SLOT_BOOTS,
EquipmentSlot.LEGS,
EMPTY_ARMOR_SLOT_LEGGINGS,
EquipmentSlot.CHEST,
EMPTY_ARMOR_SLOT_CHESTPLATE,
EquipmentSlot.HEAD,
EMPTY_ARMOR_SLOT_HELMET
);
private static final EquipmentSlot[] SLOT_IDS = new EquipmentSlot[]{EquipmentSlot.HEAD, EquipmentSlot.CHEST, EquipmentSlot.LEGS, EquipmentSlot.FEET};
private final CraftingContainer craftSlots = new TransientCraftingContainer(this, 2, 2);
private final ResultContainer resultSlots = new ResultContainer();
public final boolean active;
private final Player owner;
public InventoryMenu(Inventory playerInventory, boolean active, Player owner) {
super(null, 0);
this.active = active;
this.owner = owner;
this.addSlot(new ResultSlot(playerInventory.player, this.craftSlots, this.resultSlots, 0, 154, 28));
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
this.addSlot(new Slot(this.craftSlots, j + i * 2, 98 + j * 18, 18 + i * 18));
}
}
for (int i = 0; i < 4; i++) {
EquipmentSlot equipmentSlot = SLOT_IDS[i];
ResourceLocation resourceLocation = (ResourceLocation)TEXTURE_EMPTY_SLOTS.get(equipmentSlot);
this.addSlot(new ArmorSlot(playerInventory, owner, equipmentSlot, 39 - i, 8, 8 + i * 18, resourceLocation));
}
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 9; j++) {
this.addSlot(new Slot(playerInventory, j + (i + 1) * 9, 8 + j * 18, 84 + i * 18));
}
}
for (int i = 0; i < 9; i++) {
this.addSlot(new Slot(playerInventory, i, 8 + i * 18, 142));
}
this.addSlot(new Slot(playerInventory, 40, 77, 62) {
@Override
public void setByPlayer(ItemStack newStack, ItemStack oldStack) {
owner.onEquipItem(EquipmentSlot.OFFHAND, oldStack, newStack);
super.setByPlayer(newStack, oldStack);
}
@Override
public Pair<ResourceLocation, ResourceLocation> getNoItemIcon() {
return Pair.of(InventoryMenu.BLOCK_ATLAS, InventoryMenu.EMPTY_ARMOR_SLOT_SHIELD);
}
});
}
public static boolean isHotbarSlot(int index) {
return index >= 36 && index < 45 || index == 45;
}
@Override
public void fillCraftSlotsStackedContents(StackedContents itemHelper) {
this.craftSlots.fillStackedContents(itemHelper);
}
@Override
public void clearCraftingContent() {
this.resultSlots.clearContent();
this.craftSlots.clearContent();
}
@Override
public boolean recipeMatches(RecipeHolder<CraftingRecipe> recipe) {
return recipe.value().matches(this.craftSlots.asCraftInput(), this.owner.level());
}
@Override
public void slotsChanged(Container container) {
CraftingMenu.slotChangedCraftingGrid(this, this.owner.level(), this.owner, this.craftSlots, this.resultSlots, null);
}
@Override
public void removed(Player player) {
super.removed(player);
this.resultSlots.clearContent();
if (!player.level().isClientSide) {
this.clearContainer(player, this.craftSlots);
}
}
@Override
public boolean stillValid(Player player) {
return true;
}
@Override
public ItemStack quickMoveStack(Player player, int index) {
ItemStack itemStack = ItemStack.EMPTY;
Slot slot = this.slots.get(index);
if (slot.hasItem()) {
ItemStack itemStack2 = slot.getItem();
itemStack = itemStack2.copy();
EquipmentSlot equipmentSlot = player.getEquipmentSlotForItem(itemStack);
if (index == 0) {
if (!this.moveItemStackTo(itemStack2, 9, 45, true)) {
return ItemStack.EMPTY;
}
slot.onQuickCraft(itemStack2, itemStack);
} else if (index >= 1 && index < 5) {
if (!this.moveItemStackTo(itemStack2, 9, 45, false)) {
return ItemStack.EMPTY;
}
} else if (index >= 5 && index < 9) {
if (!this.moveItemStackTo(itemStack2, 9, 45, false)) {
return ItemStack.EMPTY;
}
} else if (equipmentSlot.getType() == EquipmentSlot.Type.HUMANOID_ARMOR && !this.slots.get(8 - equipmentSlot.getIndex()).hasItem()) {
int i = 8 - equipmentSlot.getIndex();
if (!this.moveItemStackTo(itemStack2, i, i + 1, false)) {
return ItemStack.EMPTY;
}
} else if (equipmentSlot == EquipmentSlot.OFFHAND && !this.slots.get(45).hasItem()) {
if (!this.moveItemStackTo(itemStack2, 45, 46, false)) {
return ItemStack.EMPTY;
}
} else if (index >= 9 && index < 36) {
if (!this.moveItemStackTo(itemStack2, 36, 45, false)) {
return ItemStack.EMPTY;
}
} else if (index >= 36 && index < 45) {
if (!this.moveItemStackTo(itemStack2, 9, 36, false)) {
return ItemStack.EMPTY;
}
} else if (!this.moveItemStackTo(itemStack2, 9, 45, false)) {
return ItemStack.EMPTY;
}
if (itemStack2.isEmpty()) {
slot.setByPlayer(ItemStack.EMPTY, itemStack);
} else {
slot.setChanged();
}
if (itemStack2.getCount() == itemStack.getCount()) {
return ItemStack.EMPTY;
}
slot.onTake(player, itemStack2);
if (index == 0) {
player.drop(itemStack2, false);
}
}
return itemStack;
}
@Override
public boolean canTakeItemForPickAll(ItemStack stack, Slot slot) {
return slot.container != this.resultSlots && super.canTakeItemForPickAll(stack, slot);
}
@Override
public int getResultSlotIndex() {
return 0;
}
@Override
public int getGridWidth() {
return this.craftSlots.getWidth();
}
@Override
public int getGridHeight() {
return this.craftSlots.getHeight();
}
@Override
public int getSize() {
return 5;
}
public CraftingContainer getCraftSlots() {
return this.craftSlots;
}
@Override
public RecipeBookType getRecipeBookType() {
return RecipeBookType.CRAFTING;
}
@Override
public boolean shouldMoveToInventory(int slotIndex) {
return slotIndex != this.getResultSlotIndex();
}
}