2025-11-24 22:52:51 +03:00

218 lines
8.1 KiB
Java

/*
* Decompiled with CFR 0.152.
*/
package net.minecraft.world.inventory;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.Container;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.npc.ClientSideMerchant;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.inventory.MenuType;
import net.minecraft.world.inventory.MerchantContainer;
import net.minecraft.world.inventory.MerchantResultSlot;
import net.minecraft.world.inventory.Slot;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.trading.ItemCost;
import net.minecraft.world.item.trading.Merchant;
import net.minecraft.world.item.trading.MerchantOffer;
import net.minecraft.world.item.trading.MerchantOffers;
public class MerchantMenu
extends AbstractContainerMenu {
protected static final int PAYMENT1_SLOT = 0;
protected static final int PAYMENT2_SLOT = 1;
protected static final int RESULT_SLOT = 2;
private static final int INV_SLOT_START = 3;
private static final int INV_SLOT_END = 30;
private static final int USE_ROW_SLOT_START = 30;
private static final int USE_ROW_SLOT_END = 39;
private static final int SELLSLOT1_X = 136;
private static final int SELLSLOT2_X = 162;
private static final int BUYSLOT_X = 220;
private static final int ROW_Y = 37;
private final Merchant trader;
private final MerchantContainer tradeContainer;
private int merchantLevel;
private boolean showProgressBar;
private boolean canRestock;
public MerchantMenu(int containerId, Inventory inventory) {
this(containerId, inventory, new ClientSideMerchant(inventory.player));
}
public MerchantMenu(int containerId, Inventory inventory, Merchant merchant) {
super(MenuType.MERCHANT, containerId);
this.trader = merchant;
this.tradeContainer = new MerchantContainer(merchant);
this.addSlot(new Slot(this.tradeContainer, 0, 136, 37));
this.addSlot(new Slot(this.tradeContainer, 1, 162, 37));
this.addSlot(new MerchantResultSlot(inventory.player, merchant, this.tradeContainer, 2, 220, 37));
this.addStandardInventorySlots(inventory, 108, 84);
}
public void setShowProgressBar(boolean show) {
this.showProgressBar = show;
}
@Override
public void slotsChanged(Container container) {
this.tradeContainer.updateSellItem();
super.slotsChanged(container);
}
public void setSelectionHint(int hint) {
this.tradeContainer.setSelectionHint(hint);
}
@Override
public boolean stillValid(Player player) {
return this.trader.stillValid(player);
}
public int getTraderXp() {
return this.trader.getVillagerXp();
}
public int getFutureTraderXp() {
return this.tradeContainer.getFutureXp();
}
public void setXp(int xp) {
this.trader.overrideXp(xp);
}
public int getTraderLevel() {
return this.merchantLevel;
}
public void setMerchantLevel(int level) {
this.merchantLevel = level;
}
public void setCanRestock(boolean canRestock) {
this.canRestock = canRestock;
}
public boolean canRestock() {
return this.canRestock;
}
@Override
public boolean canTakeItemForPickAll(ItemStack carried, Slot target) {
return false;
}
@Override
public ItemStack quickMoveStack(Player player, int slotIndex) {
ItemStack clicked = ItemStack.EMPTY;
Slot slot = (Slot)this.slots.get(slotIndex);
if (slot != null && slot.hasItem()) {
ItemStack stack = slot.getItem();
clicked = stack.copy();
if (slotIndex == 2) {
if (!this.moveItemStackTo(stack, 3, 39, true)) {
return ItemStack.EMPTY;
}
slot.onQuickCraft(stack, clicked);
this.playTradeSound();
} else if (slotIndex == 0 || slotIndex == 1 ? !this.moveItemStackTo(stack, 3, 39, false) : (slotIndex >= 3 && slotIndex < 30 ? !this.moveItemStackTo(stack, 30, 39, false) : slotIndex >= 30 && slotIndex < 39 && !this.moveItemStackTo(stack, 3, 30, false))) {
return ItemStack.EMPTY;
}
if (stack.isEmpty()) {
slot.setByPlayer(ItemStack.EMPTY);
} else {
slot.setChanged();
}
if (stack.getCount() == clicked.getCount()) {
return ItemStack.EMPTY;
}
slot.onTake(player, stack);
}
return clicked;
}
private void playTradeSound() {
if (!this.trader.isClientSide()) {
Entity entity = (Entity)((Object)this.trader);
entity.level().playLocalSound(entity.getX(), entity.getY(), entity.getZ(), this.trader.getNotifyTradeSound(), SoundSource.NEUTRAL, 1.0f, 1.0f, false);
}
}
@Override
public void removed(Player player) {
super.removed(player);
this.trader.setTradingPlayer(null);
if (this.trader.isClientSide()) {
return;
}
if (!player.isAlive() || player instanceof ServerPlayer && ((ServerPlayer)player).hasDisconnected()) {
ItemStack itemStack = this.tradeContainer.removeItemNoUpdate(0);
if (!itemStack.isEmpty()) {
player.drop(itemStack, false);
}
if (!(itemStack = this.tradeContainer.removeItemNoUpdate(1)).isEmpty()) {
player.drop(itemStack, false);
}
} else if (player instanceof ServerPlayer) {
player.getInventory().placeItemBackInInventory(this.tradeContainer.removeItemNoUpdate(0));
player.getInventory().placeItemBackInInventory(this.tradeContainer.removeItemNoUpdate(1));
}
}
public void tryMoveItems(int newTradeIndex) {
ItemStack oldCostB;
if (newTradeIndex < 0 || this.getOffers().size() <= newTradeIndex) {
return;
}
ItemStack oldCostA = this.tradeContainer.getItem(0);
if (!oldCostA.isEmpty()) {
if (!this.moveItemStackTo(oldCostA, 3, 39, true)) {
return;
}
this.tradeContainer.setItem(0, oldCostA);
}
if (!(oldCostB = this.tradeContainer.getItem(1)).isEmpty()) {
if (!this.moveItemStackTo(oldCostB, 3, 39, true)) {
return;
}
this.tradeContainer.setItem(1, oldCostB);
}
if (this.tradeContainer.getItem(0).isEmpty() && this.tradeContainer.getItem(1).isEmpty()) {
MerchantOffer merchantOffer = (MerchantOffer)this.getOffers().get(newTradeIndex);
this.moveFromInventoryToPaymentSlot(0, merchantOffer.getItemCostA());
merchantOffer.getItemCostB().ifPresent(costB -> this.moveFromInventoryToPaymentSlot(1, (ItemCost)costB));
}
}
private void moveFromInventoryToPaymentSlot(int paymentSlot, ItemCost cost) {
for (int i = 3; i < 39; ++i) {
ItemStack currentPaymentItem;
ItemStack inventoryItem = ((Slot)this.slots.get(i)).getItem();
if (inventoryItem.isEmpty() || !cost.test(inventoryItem) || !(currentPaymentItem = this.tradeContainer.getItem(paymentSlot)).isEmpty() && !ItemStack.isSameItemSameComponents(inventoryItem, currentPaymentItem)) continue;
int maxStackSize = inventoryItem.getMaxStackSize();
int moveCount = Math.min(maxStackSize - currentPaymentItem.getCount(), inventoryItem.getCount());
ItemStack newPaymentItem = inventoryItem.copyWithCount(currentPaymentItem.getCount() + moveCount);
inventoryItem.shrink(moveCount);
this.tradeContainer.setItem(paymentSlot, newPaymentItem);
if (newPaymentItem.getCount() >= maxStackSize) break;
}
}
public void setOffers(MerchantOffers offers) {
this.trader.overrideOffers(offers);
}
public MerchantOffers getOffers() {
return this.trader.getOffers();
}
public boolean showProgressBar() {
return this.showProgressBar;
}
}