Code/net/minecraft/world/inventory/MerchantMenu.java

229 lines
8.2 KiB
Java
Raw Normal View History

2025-07-01 06:20:03 +00:00
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.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 p_40033_, Inventory p_40034_) {
this(p_40033_, p_40034_, new ClientSideMerchant(p_40034_.player));
}
public MerchantMenu(int p_40036_, Inventory p_40037_, Merchant p_40038_) {
super(MenuType.MERCHANT, p_40036_);
this.trader = p_40038_;
this.tradeContainer = new MerchantContainer(p_40038_);
this.addSlot(new Slot(this.tradeContainer, 0, 136, 37));
this.addSlot(new Slot(this.tradeContainer, 1, 162, 37));
this.addSlot(new MerchantResultSlot(p_40037_.player, p_40038_, this.tradeContainer, 2, 220, 37));
this.addStandardInventorySlots(p_40037_, 108, 84);
}
public void setShowProgressBar(boolean p_40049_) {
this.showProgressBar = p_40049_;
}
@Override
public void slotsChanged(Container p_40040_) {
this.tradeContainer.updateSellItem();
super.slotsChanged(p_40040_);
}
public void setSelectionHint(int p_40064_) {
this.tradeContainer.setSelectionHint(p_40064_);
}
@Override
public boolean stillValid(Player p_40042_) {
return this.trader.stillValid(p_40042_);
}
public int getTraderXp() {
return this.trader.getVillagerXp();
}
public int getFutureTraderXp() {
return this.tradeContainer.getFutureXp();
}
public void setXp(int p_40067_) {
this.trader.overrideXp(p_40067_);
}
public int getTraderLevel() {
return this.merchantLevel;
}
public void setMerchantLevel(int p_40070_) {
this.merchantLevel = p_40070_;
}
public void setCanRestock(boolean p_40059_) {
this.canRestock = p_40059_;
}
public boolean canRestock() {
return this.canRestock;
}
@Override
public boolean canTakeItemForPickAll(ItemStack p_40044_, Slot p_40045_) {
return false;
}
@Override
public ItemStack quickMoveStack(Player p_40053_, int p_40054_) {
ItemStack itemstack = ItemStack.EMPTY;
Slot slot = this.slots.get(p_40054_);
if (slot != null && slot.hasItem()) {
ItemStack itemstack1 = slot.getItem();
itemstack = itemstack1.copy();
if (p_40054_ == 2) {
if (!this.moveItemStackTo(itemstack1, 3, 39, true)) {
return ItemStack.EMPTY;
}
slot.onQuickCraft(itemstack1, itemstack);
this.playTradeSound();
} else if (p_40054_ != 0 && p_40054_ != 1) {
if (p_40054_ >= 3 && p_40054_ < 30) {
if (!this.moveItemStackTo(itemstack1, 30, 39, false)) {
return ItemStack.EMPTY;
}
} else if (p_40054_ >= 30 && p_40054_ < 39 && !this.moveItemStackTo(itemstack1, 3, 30, false)) {
return ItemStack.EMPTY;
}
} else if (!this.moveItemStackTo(itemstack1, 3, 39, false)) {
return ItemStack.EMPTY;
}
if (itemstack1.isEmpty()) {
slot.setByPlayer(ItemStack.EMPTY);
} else {
slot.setChanged();
}
if (itemstack1.getCount() == itemstack.getCount()) {
return ItemStack.EMPTY;
}
slot.onTake(p_40053_, itemstack1);
}
return itemstack;
}
private void playTradeSound() {
if (!this.trader.isClientSide()) {
Entity entity = (Entity)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 p_40051_) {
super.removed(p_40051_);
this.trader.setTradingPlayer(null);
if (!this.trader.isClientSide()) {
if (!p_40051_.isAlive() || p_40051_ instanceof ServerPlayer && ((ServerPlayer)p_40051_).hasDisconnected()) {
ItemStack itemstack = this.tradeContainer.removeItemNoUpdate(0);
if (!itemstack.isEmpty()) {
p_40051_.drop(itemstack, false);
}
itemstack = this.tradeContainer.removeItemNoUpdate(1);
if (!itemstack.isEmpty()) {
p_40051_.drop(itemstack, false);
}
} else if (p_40051_ instanceof ServerPlayer) {
p_40051_.getInventory().placeItemBackInInventory(this.tradeContainer.removeItemNoUpdate(0));
p_40051_.getInventory().placeItemBackInInventory(this.tradeContainer.removeItemNoUpdate(1));
}
}
}
public void tryMoveItems(int p_40073_) {
if (p_40073_ >= 0 && this.getOffers().size() > p_40073_) {
ItemStack itemstack = this.tradeContainer.getItem(0);
if (!itemstack.isEmpty()) {
if (!this.moveItemStackTo(itemstack, 3, 39, true)) {
return;
}
this.tradeContainer.setItem(0, itemstack);
}
ItemStack itemstack1 = this.tradeContainer.getItem(1);
if (!itemstack1.isEmpty()) {
if (!this.moveItemStackTo(itemstack1, 3, 39, true)) {
return;
}
this.tradeContainer.setItem(1, itemstack1);
}
if (this.tradeContainer.getItem(0).isEmpty() && this.tradeContainer.getItem(1).isEmpty()) {
MerchantOffer merchantoffer = this.getOffers().get(p_40073_);
this.moveFromInventoryToPaymentSlot(0, merchantoffer.getItemCostA());
merchantoffer.getItemCostB().ifPresent(p_332192_ -> this.moveFromInventoryToPaymentSlot(1, p_332192_));
}
}
}
private void moveFromInventoryToPaymentSlot(int p_40061_, ItemCost p_332037_) {
for (int i = 3; i < 39; i++) {
ItemStack itemstack = this.slots.get(i).getItem();
if (!itemstack.isEmpty() && p_332037_.test(itemstack)) {
ItemStack itemstack1 = this.tradeContainer.getItem(p_40061_);
if (itemstack1.isEmpty() || ItemStack.isSameItemSameComponents(itemstack, itemstack1)) {
int j = itemstack.getMaxStackSize();
int k = Math.min(j - itemstack1.getCount(), itemstack.getCount());
ItemStack itemstack2 = itemstack.copyWithCount(itemstack1.getCount() + k);
itemstack.shrink(k);
this.tradeContainer.setItem(p_40061_, itemstack2);
if (itemstack2.getCount() >= j) {
break;
}
}
}
}
}
public void setOffers(MerchantOffers p_40047_) {
this.trader.overrideOffers(p_40047_);
}
public MerchantOffers getOffers() {
return this.trader.getOffers();
}
public boolean showProgressBar() {
return this.showProgressBar;
}
}