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 { 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 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 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 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(); } }