179 lines
5.6 KiB
Java
179 lines
5.6 KiB
Java
package net.minecraft.world.inventory;
|
|
|
|
import java.util.List;
|
|
import java.util.Optional;
|
|
import net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket;
|
|
import net.minecraft.server.level.ServerLevel;
|
|
import net.minecraft.server.level.ServerPlayer;
|
|
import net.minecraft.world.Container;
|
|
import net.minecraft.world.entity.player.Inventory;
|
|
import net.minecraft.world.entity.player.Player;
|
|
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;
|
|
import net.minecraft.world.item.crafting.RecipeType;
|
|
import net.minecraft.world.level.block.Blocks;
|
|
import org.jetbrains.annotations.Nullable;
|
|
|
|
public class CraftingMenu extends AbstractCraftingMenu {
|
|
private static final int CRAFTING_GRID_WIDTH = 3;
|
|
private static final int CRAFTING_GRID_HEIGHT = 3;
|
|
public static final int RESULT_SLOT = 0;
|
|
private static final int CRAFT_SLOT_START = 1;
|
|
private static final int CRAFT_SLOT_COUNT = 9;
|
|
private static final int CRAFT_SLOT_END = 10;
|
|
private static final int INV_SLOT_START = 10;
|
|
private static final int INV_SLOT_END = 37;
|
|
private static final int USE_ROW_SLOT_START = 37;
|
|
private static final int USE_ROW_SLOT_END = 46;
|
|
private final ContainerLevelAccess access;
|
|
private final Player player;
|
|
private boolean placingRecipe;
|
|
|
|
public CraftingMenu(int containerId, Inventory playerInventory) {
|
|
this(containerId, playerInventory, ContainerLevelAccess.NULL);
|
|
}
|
|
|
|
public CraftingMenu(int containerId, Inventory playerInventory, ContainerLevelAccess access) {
|
|
super(MenuType.CRAFTING, containerId, 3, 3);
|
|
this.access = access;
|
|
this.player = playerInventory.player;
|
|
this.addResultSlot(this.player, 124, 35);
|
|
this.addCraftingGridSlots(30, 17);
|
|
this.addStandardInventorySlots(playerInventory, 8, 84);
|
|
}
|
|
|
|
protected static void slotChangedCraftingGrid(
|
|
AbstractContainerMenu menu,
|
|
ServerLevel level,
|
|
Player player,
|
|
CraftingContainer craftSlots,
|
|
ResultContainer resultSlots,
|
|
@Nullable RecipeHolder<CraftingRecipe> recipe
|
|
) {
|
|
CraftingInput craftingInput = craftSlots.asCraftInput();
|
|
ServerPlayer serverPlayer = (ServerPlayer)player;
|
|
ItemStack itemStack = ItemStack.EMPTY;
|
|
Optional<RecipeHolder<CraftingRecipe>> optional = level.getServer().getRecipeManager().getRecipeFor(RecipeType.CRAFTING, craftingInput, level, recipe);
|
|
if (optional.isPresent()) {
|
|
RecipeHolder<CraftingRecipe> recipeHolder = (RecipeHolder<CraftingRecipe>)optional.get();
|
|
CraftingRecipe craftingRecipe = recipeHolder.value();
|
|
if (resultSlots.setRecipeUsed(serverPlayer, recipeHolder)) {
|
|
ItemStack itemStack2 = craftingRecipe.assemble(craftingInput, level.registryAccess());
|
|
if (itemStack2.isItemEnabled(level.enabledFeatures())) {
|
|
itemStack = itemStack2;
|
|
}
|
|
}
|
|
}
|
|
|
|
resultSlots.setItem(0, itemStack);
|
|
menu.setRemoteSlot(0, itemStack);
|
|
serverPlayer.connection.send(new ClientboundContainerSetSlotPacket(menu.containerId, menu.incrementStateId(), 0, itemStack));
|
|
}
|
|
|
|
@Override
|
|
public void slotsChanged(Container container) {
|
|
if (!this.placingRecipe) {
|
|
this.access.execute((level, blockPos) -> {
|
|
if (level instanceof ServerLevel serverLevel) {
|
|
slotChangedCraftingGrid(this, serverLevel, this.player, this.craftSlots, this.resultSlots, null);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void beginPlacingRecipe() {
|
|
this.placingRecipe = true;
|
|
}
|
|
|
|
@Override
|
|
public void finishPlacingRecipe(ServerLevel level, RecipeHolder<CraftingRecipe> recipe) {
|
|
this.placingRecipe = false;
|
|
slotChangedCraftingGrid(this, level, this.player, this.craftSlots, this.resultSlots, recipe);
|
|
}
|
|
|
|
@Override
|
|
public void removed(Player player) {
|
|
super.removed(player);
|
|
this.access.execute((level, blockPos) -> this.clearContainer(player, this.craftSlots));
|
|
}
|
|
|
|
@Override
|
|
public boolean stillValid(Player player) {
|
|
return stillValid(this.access, player, Blocks.CRAFTING_TABLE);
|
|
}
|
|
|
|
@Override
|
|
public ItemStack quickMoveStack(Player player, int index) {
|
|
ItemStack itemStack = ItemStack.EMPTY;
|
|
Slot slot = this.slots.get(index);
|
|
if (slot != null && slot.hasItem()) {
|
|
ItemStack itemStack2 = slot.getItem();
|
|
itemStack = itemStack2.copy();
|
|
if (index == 0) {
|
|
itemStack2.getItem().onCraftedBy(itemStack2, player);
|
|
if (!this.moveItemStackTo(itemStack2, 10, 46, true)) {
|
|
return ItemStack.EMPTY;
|
|
}
|
|
|
|
slot.onQuickCraft(itemStack2, itemStack);
|
|
} else if (index >= 10 && index < 46) {
|
|
if (!this.moveItemStackTo(itemStack2, 1, 10, false)) {
|
|
if (index < 37) {
|
|
if (!this.moveItemStackTo(itemStack2, 37, 46, false)) {
|
|
return ItemStack.EMPTY;
|
|
}
|
|
} else if (!this.moveItemStackTo(itemStack2, 10, 37, false)) {
|
|
return ItemStack.EMPTY;
|
|
}
|
|
}
|
|
} else if (!this.moveItemStackTo(itemStack2, 10, 46, false)) {
|
|
return ItemStack.EMPTY;
|
|
}
|
|
|
|
if (itemStack2.isEmpty()) {
|
|
slot.setByPlayer(ItemStack.EMPTY);
|
|
} 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 Slot getResultSlot() {
|
|
return this.slots.get(0);
|
|
}
|
|
|
|
@Override
|
|
public List<Slot> getInputGridSlots() {
|
|
return this.slots.subList(1, 10);
|
|
}
|
|
|
|
@Override
|
|
public RecipeBookType getRecipeBookType() {
|
|
return RecipeBookType.CRAFTING;
|
|
}
|
|
|
|
@Override
|
|
protected Player owner() {
|
|
return this.player;
|
|
}
|
|
}
|