246 lines
10 KiB
Java
246 lines
10 KiB
Java
/*
|
|
* Decompiled with CFR 0.152.
|
|
*
|
|
* Could not load the following classes:
|
|
* it.unimi.dsi.fastutil.objects.Object2IntMap$Entry
|
|
*/
|
|
package net.minecraft.world.inventory;
|
|
|
|
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
|
import net.minecraft.core.BlockPos;
|
|
import net.minecraft.core.Holder;
|
|
import net.minecraft.core.component.DataComponents;
|
|
import net.minecraft.server.level.ServerLevel;
|
|
import net.minecraft.tags.EnchantmentTags;
|
|
import net.minecraft.world.Container;
|
|
import net.minecraft.world.SimpleContainer;
|
|
import net.minecraft.world.entity.ExperienceOrb;
|
|
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.AnvilMenu;
|
|
import net.minecraft.world.inventory.ContainerLevelAccess;
|
|
import net.minecraft.world.inventory.MenuType;
|
|
import net.minecraft.world.inventory.ResultContainer;
|
|
import net.minecraft.world.inventory.Slot;
|
|
import net.minecraft.world.item.ItemStack;
|
|
import net.minecraft.world.item.Items;
|
|
import net.minecraft.world.item.enchantment.Enchantment;
|
|
import net.minecraft.world.item.enchantment.EnchantmentHelper;
|
|
import net.minecraft.world.item.enchantment.ItemEnchantments;
|
|
import net.minecraft.world.level.Level;
|
|
import net.minecraft.world.level.block.Blocks;
|
|
import net.minecraft.world.phys.Vec3;
|
|
|
|
public class GrindstoneMenu
|
|
extends AbstractContainerMenu {
|
|
public static final int MAX_NAME_LENGTH = 35;
|
|
public static final int INPUT_SLOT = 0;
|
|
public static final int ADDITIONAL_SLOT = 1;
|
|
public 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 final Container resultSlots = new ResultContainer();
|
|
private final Container repairSlots = new SimpleContainer(2){
|
|
|
|
@Override
|
|
public void setChanged() {
|
|
super.setChanged();
|
|
GrindstoneMenu.this.slotsChanged(this);
|
|
}
|
|
};
|
|
private final ContainerLevelAccess access;
|
|
|
|
public GrindstoneMenu(int containerId, Inventory inventory) {
|
|
this(containerId, inventory, ContainerLevelAccess.NULL);
|
|
}
|
|
|
|
public GrindstoneMenu(int containerId, Inventory inventory, final ContainerLevelAccess access) {
|
|
super(MenuType.GRINDSTONE, containerId);
|
|
this.access = access;
|
|
this.addSlot(new Slot(this, this.repairSlots, 0, 49, 19){
|
|
|
|
@Override
|
|
public boolean mayPlace(ItemStack itemStack) {
|
|
return itemStack.isDamageableItem() || EnchantmentHelper.hasAnyEnchantments(itemStack);
|
|
}
|
|
});
|
|
this.addSlot(new Slot(this, this.repairSlots, 1, 49, 40){
|
|
|
|
@Override
|
|
public boolean mayPlace(ItemStack itemStack) {
|
|
return itemStack.isDamageableItem() || EnchantmentHelper.hasAnyEnchantments(itemStack);
|
|
}
|
|
});
|
|
this.addSlot(new Slot(this.resultSlots, 2, 129, 34){
|
|
|
|
@Override
|
|
public boolean mayPlace(ItemStack itemStack) {
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public void onTake(Player player, ItemStack carried) {
|
|
access.execute((level, pos) -> {
|
|
if (level instanceof ServerLevel) {
|
|
ExperienceOrb.award((ServerLevel)level, Vec3.atCenterOf(pos), this.getExperienceAmount((Level)level));
|
|
}
|
|
level.levelEvent(1042, (BlockPos)pos, 0);
|
|
});
|
|
GrindstoneMenu.this.repairSlots.setItem(0, ItemStack.EMPTY);
|
|
GrindstoneMenu.this.repairSlots.setItem(1, ItemStack.EMPTY);
|
|
}
|
|
|
|
private int getExperienceAmount(Level level) {
|
|
int amount = 0;
|
|
amount += this.getExperienceFromItem(GrindstoneMenu.this.repairSlots.getItem(0));
|
|
if ((amount += this.getExperienceFromItem(GrindstoneMenu.this.repairSlots.getItem(1))) > 0) {
|
|
int halfAmount = (int)Math.ceil((double)amount / 2.0);
|
|
return halfAmount + level.random.nextInt(halfAmount);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
private int getExperienceFromItem(ItemStack item) {
|
|
int amount = 0;
|
|
ItemEnchantments enchantments = EnchantmentHelper.getEnchantmentsForCrafting(item);
|
|
for (Object2IntMap.Entry<Holder<Enchantment>> entry : enchantments.entrySet()) {
|
|
Holder enchant = (Holder)entry.getKey();
|
|
int lvl = entry.getIntValue();
|
|
if (enchant.is(EnchantmentTags.CURSE)) continue;
|
|
amount += ((Enchantment)enchant.value()).getMinCost(lvl);
|
|
}
|
|
return amount;
|
|
}
|
|
});
|
|
this.addStandardInventorySlots(inventory, 8, 84);
|
|
}
|
|
|
|
@Override
|
|
public void slotsChanged(Container container) {
|
|
super.slotsChanged(container);
|
|
if (container == this.repairSlots) {
|
|
this.createResult();
|
|
}
|
|
}
|
|
|
|
private void createResult() {
|
|
this.resultSlots.setItem(0, this.computeResult(this.repairSlots.getItem(0), this.repairSlots.getItem(1)));
|
|
this.broadcastChanges();
|
|
}
|
|
|
|
private ItemStack computeResult(ItemStack input, ItemStack additional) {
|
|
boolean hasBothItems;
|
|
boolean hasAnItem;
|
|
boolean bl = hasAnItem = !input.isEmpty() || !additional.isEmpty();
|
|
if (!hasAnItem) {
|
|
return ItemStack.EMPTY;
|
|
}
|
|
if (input.getCount() > 1 || additional.getCount() > 1) {
|
|
return ItemStack.EMPTY;
|
|
}
|
|
boolean bl2 = hasBothItems = !input.isEmpty() && !additional.isEmpty();
|
|
if (!hasBothItems) {
|
|
ItemStack item;
|
|
ItemStack itemStack = item = !input.isEmpty() ? input : additional;
|
|
if (!EnchantmentHelper.hasAnyEnchantments(item)) {
|
|
return ItemStack.EMPTY;
|
|
}
|
|
return this.removeNonCursesFrom(item.copy());
|
|
}
|
|
return this.mergeItems(input, additional);
|
|
}
|
|
|
|
private ItemStack mergeItems(ItemStack input, ItemStack additional) {
|
|
ItemStack newItem;
|
|
if (!input.is(additional.getItem())) {
|
|
return ItemStack.EMPTY;
|
|
}
|
|
int durability = Math.max(input.getMaxDamage(), additional.getMaxDamage());
|
|
int remaining1 = input.getMaxDamage() - input.getDamageValue();
|
|
int remaining2 = additional.getMaxDamage() - additional.getDamageValue();
|
|
int remaining = remaining1 + remaining2 + durability * 5 / 100;
|
|
int count = 1;
|
|
if (!input.isDamageableItem()) {
|
|
if (input.getMaxStackSize() < 2 || !ItemStack.matches(input, additional)) {
|
|
return ItemStack.EMPTY;
|
|
}
|
|
count = 2;
|
|
}
|
|
if ((newItem = input.copyWithCount(count)).isDamageableItem()) {
|
|
newItem.set(DataComponents.MAX_DAMAGE, durability);
|
|
newItem.setDamageValue(Math.max(durability - remaining, 0));
|
|
}
|
|
this.mergeEnchantsFrom(newItem, additional);
|
|
return this.removeNonCursesFrom(newItem);
|
|
}
|
|
|
|
private void mergeEnchantsFrom(ItemStack target, ItemStack source) {
|
|
EnchantmentHelper.updateEnchantments(target, newEnchantments -> {
|
|
ItemEnchantments enchantments = EnchantmentHelper.getEnchantmentsForCrafting(source);
|
|
for (Object2IntMap.Entry<Holder<Enchantment>> entry : enchantments.entrySet()) {
|
|
Holder enchant = (Holder)entry.getKey();
|
|
if (enchant.is(EnchantmentTags.CURSE) && newEnchantments.getLevel(enchant) != 0) continue;
|
|
newEnchantments.upgrade(enchant, entry.getIntValue());
|
|
}
|
|
});
|
|
}
|
|
|
|
private ItemStack removeNonCursesFrom(ItemStack item) {
|
|
ItemEnchantments newEnchantments = EnchantmentHelper.updateEnchantments(item, enchantments -> enchantments.removeIf(enchantment -> !enchantment.is(EnchantmentTags.CURSE)));
|
|
if (item.is(Items.ENCHANTED_BOOK) && newEnchantments.isEmpty()) {
|
|
item = item.transmuteCopy(Items.BOOK);
|
|
}
|
|
int repairCost = 0;
|
|
for (int i = 0; i < newEnchantments.size(); ++i) {
|
|
repairCost = AnvilMenu.calculateIncreasedRepairCost(repairCost);
|
|
}
|
|
item.set(DataComponents.REPAIR_COST, repairCost);
|
|
return item;
|
|
}
|
|
|
|
@Override
|
|
public void removed(Player player) {
|
|
super.removed(player);
|
|
this.access.execute((level, pos) -> this.clearContainer(player, this.repairSlots));
|
|
}
|
|
|
|
@Override
|
|
public boolean stillValid(Player player) {
|
|
return GrindstoneMenu.stillValid(this.access, player, Blocks.GRINDSTONE);
|
|
}
|
|
|
|
@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 item = slot.getItem();
|
|
clicked = item.copy();
|
|
ItemStack input = this.repairSlots.getItem(0);
|
|
ItemStack additional = this.repairSlots.getItem(1);
|
|
if (slotIndex == 2) {
|
|
if (!this.moveItemStackTo(item, 3, 39, true)) {
|
|
return ItemStack.EMPTY;
|
|
}
|
|
slot.onQuickCraft(item, clicked);
|
|
} else if (slotIndex == 0 || slotIndex == 1 ? !this.moveItemStackTo(item, 3, 39, false) : (input.isEmpty() || additional.isEmpty() ? !this.moveItemStackTo(item, 0, 2, false) : (slotIndex >= 3 && slotIndex < 30 ? !this.moveItemStackTo(item, 30, 39, false) : slotIndex >= 30 && slotIndex < 39 && !this.moveItemStackTo(item, 3, 30, false)))) {
|
|
return ItemStack.EMPTY;
|
|
}
|
|
if (item.isEmpty()) {
|
|
slot.setByPlayer(ItemStack.EMPTY);
|
|
} else {
|
|
slot.setChanged();
|
|
}
|
|
if (item.getCount() == clicked.getCount()) {
|
|
return ItemStack.EMPTY;
|
|
}
|
|
slot.onTake(player, item);
|
|
}
|
|
return clicked;
|
|
}
|
|
}
|
|
|