237 lines
8.8 KiB
Java
237 lines
8.8 KiB
Java
|
package net.minecraft.world.inventory;
|
||
|
|
||
|
import java.util.List;
|
||
|
import java.util.Optional;
|
||
|
import net.minecraft.core.BlockPos;
|
||
|
import net.minecraft.sounds.SoundEvents;
|
||
|
import net.minecraft.sounds.SoundSource;
|
||
|
import net.minecraft.world.Container;
|
||
|
import net.minecraft.world.SimpleContainer;
|
||
|
import net.minecraft.world.entity.player.Inventory;
|
||
|
import net.minecraft.world.entity.player.Player;
|
||
|
import net.minecraft.world.item.Item;
|
||
|
import net.minecraft.world.item.ItemStack;
|
||
|
import net.minecraft.world.item.crafting.RecipeHolder;
|
||
|
import net.minecraft.world.item.crafting.SelectableRecipe;
|
||
|
import net.minecraft.world.item.crafting.SingleRecipeInput;
|
||
|
import net.minecraft.world.item.crafting.StonecutterRecipe;
|
||
|
import net.minecraft.world.level.Level;
|
||
|
import net.minecraft.world.level.block.Blocks;
|
||
|
|
||
|
public class StonecutterMenu extends AbstractContainerMenu {
|
||
|
public static final int INPUT_SLOT = 0;
|
||
|
public static final int RESULT_SLOT = 1;
|
||
|
private static final int INV_SLOT_START = 2;
|
||
|
private static final int INV_SLOT_END = 29;
|
||
|
private static final int USE_ROW_SLOT_START = 29;
|
||
|
private static final int USE_ROW_SLOT_END = 38;
|
||
|
private final ContainerLevelAccess access;
|
||
|
final DataSlot selectedRecipeIndex = DataSlot.standalone();
|
||
|
private final Level level;
|
||
|
private SelectableRecipe.SingleInputSet<StonecutterRecipe> recipesForInput = SelectableRecipe.SingleInputSet.empty();
|
||
|
private ItemStack input = ItemStack.EMPTY;
|
||
|
long lastSoundTime;
|
||
|
final Slot inputSlot;
|
||
|
final Slot resultSlot;
|
||
|
Runnable slotUpdateListener = () -> {};
|
||
|
public final Container container = new SimpleContainer(1) {
|
||
|
@Override
|
||
|
public void setChanged() {
|
||
|
super.setChanged();
|
||
|
StonecutterMenu.this.slotsChanged(this);
|
||
|
StonecutterMenu.this.slotUpdateListener.run();
|
||
|
}
|
||
|
};
|
||
|
final ResultContainer resultContainer = new ResultContainer();
|
||
|
|
||
|
public StonecutterMenu(int p_40294_, Inventory p_40295_) {
|
||
|
this(p_40294_, p_40295_, ContainerLevelAccess.NULL);
|
||
|
}
|
||
|
|
||
|
public StonecutterMenu(int p_40297_, Inventory p_40298_, final ContainerLevelAccess p_40299_) {
|
||
|
super(MenuType.STONECUTTER, p_40297_);
|
||
|
this.access = p_40299_;
|
||
|
this.level = p_40298_.player.level();
|
||
|
this.inputSlot = this.addSlot(new Slot(this.container, 0, 20, 33));
|
||
|
this.resultSlot = this.addSlot(new Slot(this.resultContainer, 1, 143, 33) {
|
||
|
@Override
|
||
|
public boolean mayPlace(ItemStack p_40362_) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void onTake(Player p_150672_, ItemStack p_150673_) {
|
||
|
p_150673_.onCraftedBy(p_150672_, p_150673_.getCount());
|
||
|
StonecutterMenu.this.resultContainer.awardUsedRecipes(p_150672_, this.getRelevantItems());
|
||
|
ItemStack itemstack = StonecutterMenu.this.inputSlot.remove(1);
|
||
|
if (!itemstack.isEmpty()) {
|
||
|
StonecutterMenu.this.setupResultSlot(StonecutterMenu.this.selectedRecipeIndex.get());
|
||
|
}
|
||
|
|
||
|
p_40299_.execute((p_390780_, p_390781_) -> {
|
||
|
long i = p_390780_.getGameTime();
|
||
|
if (StonecutterMenu.this.lastSoundTime != i) {
|
||
|
p_390780_.playSound(null, p_390781_, SoundEvents.UI_STONECUTTER_TAKE_RESULT, SoundSource.BLOCKS, 1.0F, 1.0F);
|
||
|
StonecutterMenu.this.lastSoundTime = i;
|
||
|
}
|
||
|
});
|
||
|
super.onTake(p_150672_, p_150673_);
|
||
|
}
|
||
|
|
||
|
private List<ItemStack> getRelevantItems() {
|
||
|
return List.of(StonecutterMenu.this.inputSlot.getItem());
|
||
|
}
|
||
|
});
|
||
|
this.addStandardInventorySlots(p_40298_, 8, 84);
|
||
|
this.addDataSlot(this.selectedRecipeIndex);
|
||
|
}
|
||
|
|
||
|
public int getSelectedRecipeIndex() {
|
||
|
return this.selectedRecipeIndex.get();
|
||
|
}
|
||
|
|
||
|
public SelectableRecipe.SingleInputSet<StonecutterRecipe> getVisibleRecipes() {
|
||
|
return this.recipesForInput;
|
||
|
}
|
||
|
|
||
|
public int getNumberOfVisibleRecipes() {
|
||
|
return this.recipesForInput.size();
|
||
|
}
|
||
|
|
||
|
public boolean hasInputItem() {
|
||
|
return this.inputSlot.hasItem() && !this.recipesForInput.isEmpty();
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public boolean stillValid(Player p_40307_) {
|
||
|
return stillValid(this.access, p_40307_, Blocks.STONECUTTER);
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public boolean clickMenuButton(Player p_40309_, int p_40310_) {
|
||
|
if (this.selectedRecipeIndex.get() == p_40310_) {
|
||
|
return false;
|
||
|
} else {
|
||
|
if (this.isValidRecipeIndex(p_40310_)) {
|
||
|
this.selectedRecipeIndex.set(p_40310_);
|
||
|
this.setupResultSlot(p_40310_);
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private boolean isValidRecipeIndex(int p_40335_) {
|
||
|
return p_40335_ >= 0 && p_40335_ < this.recipesForInput.size();
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void slotsChanged(Container p_40302_) {
|
||
|
ItemStack itemstack = this.inputSlot.getItem();
|
||
|
if (!itemstack.is(this.input.getItem())) {
|
||
|
this.input = itemstack.copy();
|
||
|
this.setupRecipeList(itemstack);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void setupRecipeList(ItemStack p_40305_) {
|
||
|
this.selectedRecipeIndex.set(-1);
|
||
|
this.resultSlot.set(ItemStack.EMPTY);
|
||
|
if (!p_40305_.isEmpty()) {
|
||
|
this.recipesForInput = this.level.recipeAccess().stonecutterRecipes().selectByInput(p_40305_);
|
||
|
} else {
|
||
|
this.recipesForInput = SelectableRecipe.SingleInputSet.empty();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void setupResultSlot(int p_366661_) {
|
||
|
Optional<RecipeHolder<StonecutterRecipe>> optional;
|
||
|
if (!this.recipesForInput.isEmpty() && this.isValidRecipeIndex(p_366661_)) {
|
||
|
SelectableRecipe.SingleInputEntry<StonecutterRecipe> singleinputentry = this.recipesForInput.entries().get(p_366661_);
|
||
|
optional = singleinputentry.recipe().recipe();
|
||
|
} else {
|
||
|
optional = Optional.empty();
|
||
|
}
|
||
|
|
||
|
optional.ifPresentOrElse(p_359376_ -> {
|
||
|
this.resultContainer.setRecipeUsed((RecipeHolder<?>)p_359376_);
|
||
|
this.resultSlot.set(p_359376_.value().assemble(new SingleRecipeInput(this.container.getItem(0)), this.level.registryAccess()));
|
||
|
}, () -> {
|
||
|
this.resultSlot.set(ItemStack.EMPTY);
|
||
|
this.resultContainer.setRecipeUsed(null);
|
||
|
});
|
||
|
this.broadcastChanges();
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public MenuType<?> getType() {
|
||
|
return MenuType.STONECUTTER;
|
||
|
}
|
||
|
|
||
|
public void registerUpdateListener(Runnable p_40324_) {
|
||
|
this.slotUpdateListener = p_40324_;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public boolean canTakeItemForPickAll(ItemStack p_40321_, Slot p_40322_) {
|
||
|
return p_40322_.container != this.resultContainer && super.canTakeItemForPickAll(p_40321_, p_40322_);
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public ItemStack quickMoveStack(Player p_40328_, int p_40329_) {
|
||
|
ItemStack itemstack = ItemStack.EMPTY;
|
||
|
Slot slot = this.slots.get(p_40329_);
|
||
|
if (slot != null && slot.hasItem()) {
|
||
|
ItemStack itemstack1 = slot.getItem();
|
||
|
Item item = itemstack1.getItem();
|
||
|
itemstack = itemstack1.copy();
|
||
|
if (p_40329_ == 1) {
|
||
|
item.onCraftedBy(itemstack1, p_40328_);
|
||
|
if (!this.moveItemStackTo(itemstack1, 2, 38, true)) {
|
||
|
return ItemStack.EMPTY;
|
||
|
}
|
||
|
|
||
|
slot.onQuickCraft(itemstack1, itemstack);
|
||
|
} else if (p_40329_ == 0) {
|
||
|
if (!this.moveItemStackTo(itemstack1, 2, 38, false)) {
|
||
|
return ItemStack.EMPTY;
|
||
|
}
|
||
|
} else if (this.level.recipeAccess().stonecutterRecipes().acceptsInput(itemstack1)) {
|
||
|
if (!this.moveItemStackTo(itemstack1, 0, 1, false)) {
|
||
|
return ItemStack.EMPTY;
|
||
|
}
|
||
|
} else if (p_40329_ >= 2 && p_40329_ < 29) {
|
||
|
if (!this.moveItemStackTo(itemstack1, 29, 38, false)) {
|
||
|
return ItemStack.EMPTY;
|
||
|
}
|
||
|
} else if (p_40329_ >= 29 && p_40329_ < 38 && !this.moveItemStackTo(itemstack1, 2, 29, false)) {
|
||
|
return ItemStack.EMPTY;
|
||
|
}
|
||
|
|
||
|
if (itemstack1.isEmpty()) {
|
||
|
slot.setByPlayer(ItemStack.EMPTY);
|
||
|
}
|
||
|
|
||
|
slot.setChanged();
|
||
|
if (itemstack1.getCount() == itemstack.getCount()) {
|
||
|
return ItemStack.EMPTY;
|
||
|
}
|
||
|
|
||
|
slot.onTake(p_40328_, itemstack1);
|
||
|
if (p_40329_ == 1) {
|
||
|
p_40328_.drop(itemstack1, false);
|
||
|
}
|
||
|
|
||
|
this.broadcastChanges();
|
||
|
}
|
||
|
|
||
|
return itemstack;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void removed(Player p_40326_) {
|
||
|
super.removed(p_40326_);
|
||
|
this.resultContainer.removeItemNoUpdate(1);
|
||
|
this.access.execute((p_40313_, p_40314_) -> this.clearContainer(p_40326_, this.container));
|
||
|
}
|
||
|
}
|