From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sun, 19 Apr 2020 00:17:56 -0500 Subject: [PATCH] Anvil API diff --git a/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java b/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java index ffd349c1b80df0f1e8c02bda23700184825170fd..29f301bde378bd320d5c44f2c1b6bf9dc185e286 100644 --- a/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java +++ b/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java @@ -76,6 +76,7 @@ public abstract class AbstractContainerMenu { @Nullable private ContainerSynchronizer synchronizer; private boolean suppressRemoteUpdates; + @javax.annotation.Nullable protected ItemStack activeQuickItem = null; // Purpur // CraftBukkit start public boolean checkReachable = true; diff --git a/src/main/java/net/minecraft/world/inventory/AnvilMenu.java b/src/main/java/net/minecraft/world/inventory/AnvilMenu.java index f00638e9d7baf8b803dd610f2bf6250da34efab3..9cc9925cd43c4b1b742acde9cf4fb5fe46619d24 100644 --- a/src/main/java/net/minecraft/world/inventory/AnvilMenu.java +++ b/src/main/java/net/minecraft/world/inventory/AnvilMenu.java @@ -23,6 +23,13 @@ import org.slf4j.Logger; import org.bukkit.craftbukkit.inventory.CraftInventoryView; // CraftBukkit end +// Purpur start +import net.minecraft.nbt.IntTag; +import net.minecraft.network.protocol.game.ClientboundContainerSetDataPacket; +import net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket; +import net.minecraft.server.level.ServerPlayer; +// Purpur end + public class AnvilMenu extends ItemCombinerMenu { public static final int INPUT_SLOT = 0; @@ -51,6 +58,8 @@ public class AnvilMenu extends ItemCombinerMenu { public int maximumRepairCost = 40; private CraftInventoryView bukkitEntity; // CraftBukkit end + public boolean bypassCost = false; // Purpur + public boolean canDoUnsafeEnchants = false; // Purpur public AnvilMenu(int syncId, Inventory inventory) { this(syncId, inventory, ContainerLevelAccess.NULL); @@ -78,12 +87,15 @@ public class AnvilMenu extends ItemCombinerMenu { @Override protected boolean mayPickup(Player player, boolean present) { - return (player.getAbilities().instabuild || player.experienceLevel >= this.cost.get()) && this.cost.get() > AnvilMenu.DEFAULT_DENIED_COST && present; // CraftBukkit - allow cost 0 like a free item + return (player.getAbilities().instabuild || player.experienceLevel >= this.cost.get()) && (bypassCost || this.cost.get() > AnvilMenu.DEFAULT_DENIED_COST) && present; // CraftBukkit - allow cost 0 like a free item // Purpur } @Override protected void onTake(Player player, ItemStack stack) { + ItemStack itemstack = activeQuickItem == null ? stack : activeQuickItem; // Purpur + if (org.purpurmc.purpur.event.inventory.AnvilTakeResultEvent.getHandlerList().getRegisteredListeners().length > 0) new org.purpurmc.purpur.event.inventory.AnvilTakeResultEvent(player.getBukkitEntity(), getBukkitView(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack)).callEvent(); // Purpur if (!player.getAbilities().instabuild) { + if (bypassCost) ((ServerPlayer) player).lastSentExp = -1; else // Purpur player.giveExperienceLevels(-this.cost.get()); } @@ -134,6 +146,12 @@ public class AnvilMenu extends ItemCombinerMenu { @Override public void createResult() { + // Purpur start + bypassCost = false; + canDoUnsafeEnchants = false; + if (org.purpurmc.purpur.event.inventory.AnvilUpdateResultEvent.getHandlerList().getRegisteredListeners().length > 0) new org.purpurmc.purpur.event.inventory.AnvilUpdateResultEvent(getBukkitView()).callEvent(); + // Purpur end + ItemStack itemstack = this.inputSlots.getItem(0); this.cost.set(1); @@ -210,7 +228,7 @@ public class AnvilMenu extends ItemCombinerMenu { int i2 = (Integer) map1.get(enchantment); i2 = l1 == i2 ? i2 + 1 : Math.max(i2, l1); - boolean flag3 = enchantment.canEnchant(itemstack); + boolean flag3 = canDoUnsafeEnchants || enchantment.canEnchant(itemstack); // Purpur if (this.player.getAbilities().instabuild || itemstack.is(Items.ENCHANTED_BOOK)) { flag3 = true; @@ -222,7 +240,7 @@ public class AnvilMenu extends ItemCombinerMenu { Enchantment enchantment1 = (Enchantment) iterator1.next(); if (enchantment1 != enchantment && !enchantment.isCompatibleWith(enchantment1)) { - flag3 = false; + flag3 = canDoUnsafeEnchants; // Purpur ++i; } } @@ -293,6 +311,13 @@ public class AnvilMenu extends ItemCombinerMenu { this.cost.set(this.maximumRepairCost - 1); // CraftBukkit } + // Purpur start + if (bypassCost && cost.get() >= maximumRepairCost) { + itemstack.addTagElement("Purpur.realCost", IntTag.valueOf(cost.get())); + cost.set(maximumRepairCost - 1); + } + // Purpur end + if (this.cost.get() >= this.maximumRepairCost && !this.player.getAbilities().instabuild) { // CraftBukkit itemstack1 = ItemStack.EMPTY; } @@ -315,6 +340,12 @@ public class AnvilMenu extends ItemCombinerMenu { org.bukkit.craftbukkit.event.CraftEventFactory.callPrepareAnvilEvent(this.getBukkitView(), itemstack1); // CraftBukkit this.sendAllDataToRemote(); // CraftBukkit - SPIGOT-6686: Always send completed inventory to stay in sync with client this.broadcastChanges(); + // Purpur start + if (canDoUnsafeEnchants && itemstack1 != ItemStack.EMPTY) { + ((ServerPlayer) player).connection.send(new ClientboundContainerSetSlotPacket(containerId, incrementStateId(), 2, itemstack1)); + ((ServerPlayer) player).connection.send(new ClientboundContainerSetDataPacket(containerId, 0, cost.get())); + } + // Purpur end } } diff --git a/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java b/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java index c2cf5a8e788637c6264cf43d712a5be223ff1cc5..a578882b64c581ef4f47fa483a9f2988cfa4c8cf 100644 --- a/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java +++ b/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java @@ -178,7 +178,9 @@ public abstract class ItemCombinerMenu extends AbstractContainerMenu { return ItemStack.EMPTY; } + this.activeQuickItem = itemstack; // Purpur slot1.onTake(player, itemstack1); + this.activeQuickItem = null; // Purpur } return itemstack; diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryAnvil.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryAnvil.java index 9ee14589d63bbfc0880f2eee5e924fe946ee0035..0a5841fa26698e60bdeadbb58b9343fe1ff08a28 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryAnvil.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryAnvil.java @@ -9,7 +9,7 @@ import org.bukkit.inventory.AnvilInventory; public class CraftInventoryAnvil extends CraftResultInventory implements AnvilInventory { private final Location location; - private final AnvilMenu container; + public final AnvilMenu container; // Purpur - private -> public public CraftInventoryAnvil(Location location, Container inventory, Container resultInventory, AnvilMenu container) { super(inventory, resultInventory); @@ -57,4 +57,26 @@ public class CraftInventoryAnvil extends CraftResultInventory implements AnvilIn Preconditions.checkArgument(levels >= 0, "Maximum repair cost must be positive (or 0)"); this.container.maximumRepairCost = levels; } + + // Purpur start + @Override + public boolean canBypassCost() { + return container.bypassCost; + } + + @Override + public void setBypassCost(boolean bypassCost) { + container.bypassCost = bypassCost; + } + + @Override + public boolean canDoUnsafeEnchants() { + return container.canDoUnsafeEnchants; + } + + @Override + public void setDoUnsafeEnchants(boolean canDoUnsafeEnchants) { + container.canDoUnsafeEnchants = canDoUnsafeEnchants; + } + // Purpur end }