aboutsummaryrefslogtreecommitdiffhomepage
path: root/patch-remap/mache-vineflower/net/minecraft/world/item/ItemStack.java.patch
diff options
context:
space:
mode:
Diffstat (limited to 'patch-remap/mache-vineflower/net/minecraft/world/item/ItemStack.java.patch')
-rw-r--r--patch-remap/mache-vineflower/net/minecraft/world/item/ItemStack.java.patch1384
1 files changed, 1384 insertions, 0 deletions
diff --git a/patch-remap/mache-vineflower/net/minecraft/world/item/ItemStack.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/item/ItemStack.java.patch
new file mode 100644
index 0000000000..8f2b7a5500
--- /dev/null
+++ b/patch-remap/mache-vineflower/net/minecraft/world/item/ItemStack.java.patch
@@ -0,0 +1,1384 @@
+--- a/net/minecraft/world/item/ItemStack.java
++++ b/net/minecraft/world/item/ItemStack.java
+@@ -9,15 +9,15 @@
+ import com.mojang.serialization.DataResult;
+ import com.mojang.serialization.MapCodec;
+ import com.mojang.serialization.codecs.RecordCodecBuilder;
+-import com.mojang.serialization.codecs.RecordCodecBuilder.Instance;
+ import java.text.DecimalFormat;
+ import java.text.DecimalFormatSymbols;
+ import java.util.Collection;
++import java.util.Iterator;
+ import java.util.List;
+ import java.util.Locale;
++import java.util.Map.Entry;
+ import java.util.Objects;
+ import java.util.Optional;
+-import java.util.Map.Entry;
+ import java.util.function.Consumer;
+ import java.util.function.Predicate;
+ import java.util.stream.Collectors;
+@@ -28,6 +28,7 @@
+ import net.minecraft.advancements.CriteriaTriggers;
+ import net.minecraft.commands.arguments.blocks.BlockStateParser;
+ import net.minecraft.core.BlockPos;
++import net.minecraft.core.Direction;
+ import net.minecraft.core.Holder;
+ import net.minecraft.core.HolderSet;
+ import net.minecraft.core.Registry;
+@@ -35,6 +36,7 @@
+ import net.minecraft.core.registries.Registries;
+ import net.minecraft.nbt.CompoundTag;
+ import net.minecraft.nbt.ListTag;
++import net.minecraft.nbt.NbtOps;
+ import net.minecraft.nbt.Tag;
+ import net.minecraft.nbt.TagParser;
+ import net.minecraft.network.chat.CommonComponents;
+@@ -43,27 +45,24 @@
+ import net.minecraft.network.chat.HoverEvent;
+ import net.minecraft.network.chat.MutableComponent;
+ import net.minecraft.network.chat.Style;
++import net.minecraft.network.protocol.game.ClientboundBlockUpdatePacket;
+ import net.minecraft.resources.ResourceLocation;
+-import net.minecraft.server.level.ServerPlayer;
+-import net.minecraft.sounds.SoundEvent;
+-import net.minecraft.stats.Stats;
+ import net.minecraft.tags.TagKey;
+ import net.minecraft.util.ExtraCodecs;
+ import net.minecraft.util.RandomSource;
+-import net.minecraft.world.InteractionHand;
++import net.minecraft.world.EnumHand;
+ import net.minecraft.world.InteractionResult;
+ import net.minecraft.world.InteractionResultHolder;
+ import net.minecraft.world.entity.Entity;
++import net.minecraft.world.entity.EnumMonsterType;
+ import net.minecraft.world.entity.EquipmentSlot;
+ import net.minecraft.world.entity.LivingEntity;
+-import net.minecraft.world.entity.MobType;
+ import net.minecraft.world.entity.SlotAccess;
+ import net.minecraft.world.entity.ai.attributes.Attribute;
+ import net.minecraft.world.entity.ai.attributes.AttributeModifier;
+ import net.minecraft.world.entity.ai.attributes.Attributes;
+ import net.minecraft.world.entity.decoration.ItemFrame;
+ import net.minecraft.world.entity.item.ItemEntity;
+-import net.minecraft.world.entity.player.Player;
+ import net.minecraft.world.flag.FeatureFlagSet;
+ import net.minecraft.world.inventory.ClickAction;
+ import net.minecraft.world.inventory.Slot;
+@@ -74,52 +73,81 @@
+ import net.minecraft.world.item.enchantment.Enchantment;
+ import net.minecraft.world.item.enchantment.EnchantmentHelper;
+ import net.minecraft.world.item.enchantment.Enchantments;
+-import net.minecraft.world.level.ItemLike;
++import net.minecraft.world.level.IMaterial;
+ import net.minecraft.world.level.Level;
++import net.minecraft.world.level.block.BaseEntityBlock;
++import net.minecraft.world.level.block.BedBlock;
+ import net.minecraft.world.level.block.Block;
+-import net.minecraft.world.level.block.state.BlockState;
++import net.minecraft.world.level.block.state.IBlockData;
+ import net.minecraft.world.level.block.state.pattern.BlockInWorld;
+ import org.slf4j.Logger;
+
++// CraftBukkit start
++import com.mojang.serialization.Dynamic;
++import java.util.Map;
++import java.util.Objects;
++import net.minecraft.server.MinecraftServer;
++import net.minecraft.server.level.ServerLevel;
++import net.minecraft.server.level.ServerPlayer;
++import net.minecraft.sounds.SoundEvent;
++import net.minecraft.sounds.SoundSource;
++import net.minecraft.stats.Stats;
++import net.minecraft.util.datafix.fixes.DataConverterTypes;
++import net.minecraft.world.level.block.Blocks;
++import net.minecraft.world.level.block.SaplingBlock;
++import net.minecraft.world.level.block.SignBlock;
++import net.minecraft.world.level.block.SoundType;
++import net.minecraft.world.level.block.WitherSkullBlock;
++import net.minecraft.world.level.block.entity.BlockEntity;
++import net.minecraft.world.level.block.entity.JukeboxBlockEntity;
++import net.minecraft.world.level.block.entity.SignBlockEntity;
++import net.minecraft.world.level.block.entity.SkullBlockEntity;
++import net.minecraft.world.level.gameevent.GameEvent;
++import org.bukkit.Location;
++import org.bukkit.TreeType;
++import org.bukkit.block.BlockState;
++import org.bukkit.craftbukkit.block.CraftBlock;
++import org.bukkit.craftbukkit.block.CraftBlockState;
++import org.bukkit.craftbukkit.inventory.CraftItemStack;
++import org.bukkit.craftbukkit.util.CraftLocation;
++import org.bukkit.craftbukkit.util.CraftMagicNumbers;
++import org.bukkit.entity.Player;
++import org.bukkit.event.block.BlockFertilizeEvent;
++import org.bukkit.event.player.PlayerItemDamageEvent;
++import org.bukkit.event.world.StructureGrowEvent;
++// CraftBukkit end
++
+ public final class ItemStack {
+- public static final Codec<ItemStack> CODEC = RecordCodecBuilder.create(
+- instance -> instance.group(
+- BuiltInRegistries.ITEM.holderByNameCodec().fieldOf("id").forGetter(ItemStack::getItemHolder),
+- Codec.INT.fieldOf("Count").forGetter(ItemStack::getCount),
+- CompoundTag.CODEC.optionalFieldOf("tag").forGetter(itemStack -> Optional.ofNullable(itemStack.getTag()))
+- )
+- .apply(instance, ItemStack::new)
+- );
+- private static final Codec<Item> ITEM_NON_AIR_CODEC = ExtraCodecs.validate(
+- BuiltInRegistries.ITEM.byNameCodec(), item -> item == Items.AIR ? DataResult.error(() -> "Item must not be minecraft:air") : DataResult.success(item)
+- );
+- public static final Codec<ItemStack> ADVANCEMENT_ICON_CODEC = RecordCodecBuilder.create(
+- instance -> instance.group(
+- BuiltInRegistries.ITEM.holderByNameCodec().fieldOf("item").forGetter(ItemStack::getItemHolder),
+- ExtraCodecs.strictOptionalField(TagParser.AS_CODEC, "nbt").forGetter(itemStack -> Optional.ofNullable(itemStack.getTag()))
+- )
+- .apply(instance, (holder, optional) -> new ItemStack(holder, 1, optional))
+- );
+- public static final Codec<ItemStack> ITEM_WITH_COUNT_CODEC = RecordCodecBuilder.create(
+- instance -> instance.group(
+- ITEM_NON_AIR_CODEC.fieldOf("item").forGetter(ItemStack::getItem),
+- ExtraCodecs.strictOptionalField(ExtraCodecs.POSITIVE_INT, "count", 1).forGetter(ItemStack::getCount)
+- )
+- .apply(instance, ItemStack::new)
+- );
+- public static final Codec<ItemStack> SINGLE_ITEM_CODEC = ITEM_NON_AIR_CODEC.xmap(ItemStack::new, ItemStack::getItem);
+- public static final MapCodec<ItemStack> RESULT_CODEC = RecordCodecBuilder.mapCodec(
+- instance -> instance.group(
+- BuiltInRegistries.ITEM.byNameCodec().fieldOf("result").forGetter(ItemStack::getItem),
+- Codec.INT.fieldOf("count").forGetter(ItemStack::getCount)
+- )
+- .apply(instance, ItemStack::new)
+- );
++
++ public static final Codec<ItemStack> CODEC = RecordCodecBuilder.create((instance) -> {
++ return instance.group(BuiltInRegistries.ITEM.holderByNameCodec().fieldOf("id").forGetter(ItemStack::getItemHolder), Codec.INT.fieldOf("Count").forGetter(ItemStack::getCount), CompoundTag.CODEC.optionalFieldOf("tag").forGetter((itemstack) -> {
++ return Optional.ofNullable(itemstack.getTag());
++ })).apply(instance, ItemStack::new);
++ });
++ private static final Codec<Item> ITEM_NON_AIR_CODEC = ExtraCodecs.validate(BuiltInRegistries.ITEM.byNameCodec(), (item) -> {
++ return item == Items.AIR ? DataResult.error(() -> {
++ return "Item must not be minecraft:air";
++ }) : DataResult.success(item);
++ });
++ public static final Codec<ItemStack> ADVANCEMENT_ICON_CODEC = RecordCodecBuilder.create((instance) -> {
++ return instance.group(BuiltInRegistries.ITEM.holderByNameCodec().fieldOf("item").forGetter(ItemStack::getItemHolder), ExtraCodecs.strictOptionalField(TagParser.AS_CODEC, "nbt").forGetter((itemstack) -> {
++ return Optional.ofNullable(itemstack.getTag());
++ })).apply(instance, (holder, optional) -> {
++ return new ItemStack(holder, 1, optional);
++ });
++ });
++ public static final Codec<ItemStack> ITEM_WITH_COUNT_CODEC = RecordCodecBuilder.create((instance) -> {
++ return instance.group(ItemStack.ITEM_NON_AIR_CODEC.fieldOf("item").forGetter(ItemStack::getItem), ExtraCodecs.strictOptionalField(ExtraCodecs.POSITIVE_INT, "count", 1).forGetter(ItemStack::getCount)).apply(instance, ItemStack::new);
++ });
++ public static final Codec<ItemStack> SINGLE_ITEM_CODEC = ItemStack.ITEM_NON_AIR_CODEC.xmap(ItemStack::new, ItemStack::getItem);
++ public static final MapCodec<ItemStack> RESULT_CODEC = RecordCodecBuilder.mapCodec((instance) -> {
++ return instance.group(BuiltInRegistries.ITEM.byNameCodec().fieldOf("result").forGetter(ItemStack::getItem), Codec.INT.fieldOf("count").forGetter(ItemStack::getCount)).apply(instance, ItemStack::new);
++ });
+ private static final Logger LOGGER = LogUtils.getLogger();
+- public static final ItemStack EMPTY = new ItemStack((Void)null);
+- public static final DecimalFormat ATTRIBUTE_MODIFIER_FORMAT = Util.make(
+- new DecimalFormat("#.##"), decimalFormat -> decimalFormat.setDecimalFormatSymbols(DecimalFormatSymbols.getInstance(Locale.ROOT))
+- );
++ public static final ItemStack EMPTY = new ItemStack((Void) null);
++ public static final DecimalFormat ATTRIBUTE_MODIFIER_FORMAT = (DecimalFormat) Util.make(new DecimalFormat("#.##"), (decimalformat) -> {
++ decimalformat.setDecimalFormatSymbols(DecimalFormatSymbols.getInstance(Locale.ROOT));
++ });
+ public static final String TAG_ENCH = "Enchantments";
+ public static final String TAG_DISPLAY = "display";
+ public static final String TAG_DISPLAY_NAME = "Name";
+@@ -136,9 +164,10 @@
+ private static final Style LORE_STYLE = Style.EMPTY.withColor(ChatFormatting.DARK_PURPLE).withItalic(true);
+ private int count;
+ private int popTime;
++ /** @deprecated */
+ @Deprecated
+ @Nullable
+- private final Item item;
++ private Item item;
+ @Nullable
+ private CompoundTag tag;
+ @Nullable
+@@ -152,12 +181,12 @@
+ return this.getItem().getTooltipImage(this);
+ }
+
+- public ItemStack(ItemLike item) {
++ public ItemStack(IMaterial item) {
+ this(item, 1);
+ }
+
+ public ItemStack(Holder<Item> tag) {
+- this(tag.value(), 1);
++ this((IMaterial) tag.value(), 1);
+ }
+
+ public ItemStack(Holder<Item> item, int count, Optional<CompoundTag> optional) {
+@@ -166,45 +195,63 @@
+ }
+
+ public ItemStack(Holder<Item> item, int count) {
+- this(item.value(), count);
++ this((IMaterial) item.value(), count);
+ }
+
+- public ItemStack(ItemLike item, int count) {
++ public ItemStack(IMaterial item, int count) {
+ this.item = item.asItem();
+ this.count = count;
+ if (this.item.canBeDepleted()) {
+ this.setDamageValue(this.getDamageValue());
+ }
++
+ }
+
+- private ItemStack(@Nullable Void _void) {
++ private ItemStack(@Nullable Void ovoid) {
+ this.item = null;
+ }
+
+- private ItemStack(CompoundTag compoundTag) {
+- this.item = BuiltInRegistries.ITEM.get(new ResourceLocation(compoundTag.getString("id")));
+- this.count = compoundTag.getByte("Count");
+- if (compoundTag.contains("tag", 10)) {
+- this.tag = compoundTag.getCompound("tag").copy();
++ // Called to run this stack through the data converter to handle older storage methods and serialized items
++ public void convertStack(int version) {
++ if (0 < version && version < CraftMagicNumbers.INSTANCE.getDataVersion()) {
++ CompoundTag savedStack = new CompoundTag();
++ this.save(savedStack);
++ savedStack = (CompoundTag) MinecraftServer.getServer().fixerUpper.update(DataConverterTypes.ITEM_STACK, new Dynamic(NbtOps.INSTANCE, savedStack), version, CraftMagicNumbers.INSTANCE.getDataVersion()).getValue();
++ this.load(savedStack);
++ }
++ }
++
++ // CraftBukkit - break into own method
++ private void load(CompoundTag nbttagcompound) {
++ this.item = (Item) BuiltInRegistries.ITEM.get(new ResourceLocation(nbttagcompound.getString("id")));
++ this.count = nbttagcompound.getByte("Count");
++ if (nbttagcompound.contains("tag", 10)) {
++ this.tag = nbttagcompound.getCompound("tag").copy();
+ this.getItem().verifyTagAfterLoad(this.tag);
+ }
+
+ if (this.getItem().canBeDepleted()) {
+ this.setDamageValue(this.getDamageValue());
+ }
++
+ }
+
++ private ItemStack(CompoundTag compoundTag) {
++ this.load(compoundTag);
++ // CraftBukkit end
++ }
++
+ public static ItemStack of(CompoundTag compoundTag) {
+ try {
+ return new ItemStack(compoundTag);
+- } catch (RuntimeException var2) {
+- LOGGER.debug("Tried to load invalid item: {}", compoundTag, var2);
+- return EMPTY;
++ } catch (RuntimeException runtimeexception) {
++ ItemStack.LOGGER.debug("Tried to load invalid item: {}", compoundTag, runtimeexception);
++ return ItemStack.EMPTY;
+ }
+ }
+
+ public boolean isEmpty() {
+- return this == EMPTY || this.item == Items.AIR || this.count <= 0;
++ return this == ItemStack.EMPTY || this.item == Items.AIR || this.count <= 0;
+ }
+
+ public boolean isItemEnabled(FeatureFlagSet enabledFlags) {
+@@ -212,19 +259,21 @@
+ }
+
+ public ItemStack split(int amount) {
+- int min = Math.min(amount, this.getCount());
+- ItemStack itemStack = this.copyWithCount(min);
+- this.shrink(min);
+- return itemStack;
++ int j = Math.min(amount, this.getCount());
++ ItemStack itemstack = this.copyWithCount(j);
++
++ this.shrink(j);
++ return itemstack;
+ }
+
+ public ItemStack copyAndClear() {
+ if (this.isEmpty()) {
+- return EMPTY;
++ return ItemStack.EMPTY;
+ } else {
+- ItemStack itemStack = this.copy();
++ ItemStack itemstack = this.copy();
++
+ this.setCount(0);
+- return itemStack;
++ return itemstack;
+ }
+ }
+
+@@ -252,8 +301,8 @@
+ return this.getItem().builtInRegistryHolder() == item;
+ }
+
+- public boolean is(HolderSet<Item> holderSet) {
+- return holderSet.contains(this.getItemHolder());
++ public boolean is(HolderSet<Item> holderset) {
++ return holderset.contains(this.getItemHolder());
+ }
+
+ public Stream<TagKey<Item>> getTags() {
+@@ -261,29 +310,208 @@
+ }
+
+ public InteractionResult useOn(UseOnContext context) {
+- Player player = context.getPlayer();
+- BlockPos clickedPos = context.getClickedPos();
+- BlockInWorld blockInWorld = new BlockInWorld(context.getLevel(), clickedPos, false);
+- if (player != null
+- && !player.getAbilities().mayBuild
+- && !this.hasAdventureModePlaceTagForBlock(context.getLevel().registryAccess().registryOrThrow(Registries.BLOCK), blockInWorld)) {
++ net.minecraft.world.entity.player.Player entityhuman = context.getPlayer();
++ BlockPos blockposition = context.getClickedPos();
++ BlockInWorld shapedetectorblock = new BlockInWorld(context.getLevel(), blockposition, false);
++
++ if (entityhuman != null && !entityhuman.getAbilities().mayBuild && !this.hasAdventureModePlaceTagForBlock(context.getLevel().registryAccess().registryOrThrow(Registries.BLOCK), shapedetectorblock)) {
+ return InteractionResult.PASS;
+ } else {
+ Item item = this.getItem();
+- InteractionResult interactionResult = item.useOn(context);
+- if (player != null && interactionResult.shouldAwardStats()) {
+- player.awardStat(Stats.ITEM_USED.get(item));
++ // CraftBukkit start - handle all block place event logic here
++ CompoundTag oldData = this.getTagClone();
++ int oldCount = this.getCount();
++ ServerLevel world = (ServerLevel) context.getLevel();
++
++ if (!(item instanceof BucketItem || item instanceof SolidBucketItem)) { // if not bucket
++ world.captureBlockStates = true;
++ // special case bonemeal
++ if (item == Items.BONE_MEAL) {
++ world.captureTreeGeneration = true;
++ }
+ }
++ InteractionResult enuminteractionresult;
++ try {
++ enuminteractionresult = item.useOn(context);
++ } finally {
++ world.captureBlockStates = false;
++ }
++ CompoundTag newData = this.getTagClone();
++ int newCount = this.getCount();
++ this.setCount(oldCount);
++ this.setTagClone(oldData);
++ if (enuminteractionresult.consumesAction() && world.captureTreeGeneration && world.capturedBlockStates.size() > 0) {
++ world.captureTreeGeneration = false;
++ Location location = CraftLocation.toBukkit(blockposition, world.getWorld());
++ TreeType treeType = SaplingBlock.treeType;
++ SaplingBlock.treeType = null;
++ List<CraftBlockState> blocks = new java.util.ArrayList<>(world.capturedBlockStates.values());
++ world.capturedBlockStates.clear();
++ StructureGrowEvent structureEvent = null;
++ if (treeType != null) {
++ boolean isBonemeal = getItem() == Items.BONE_MEAL;
++ structureEvent = new StructureGrowEvent(location, treeType, isBonemeal, (Player) entityhuman.getBukkitEntity(), (List< BlockState>) (List<? extends BlockState>) blocks);
++ org.bukkit.Bukkit.getPluginManager().callEvent(structureEvent);
++ }
+
+- return interactionResult;
++ BlockFertilizeEvent fertilizeEvent = new BlockFertilizeEvent(CraftBlock.at(world, blockposition), (Player) entityhuman.getBukkitEntity(), (List< BlockState>) (List<? extends BlockState>) blocks);
++ fertilizeEvent.setCancelled(structureEvent != null && structureEvent.isCancelled());
++ org.bukkit.Bukkit.getPluginManager().callEvent(fertilizeEvent);
++
++ if (!fertilizeEvent.isCancelled()) {
++ // Change the stack to its new contents if it hasn't been tampered with.
++ if (this.getCount() == oldCount && Objects.equals(this.tag, oldData)) {
++ this.setTag(newData);
++ this.setCount(newCount);
++ }
++ for (CraftBlockState blockstate : blocks) {
++ world.setBlock(blockstate.getPosition(),blockstate.getHandle(), blockstate.getFlag()); // SPIGOT-7248 - manual update to avoid physics where appropriate
++ }
++ entityhuman.awardStat(Stats.ITEM_USED.get(item)); // SPIGOT-7236 - award stat
++ }
++
++ SignItem.openSign = null; // SPIGOT-6758 - Reset on early return
++ return enuminteractionresult;
++ }
++ world.captureTreeGeneration = false;
++
++ if (entityhuman != null && enuminteractionresult.shouldAwardStats()) {
++ EnumHand enumhand = context.getHand();
++ org.bukkit.event.block.BlockPlaceEvent placeEvent = null;
++ List<BlockState> blocks = new java.util.ArrayList<>(world.capturedBlockStates.values());
++ world.capturedBlockStates.clear();
++ if (blocks.size() > 1) {
++ placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockMultiPlaceEvent(world, entityhuman, enumhand, blocks, blockposition.getX(), blockposition.getY(), blockposition.getZ());
++ } else if (blocks.size() == 1) {
++ placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPlaceEvent(world, entityhuman, enumhand, blocks.get(0), blockposition.getX(), blockposition.getY(), blockposition.getZ());
++ }
++
++ if (placeEvent != null && (placeEvent.isCancelled() || !placeEvent.canBuild())) {
++ enuminteractionresult = InteractionResult.FAIL; // cancel placement
++ // PAIL: Remove this when MC-99075 fixed
++ placeEvent.getPlayer().updateInventory();
++ // revert back all captured blocks
++ world.preventPoiUpdated = true; // CraftBukkit - SPIGOT-5710
++ for (BlockState blockstate : blocks) {
++ blockstate.update(true, false);
++ }
++ world.preventPoiUpdated = false;
++
++ // Brute force all possible updates
++ BlockPos placedPos = ((CraftBlock) placeEvent.getBlock()).getPosition();
++ for (Direction dir : Direction.values()) {
++ ((ServerPlayer) entityhuman).connection.send(new ClientboundBlockUpdatePacket(world, placedPos.relative(dir)));
++ }
++ SignItem.openSign = null; // SPIGOT-6758 - Reset on early return
++ } else {
++ // Change the stack to its new contents if it hasn't been tampered with.
++ if (this.getCount() == oldCount && Objects.equals(this.tag, oldData)) {
++ this.setTag(newData);
++ this.setCount(newCount);
++ }
++
++ for (Map.Entry<BlockPos, BlockEntity> e : world.capturedTileEntities.entrySet()) {
++ world.setBlockEntity(e.getValue());
++ }
++
++ for (BlockState blockstate : blocks) {
++ int updateFlag = ((CraftBlockState) blockstate).getFlag();
++ IBlockData oldBlock = ((CraftBlockState) blockstate).getHandle();
++ BlockPos newblockposition = ((CraftBlockState) blockstate).getPosition();
++ IBlockData block = world.getBlockState(newblockposition);
++
++ if (!(block.getBlock() instanceof BaseEntityBlock)) { // Containers get placed automatically
++ block.getBlock().onPlace(block, world, newblockposition, oldBlock, true);
++ }
++
++ world.notifyAndUpdatePhysics(newblockposition, null, oldBlock, block, world.getBlockState(newblockposition), updateFlag, 512); // send null chunk as chunk.k() returns false by this point
++ }
++
++ // Special case juke boxes as they update their tile entity. Copied from ItemRecord.
++ // PAIL: checkme on updates.
++ if (this.item instanceof RecordItem) {
++ BlockEntity tileentity = world.getBlockEntity(blockposition);
++
++ if (tileentity instanceof JukeboxBlockEntity) {
++ JukeboxBlockEntity tileentityjukebox = (JukeboxBlockEntity) tileentity;
++
++ // There can only be one
++ ItemStack record = this.copy();
++ if (!record.isEmpty()) {
++ record.setCount(1);
++ }
++
++ tileentityjukebox.setTheItem(record);
++ world.gameEvent(GameEvent.BLOCK_CHANGE, blockposition, GameEvent.Context.of(entityhuman, world.getBlockState(blockposition)));
++ }
++
++ this.shrink(1);
++ entityhuman.awardStat(Stats.PLAY_RECORD);
++ }
++
++ if (this.item == Items.WITHER_SKELETON_SKULL) { // Special case skulls to allow wither spawns to be cancelled
++ BlockPos bp = blockposition;
++ if (!world.getBlockState(blockposition).canBeReplaced()) {
++ if (!world.getBlockState(blockposition).isSolid()) {
++ bp = null;
++ } else {
++ bp = bp.relative(context.getClickedFace());
++ }
++ }
++ if (bp != null) {
++ BlockEntity te = world.getBlockEntity(bp);
++ if (te instanceof SkullBlockEntity) {
++ WitherSkullBlock.checkSpawn(world, bp, (SkullBlockEntity) te);
++ }
++ }
++ }
++
++ // SPIGOT-4678
++ if (this.item instanceof SignItem && SignItem.openSign != null) {
++ try {
++ if (world.getBlockEntity(SignItem.openSign) instanceof SignBlockEntity tileentitysign) {
++ if (world.getBlockState(SignItem.openSign).getBlock() instanceof SignBlock blocksign) {
++ blocksign.openTextEdit(entityhuman, tileentitysign, true, org.bukkit.event.player.PlayerSignOpenEvent.Cause.PLACE); // Craftbukkit
++ }
++ }
++ } finally {
++ SignItem.openSign = null;
++ }
++ }
++
++ // SPIGOT-7315: Moved from BlockBed#setPlacedBy
++ if (placeEvent != null && this.item instanceof BedItem) {
++ BlockPos position = ((CraftBlock) placeEvent.getBlock()).getPosition();
++ IBlockData blockData = world.getBlockState(position);
++
++ if (blockData.getBlock() instanceof BedBlock) {
++ world.blockUpdated(position, Blocks.AIR);
++ blockData.updateNeighbourShapes(world, position, 3);
++ }
++ }
++
++ // SPIGOT-1288 - play sound stripped from ItemBlock
++ if (this.item instanceof BlockItem) {
++ SoundType soundeffecttype = ((BlockItem) this.item).getBlock().defaultBlockState().getSoundType(); // TODO: not strictly correct, however currently only affects decorated pots
++ world.playSound(entityhuman, blockposition, soundeffecttype.getPlaceSound(), SoundSource.BLOCKS, (soundeffecttype.getVolume() + 1.0F) / 2.0F, soundeffecttype.getPitch() * 0.8F);
++ }
++
++ entityhuman.awardStat(Stats.ITEM_USED.get(item));
++ }
++ }
++ world.capturedTileEntities.clear();
++ world.capturedBlockStates.clear();
++ // CraftBukkit end
++
++ return enuminteractionresult;
+ }
+ }
+
+- public float getDestroySpeed(BlockState state) {
++ public float getDestroySpeed(IBlockData state) {
+ return this.getItem().getDestroySpeed(this, state);
+ }
+
+- public InteractionResultHolder<ItemStack> use(Level level, Player player, InteractionHand usedHand) {
++ public InteractionResultHolder<ItemStack> use(Level level, net.minecraft.world.entity.player.Player player, EnumHand usedHand) {
+ return this.getItem().use(level, player, usedHand);
+ }
+
+@@ -292,9 +520,10 @@
+ }
+
+ public CompoundTag save(CompoundTag compoundTag) {
+- ResourceLocation key = BuiltInRegistries.ITEM.getKey(this.getItem());
+- compoundTag.putString("id", key == null ? "minecraft:air" : key.toString());
+- compoundTag.putByte("Count", (byte)this.count);
++ ResourceLocation minecraftkey = BuiltInRegistries.ITEM.getKey(this.getItem());
++
++ compoundTag.putString("id", minecraftkey == null ? "minecraft:air" : minecraftkey.toString());
++ compoundTag.putByte("Count", (byte) this.count);
+ if (this.tag != null) {
+ compoundTag.put("tag", this.tag.copy());
+ }
+@@ -312,8 +541,9 @@
+
+ public boolean isDamageableItem() {
+ if (!this.isEmpty() && this.getItem().getMaxDamage() > 0) {
+- CompoundTag tag = this.getTag();
+- return tag == null || !tag.getBoolean("Unbreakable");
++ CompoundTag nbttagcompound = this.getTag();
++
++ return nbttagcompound == null || !nbttagcompound.getBoolean("Unbreakable");
+ } else {
+ return false;
+ }
+@@ -339,17 +569,34 @@
+ if (!this.isDamageableItem()) {
+ return false;
+ } else {
++ int j;
++
+ if (amount > 0) {
+- int itemEnchantmentLevel = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.UNBREAKING, this);
+- int i = 0;
++ j = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.UNBREAKING, this);
++ int k = 0;
+
+- for (int i1 = 0; itemEnchantmentLevel > 0 && i1 < amount; i1++) {
+- if (DigDurabilityEnchantment.shouldIgnoreDurabilityDrop(this, itemEnchantmentLevel, random)) {
+- i++;
++ for (int l = 0; j > 0 && l < amount; ++l) {
++ if (DigDurabilityEnchantment.shouldIgnoreDurabilityDrop(this, j, random)) {
++ ++k;
+ }
+ }
+
+- amount -= i;
++ amount -= k;
++ // CraftBukkit start
++ if (user != null) {
++ PlayerItemDamageEvent event = new PlayerItemDamageEvent(user.getBukkitEntity(), CraftItemStack.asCraftMirror(this), amount);
++ event.getPlayer().getServer().getPluginManager().callEvent(event);
++
++ if (amount != event.getDamage() || event.isCancelled()) {
++ event.getPlayer().updateInventory();
++ }
++ if (event.isCancelled()) {
++ return false;
++ }
++
++ amount = event.getDamage();
++ }
++ // CraftBukkit end
+ if (amount <= 0) {
+ return false;
+ }
+@@ -359,25 +606,32 @@
+ CriteriaTriggers.ITEM_DURABILITY_CHANGED.trigger(user, this, this.getDamageValue() + amount);
+ }
+
+- int itemEnchantmentLevel = this.getDamageValue() + amount;
+- this.setDamageValue(itemEnchantmentLevel);
+- return itemEnchantmentLevel >= this.getMaxDamage();
++ j = this.getDamageValue() + amount;
++ this.setDamageValue(j);
++ return j >= this.getMaxDamage();
+ }
+ }
+
+ public <T extends LivingEntity> void hurtAndBreak(int amount, T entity, Consumer<T> onBroken) {
+- if (!entity.level().isClientSide && (!(entity instanceof Player) || !((Player)entity).getAbilities().instabuild)) {
++ if (!entity.level().isClientSide && (!(entity instanceof net.minecraft.world.entity.player.Player) || !((net.minecraft.world.entity.player.Player) entity).getAbilities().instabuild)) {
+ if (this.isDamageableItem()) {
+- if (this.hurt(amount, entity.getRandom(), entity instanceof ServerPlayer ? (ServerPlayer)entity : null)) {
++ if (this.hurt(amount, entity.getRandom(), entity instanceof ServerPlayer ? (ServerPlayer) entity : null)) {
+ onBroken.accept(entity);
+ Item item = this.getItem();
++ // CraftBukkit start - Check for item breaking
++ if (this.count == 1 && entity instanceof net.minecraft.world.entity.player.Player) {
++ org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerItemBreakEvent((net.minecraft.world.entity.player.Player) entity, this);
++ }
++ // CraftBukkit end
++
+ this.shrink(1);
+- if (entity instanceof Player) {
+- ((Player)entity).awardStat(Stats.ITEM_BROKEN.get(item));
++ if (entity instanceof net.minecraft.world.entity.player.Player) {
++ ((net.minecraft.world.entity.player.Player) entity).awardStat(Stats.ITEM_BROKEN.get(item));
+ }
+
+ this.setDamageValue(0);
+ }
++
+ }
+ }
+ }
+@@ -394,62 +648,68 @@
+ return this.getItem().getBarColor(this);
+ }
+
+- public boolean overrideStackedOnOther(Slot slot, ClickAction action, Player player) {
++ public boolean overrideStackedOnOther(Slot slot, ClickAction action, net.minecraft.world.entity.player.Player player) {
+ return this.getItem().overrideStackedOnOther(this, slot, action, player);
+ }
+
+- public boolean overrideOtherStackedOnMe(ItemStack stack, Slot slot, ClickAction action, Player player, SlotAccess access) {
++ public boolean overrideOtherStackedOnMe(ItemStack stack, Slot slot, ClickAction action, net.minecraft.world.entity.player.Player player, SlotAccess access) {
+ return this.getItem().overrideOtherStackedOnMe(this, stack, slot, action, player, access);
+ }
+
+- public void hurtEnemy(LivingEntity entity, Player player) {
++ public void hurtEnemy(LivingEntity entity, net.minecraft.world.entity.player.Player player) {
+ Item item = this.getItem();
++
+ if (item.hurtEnemy(this, entity, player)) {
+ player.awardStat(Stats.ITEM_USED.get(item));
+ }
++
+ }
+
+- public void mineBlock(Level level, BlockState state, BlockPos pos, Player player) {
++ public void mineBlock(Level level, IBlockData state, BlockPos pos, net.minecraft.world.entity.player.Player player) {
+ Item item = this.getItem();
++
+ if (item.mineBlock(this, level, state, pos, player)) {
+ player.awardStat(Stats.ITEM_USED.get(item));
+ }
++
+ }
+
+- public boolean isCorrectToolForDrops(BlockState state) {
++ public boolean isCorrectToolForDrops(IBlockData state) {
+ return this.getItem().isCorrectToolForDrops(state);
+ }
+
+- public InteractionResult interactLivingEntity(Player player, LivingEntity entity, InteractionHand usedHand) {
++ public InteractionResult interactLivingEntity(net.minecraft.world.entity.player.Player player, LivingEntity entity, EnumHand usedHand) {
+ return this.getItem().interactLivingEntity(this, player, entity, usedHand);
+ }
+
+ public ItemStack copy() {
+ if (this.isEmpty()) {
+- return EMPTY;
++ return ItemStack.EMPTY;
+ } else {
+- ItemStack itemStack = new ItemStack(this.getItem(), this.count);
+- itemStack.setPopTime(this.getPopTime());
++ ItemStack itemstack = new ItemStack(this.getItem(), this.count);
++
++ itemstack.setPopTime(this.getPopTime());
+ if (this.tag != null) {
+- itemStack.tag = this.tag.copy();
++ itemstack.tag = this.tag.copy();
+ }
+
+- return itemStack;
++ return itemstack;
+ }
+ }
+
+ public ItemStack copyWithCount(int count) {
+ if (this.isEmpty()) {
+- return EMPTY;
++ return ItemStack.EMPTY;
+ } else {
+- ItemStack itemStack = this.copy();
+- itemStack.setCount(count);
+- return itemStack;
++ ItemStack itemstack = this.copy();
++
++ itemstack.setCount(count);
++ return itemstack;
+ }
+ }
+
+ public static boolean matches(ItemStack stack, ItemStack other) {
+- return stack == other || stack.getCount() == other.getCount() && isSameItemSameTags(stack, other);
++ return stack == other ? true : (stack.getCount() != other.getCount() ? false : isSameItemSameTags(stack, other));
+ }
+
+ public static boolean isSameItem(ItemStack stack, ItemStack other) {
+@@ -457,42 +717,44 @@
+ }
+
+ public static boolean isSameItemSameTags(ItemStack stack, ItemStack other) {
+- return stack.is(other.getItem()) && (stack.isEmpty() && other.isEmpty() || Objects.equals(stack.tag, other.tag));
++ return !stack.is(other.getItem()) ? false : (stack.isEmpty() && other.isEmpty() ? true : Objects.equals(stack.tag, other.tag));
+ }
+
+ public String getDescriptionId() {
+ return this.getItem().getDescriptionId(this);
+ }
+
+- @Override
+ public String toString() {
+- return this.getCount() + " " + this.getItem();
++ int i = this.getCount();
++
++ return i + " " + this.getItem();
+ }
+
+ public void inventoryTick(Level level, Entity entity, int inventorySlot, boolean isCurrentItem) {
+ if (this.popTime > 0) {
+- this.popTime--;
++ --this.popTime;
+ }
+
+ if (this.getItem() != null) {
+ this.getItem().inventoryTick(this, level, entity, inventorySlot, isCurrentItem);
+ }
++
+ }
+
+- public void onCraftedBy(Level level, Player player, int amount) {
++ public void onCraftedBy(Level level, net.minecraft.world.entity.player.Player player, int amount) {
+ player.awardStat(Stats.ITEM_CRAFTED.get(this.getItem()), amount);
+ this.getItem().onCraftedBy(this, level, player);
+ }
+
+- public void onCraftedBySystem(Level level) {
+- this.getItem().onCraftedPostProcess(this, level);
++ public void onCraftedBySystem(Level world) {
++ this.getItem().onCraftedPostProcess(this, world);
+ }
+
+ public int getUseDuration() {
+ return this.getItem().getUseDuration(this);
+ }
+
+- public UseAnim getUseAnimation() {
++ public EnumAnimation getUseAnimation() {
+ return this.getItem().getUseAnimation(this);
+ }
+
+@@ -513,6 +775,17 @@
+ return this.tag;
+ }
+
++ // CraftBukkit start
++ @Nullable
++ private CompoundTag getTagClone() {
++ return this.tag == null ? null : this.tag.copy();
++ }
++
++ private void setTagClone(@Nullable CompoundTag nbtttagcompound) {
++ this.setTag(nbtttagcompound == null ? null : nbtttagcompound.copy());
++ }
++ // CraftBukkit end
++
+ public CompoundTag getOrCreateTag() {
+ if (this.tag == null) {
+ this.setTag(new CompoundTag());
+@@ -525,9 +798,10 @@
+ if (this.tag != null && this.tag.contains(key, 10)) {
+ return this.tag.getCompound(key);
+ } else {
+- CompoundTag compoundTag = new CompoundTag();
+- this.addTagElement(key, compoundTag);
+- return compoundTag;
++ CompoundTag nbttagcompound = new CompoundTag();
++
++ this.addTagElement(key, nbttagcompound);
++ return nbttagcompound;
+ }
+ }
+
+@@ -543,6 +817,7 @@
+ this.tag = null;
+ }
+ }
++
+ }
+
+ public ListTag getEnchantmentTags() {
+@@ -558,20 +833,23 @@
+ if (compoundTag != null) {
+ this.getItem().verifyTagAfterLoad(compoundTag);
+ }
++
+ }
+
+ public Component getHoverName() {
+- CompoundTag tagElement = this.getTagElement("display");
+- if (tagElement != null && tagElement.contains("Name", 8)) {
++ CompoundTag nbttagcompound = this.getTagElement("display");
++
++ if (nbttagcompound != null && nbttagcompound.contains("Name", 8)) {
+ try {
+- Component component = Component.Serializer.fromJson(tagElement.getString("Name"));
+- if (component != null) {
+- return component;
++ MutableComponent ichatmutablecomponent = Component.Serializer.fromJson(nbttagcompound.getString("Name"));
++
++ if (ichatmutablecomponent != null) {
++ return ichatmutablecomponent;
+ }
+
+- tagElement.remove("Name");
+- } catch (Exception var3) {
+- tagElement.remove("Name");
++ nbttagcompound.remove("Name");
++ } catch (Exception exception) {
++ nbttagcompound.remove("Name");
+ }
+ }
+
+@@ -579,21 +857,23 @@
+ }
+
+ public ItemStack setHoverName(@Nullable Component nameComponent) {
+- CompoundTag tagElement = this.getOrCreateTagElement("display");
++ CompoundTag nbttagcompound = this.getOrCreateTagElement("display");
++
+ if (nameComponent != null) {
+- tagElement.putString("Name", Component.Serializer.toJson(nameComponent));
++ nbttagcompound.putString("Name", Component.Serializer.toJson(nameComponent));
+ } else {
+- tagElement.remove("Name");
++ nbttagcompound.remove("Name");
+ }
+
+ return this;
+ }
+
+ public void resetHoverName() {
+- CompoundTag tagElement = this.getTagElement("display");
+- if (tagElement != null) {
+- tagElement.remove("Name");
+- if (tagElement.isEmpty()) {
++ CompoundTag nbttagcompound = this.getTagElement("display");
++
++ if (nbttagcompound != null) {
++ nbttagcompound.remove("Name");
++ if (nbttagcompound.isEmpty()) {
+ this.removeTagKey("display");
+ }
+ }
+@@ -601,136 +881,132 @@
+ if (this.tag != null && this.tag.isEmpty()) {
+ this.tag = null;
+ }
++
+ }
+
+ public boolean hasCustomHoverName() {
+- CompoundTag tagElement = this.getTagElement("display");
+- return tagElement != null && tagElement.contains("Name", 8);
++ CompoundTag nbttagcompound = this.getTagElement("display");
++
++ return nbttagcompound != null && nbttagcompound.contains("Name", 8);
+ }
+
+- public List<Component> getTooltipLines(@Nullable Player player, TooltipFlag isAdvanced) {
++ public List<Component> getTooltipLines(@Nullable net.minecraft.world.entity.player.Player player, TooltipFlag isAdvanced) {
+ List<Component> list = Lists.newArrayList();
+- MutableComponent mutableComponent = Component.empty().append(this.getHoverName()).withStyle(this.getRarity().color);
++ MutableComponent ichatmutablecomponent = Component.empty().append(this.getHoverName()).withStyle(this.getRarity().color);
++
+ if (this.hasCustomHoverName()) {
+- mutableComponent.withStyle(ChatFormatting.ITALIC);
++ ichatmutablecomponent.withStyle(ChatFormatting.ITALIC);
+ }
+
+- list.add(mutableComponent);
++ list.add(ichatmutablecomponent);
+ if (!isAdvanced.isAdvanced() && !this.hasCustomHoverName() && this.is(Items.FILLED_MAP)) {
+- Integer mapId = MapItem.getMapId(this);
+- if (mapId != null) {
++ Integer integer = MapItem.getMapId(this);
++
++ if (integer != null) {
+ list.add(MapItem.getTooltipForId(this));
+ }
+ }
+
+- int hideFlags = this.getHideFlags();
+- if (shouldShowInTooltip(hideFlags, ItemStack.TooltipPart.ADDITIONAL)) {
++ int i = this.getHideFlags();
++
++ if (shouldShowInTooltip(i, ItemStack.HideFlags.ADDITIONAL)) {
+ this.getItem().appendHoverText(this, player == null ? null : player.level(), list, isAdvanced);
+ }
+
++ int j;
++
+ if (this.hasTag()) {
+- if (shouldShowInTooltip(hideFlags, ItemStack.TooltipPart.UPGRADES) && player != null) {
++ if (shouldShowInTooltip(i, ItemStack.HideFlags.UPGRADES) && player != null) {
+ ArmorTrim.appendUpgradeHoverText(this, player.level().registryAccess(), list);
+ }
+
+- if (shouldShowInTooltip(hideFlags, ItemStack.TooltipPart.ENCHANTMENTS)) {
++ if (shouldShowInTooltip(i, ItemStack.HideFlags.ENCHANTMENTS)) {
+ appendEnchantmentNames(list, this.getEnchantmentTags());
+ }
+
+ if (this.tag.contains("display", 10)) {
+- CompoundTag compound = this.tag.getCompound("display");
+- if (shouldShowInTooltip(hideFlags, ItemStack.TooltipPart.DYE) && compound.contains("color", 99)) {
++ CompoundTag nbttagcompound = this.tag.getCompound("display");
++
++ if (shouldShowInTooltip(i, ItemStack.HideFlags.DYE) && nbttagcompound.contains("color", 99)) {
+ if (isAdvanced.isAdvanced()) {
+- list.add(
+- Component.translatable("item.color", String.format(Locale.ROOT, "#%06X", compound.getInt("color"))).withStyle(ChatFormatting.GRAY)
+- );
++ list.add(Component.translatable("item.color", String.format(Locale.ROOT, "#%06X", nbttagcompound.getInt("color"))).withStyle(ChatFormatting.GRAY));
+ } else {
+ list.add(Component.translatable("item.dyed").withStyle(ChatFormatting.GRAY, ChatFormatting.ITALIC));
+ }
+ }
+
+- if (compound.getTagType("Lore") == 9) {
+- ListTag list1 = compound.getList("Lore", 8);
++ if (nbttagcompound.getTagType("Lore") == 9) {
++ ListTag nbttaglist = nbttagcompound.getList("Lore", 8);
+
+- for (int i = 0; i < list1.size(); i++) {
+- String string = list1.getString(i);
++ for (j = 0; j < nbttaglist.size(); ++j) {
++ String s = nbttaglist.getString(j);
+
+ try {
+- MutableComponent mutableComponent1 = Component.Serializer.fromJson(string);
+- if (mutableComponent1 != null) {
+- list.add(ComponentUtils.mergeStyles(mutableComponent1, LORE_STYLE));
++ MutableComponent ichatmutablecomponent1 = Component.Serializer.fromJson(s);
++
++ if (ichatmutablecomponent1 != null) {
++ list.add(ComponentUtils.mergeStyles(ichatmutablecomponent1, ItemStack.LORE_STYLE));
+ }
+- } catch (Exception var19) {
+- compound.remove("Lore");
++ } catch (Exception exception) {
++ nbttagcompound.remove("Lore");
+ }
+ }
+ }
+ }
+ }
+
+- if (shouldShowInTooltip(hideFlags, ItemStack.TooltipPart.MODIFIERS)) {
+- for (EquipmentSlot equipmentSlot : EquipmentSlot.values()) {
+- Multimap<Attribute, AttributeModifier> attributeModifiers = this.getAttributeModifiers(equipmentSlot);
+- if (!attributeModifiers.isEmpty()) {
++ int k;
++
++ if (shouldShowInTooltip(i, ItemStack.HideFlags.MODIFIERS)) {
++ EquipmentSlot[] aenumitemslot = EquipmentSlot.values();
++
++ k = aenumitemslot.length;
++
++ for (j = 0; j < k; ++j) {
++ EquipmentSlot enumitemslot = aenumitemslot[j];
++ Multimap<Attribute, AttributeModifier> multimap = this.getAttributeModifiers(enumitemslot);
++
++ if (!multimap.isEmpty()) {
+ list.add(CommonComponents.EMPTY);
+- list.add(Component.translatable("item.modifiers." + equipmentSlot.getName()).withStyle(ChatFormatting.GRAY));
++ list.add(Component.translatable("item.modifiers." + enumitemslot.getName()).withStyle(ChatFormatting.GRAY));
++ Iterator iterator = multimap.entries().iterator();
+
+- for (Entry<Attribute, AttributeModifier> entry : attributeModifiers.entries()) {
+- AttributeModifier attributeModifier = entry.getValue();
+- double amount = attributeModifier.getAmount();
++ while (iterator.hasNext()) {
++ Entry<Attribute, AttributeModifier> entry = (Entry) iterator.next();
++ AttributeModifier attributemodifier = (AttributeModifier) entry.getValue();
++ double d0 = attributemodifier.getAmount();
+ boolean flag = false;
++
+ if (player != null) {
+- if (attributeModifier.getId() == Item.BASE_ATTACK_DAMAGE_UUID) {
+- amount += player.getAttributeBaseValue(Attributes.ATTACK_DAMAGE);
+- amount += (double)EnchantmentHelper.getDamageBonus(this, MobType.UNDEFINED);
++ if (attributemodifier.getId() == Item.BASE_ATTACK_DAMAGE_UUID) {
++ d0 += player.getAttributeBaseValue(Attributes.ATTACK_DAMAGE);
++ d0 += (double) EnchantmentHelper.getDamageBonus(this, EnumMonsterType.UNDEFINED);
+ flag = true;
+- } else if (attributeModifier.getId() == Item.BASE_ATTACK_SPEED_UUID) {
+- amount += player.getAttributeBaseValue(Attributes.ATTACK_SPEED);
++ } else if (attributemodifier.getId() == Item.BASE_ATTACK_SPEED_UUID) {
++ d0 += player.getAttributeBaseValue(Attributes.ATTACK_SPEED);
+ flag = true;
+ }
+ }
+
+- double d;
+- if (attributeModifier.getOperation() == AttributeModifier.Operation.MULTIPLY_BASE
+- || attributeModifier.getOperation() == AttributeModifier.Operation.MULTIPLY_TOTAL) {
+- d = amount * 100.0;
+- } else if (entry.getKey().equals(Attributes.KNOCKBACK_RESISTANCE)) {
+- d = amount * 10.0;
++ double d1;
++
++ if (attributemodifier.getOperation() != AttributeModifier.Operation.MULTIPLY_BASE && attributemodifier.getOperation() != AttributeModifier.Operation.MULTIPLY_TOTAL) {
++ if (((Attribute) entry.getKey()).equals(Attributes.KNOCKBACK_RESISTANCE)) {
++ d1 = d0 * 10.0D;
++ } else {
++ d1 = d0;
++ }
+ } else {
+- d = amount;
++ d1 = d0 * 100.0D;
+ }
+
+ if (flag) {
+- list.add(
+- CommonComponents.space()
+- .append(
+- Component.translatable(
+- "attribute.modifier.equals." + attributeModifier.getOperation().toValue(),
+- ATTRIBUTE_MODIFIER_FORMAT.format(d),
+- Component.translatable(entry.getKey().getDescriptionId())
+- )
+- )
+- .withStyle(ChatFormatting.DARK_GREEN)
+- );
+- } else if (amount > 0.0) {
+- list.add(
+- Component.translatable(
+- "attribute.modifier.plus." + attributeModifier.getOperation().toValue(),
+- ATTRIBUTE_MODIFIER_FORMAT.format(d),
+- Component.translatable(entry.getKey().getDescriptionId())
+- )
+- .withStyle(ChatFormatting.BLUE)
+- );
+- } else if (amount < 0.0) {
+- d *= -1.0;
+- list.add(
+- Component.translatable(
+- "attribute.modifier.take." + attributeModifier.getOperation().toValue(),
+- ATTRIBUTE_MODIFIER_FORMAT.format(d),
+- Component.translatable(entry.getKey().getDescriptionId())
+- )
+- .withStyle(ChatFormatting.RED)
+- );
++ list.add(CommonComponents.space().append((Component) Component.translatable("attribute.modifier.equals." + attributemodifier.getOperation().toValue(), ItemStack.ATTRIBUTE_MODIFIER_FORMAT.format(d1), Component.translatable(((Attribute) entry.getKey()).getDescriptionId()))).withStyle(ChatFormatting.DARK_GREEN));
++ } else if (d0 > 0.0D) {
++ list.add(Component.translatable("attribute.modifier.plus." + attributemodifier.getOperation().toValue(), ItemStack.ATTRIBUTE_MODIFIER_FORMAT.format(d1), Component.translatable(((Attribute) entry.getKey()).getDescriptionId())).withStyle(ChatFormatting.BLUE));
++ } else if (d0 < 0.0D) {
++ d1 *= -1.0D;
++ list.add(Component.translatable("attribute.modifier.take." + attributemodifier.getOperation().toValue(), ItemStack.ATTRIBUTE_MODIFIER_FORMAT.format(d1), Component.translatable(((Attribute) entry.getKey()).getDescriptionId())).withStyle(ChatFormatting.RED));
+ }
+ }
+ }
+@@ -738,30 +1014,32 @@
+ }
+
+ if (this.hasTag()) {
+- if (shouldShowInTooltip(hideFlags, ItemStack.TooltipPart.UNBREAKABLE) && this.tag.getBoolean("Unbreakable")) {
++ if (shouldShowInTooltip(i, ItemStack.HideFlags.UNBREAKABLE) && this.tag.getBoolean("Unbreakable")) {
+ list.add(Component.translatable("item.unbreakable").withStyle(ChatFormatting.BLUE));
+ }
+
+- if (shouldShowInTooltip(hideFlags, ItemStack.TooltipPart.CAN_DESTROY) && this.tag.contains("CanDestroy", 9)) {
+- ListTag list2 = this.tag.getList("CanDestroy", 8);
+- if (!list2.isEmpty()) {
++ ListTag nbttaglist1;
++
++ if (shouldShowInTooltip(i, ItemStack.HideFlags.CAN_DESTROY) && this.tag.contains("CanDestroy", 9)) {
++ nbttaglist1 = this.tag.getList("CanDestroy", 8);
++ if (!nbttaglist1.isEmpty()) {
+ list.add(CommonComponents.EMPTY);
+ list.add(Component.translatable("item.canBreak").withStyle(ChatFormatting.GRAY));
+
+- for (int i1 = 0; i1 < list2.size(); i1++) {
+- list.addAll(expandBlockState(list2.getString(i1)));
++ for (k = 0; k < nbttaglist1.size(); ++k) {
++ list.addAll(expandBlockState(nbttaglist1.getString(k)));
+ }
+ }
+ }
+
+- if (shouldShowInTooltip(hideFlags, ItemStack.TooltipPart.CAN_PLACE) && this.tag.contains("CanPlaceOn", 9)) {
+- ListTag list2 = this.tag.getList("CanPlaceOn", 8);
+- if (!list2.isEmpty()) {
++ if (shouldShowInTooltip(i, ItemStack.HideFlags.CAN_PLACE) && this.tag.contains("CanPlaceOn", 9)) {
++ nbttaglist1 = this.tag.getList("CanPlaceOn", 8);
++ if (!nbttaglist1.isEmpty()) {
+ list.add(CommonComponents.EMPTY);
+ list.add(Component.translatable("item.canPlace").withStyle(ChatFormatting.GRAY));
+
+- for (int i1 = 0; i1 < list2.size(); i1++) {
+- list.addAll(expandBlockState(list2.getString(i1)));
++ for (k = 0; k < nbttaglist1.size(); ++k) {
++ list.addAll(expandBlockState(nbttaglist1.getString(k)));
+ }
+ }
+ }
+@@ -779,13 +1057,13 @@
+ }
+
+ if (player != null && !this.getItem().isEnabled(player.level().enabledFeatures())) {
+- list.add(DISABLED_ITEM_TOOLTIP);
++ list.add(ItemStack.DISABLED_ITEM_TOOLTIP);
+ }
+
+ return list;
+ }
+
+- private static boolean shouldShowInTooltip(int hideFlags, ItemStack.TooltipPart part) {
++ private static boolean shouldShowInTooltip(int hideFlags, ItemStack.HideFlags part) {
+ return (hideFlags & part.getMask()) == 0;
+ }
+
+@@ -793,32 +1071,34 @@
+ return this.hasTag() && this.tag.contains("HideFlags", 99) ? this.tag.getInt("HideFlags") : 0;
+ }
+
+- public void hideTooltipPart(ItemStack.TooltipPart part) {
+- CompoundTag tag = this.getOrCreateTag();
+- tag.putInt("HideFlags", tag.getInt("HideFlags") | part.getMask());
++ public void hideTooltipPart(ItemStack.HideFlags part) {
++ CompoundTag nbttagcompound = this.getOrCreateTag();
++
++ nbttagcompound.putInt("HideFlags", nbttagcompound.getInt("HideFlags") | part.getMask());
+ }
+
+ public static void appendEnchantmentNames(List<Component> tooltipComponents, ListTag storedEnchantments) {
+- for (int i = 0; i < storedEnchantments.size(); i++) {
+- CompoundTag compound = storedEnchantments.getCompound(i);
+- BuiltInRegistries.ENCHANTMENT
+- .getOptional(EnchantmentHelper.getEnchantmentId(compound))
+- .ifPresent(enchantment -> tooltipComponents.add(enchantment.getFullname(EnchantmentHelper.getEnchantmentLevel(compound))));
++ for (int i = 0; i < storedEnchantments.size(); ++i) {
++ CompoundTag nbttagcompound = storedEnchantments.getCompound(i);
++
++ BuiltInRegistries.ENCHANTMENT.getOptional(EnchantmentHelper.getEnchantmentId(nbttagcompound)).ifPresent((enchantment) -> {
++ tooltipComponents.add(enchantment.getFullname(EnchantmentHelper.getEnchantmentLevel(nbttagcompound)));
++ });
+ }
++
+ }
+
+ private static Collection<Component> expandBlockState(String stateString) {
+ try {
+- return BlockStateParser.parseForTesting(BuiltInRegistries.BLOCK.asLookup(), stateString, true)
+- .map(
+- blockResult -> Lists.newArrayList(blockResult.blockState().getBlock().getName().withStyle(ChatFormatting.DARK_GRAY)),
+- tagResult -> tagResult.tag()
+- .stream()
+- .map(holder -> holder.value().getName().withStyle(ChatFormatting.DARK_GRAY))
+- .collect(Collectors.toList())
+- );
+- } catch (CommandSyntaxException var2) {
+- return Lists.newArrayList(Component.literal("missingno").withStyle(ChatFormatting.DARK_GRAY));
++ return (Collection) BlockStateParser.parseForTesting(BuiltInRegistries.BLOCK.asLookup(), stateString, true).map((argumentblock_a) -> {
++ return Lists.newArrayList(new Component[]{argumentblock_a.blockState().getBlock().getName().withStyle(ChatFormatting.DARK_GRAY)});
++ }, (argumentblock_b) -> {
++ return (List) argumentblock_b.tag().stream().map((holder) -> {
++ return ((Block) holder.value()).getName().withStyle(ChatFormatting.DARK_GRAY);
++ }).collect(Collectors.toList());
++ });
++ } catch (CommandSyntaxException commandsyntaxexception) {
++ return Lists.newArrayList(new Component[]{Component.literal("missingno").withStyle(ChatFormatting.DARK_GRAY)});
+ }
+ }
+
+@@ -831,7 +1111,7 @@
+ }
+
+ public boolean isEnchantable() {
+- return this.getItem().isEnchantable(this) && !this.isEnchanted();
++ return !this.getItem().isEnchantable(this) ? false : !this.isEnchanted();
+ }
+
+ public void enchant(Enchantment enchantment, int level) {
+@@ -840,12 +1120,13 @@
+ this.tag.put("Enchantments", new ListTag());
+ }
+
+- ListTag list = this.tag.getList("Enchantments", 10);
+- list.add(EnchantmentHelper.storeEnchantment(EnchantmentHelper.getEnchantmentId(enchantment), (byte)level));
++ ListTag nbttaglist = this.tag.getList("Enchantments", 10);
++
++ nbttaglist.add(EnchantmentHelper.storeEnchantment(EnchantmentHelper.getEnchantmentId(enchantment), (byte) level));
+ }
+
+ public boolean isEnchanted() {
+- return this.tag != null && this.tag.contains("Enchantments", 9) && !this.tag.getList("Enchantments", 10).isEmpty();
++ return this.tag != null && this.tag.contains("Enchantments", 9) ? !this.tag.getList("Enchantments", 10).isEmpty() : false;
+ }
+
+ public void addTagElement(String key, Tag tag) {
+@@ -862,7 +1143,7 @@
+
+ @Nullable
+ public ItemFrame getFrame() {
+- return this.entityRepresentation instanceof ItemFrame ? (ItemFrame)this.getEntityRepresentation() : null;
++ return this.entityRepresentation instanceof ItemFrame ? (ItemFrame) this.getEntityRepresentation() : null;
+ }
+
+ @Nullable
+@@ -880,33 +1161,36 @@
+ } else {
+ this.removeTagKey("RepairCost");
+ }
++
+ }
+
+ public Multimap<Attribute, AttributeModifier> getAttributeModifiers(EquipmentSlot slot) {
+- Multimap<Attribute, AttributeModifier> multimap;
++ Object object;
++
+ if (this.hasTag() && this.tag.contains("AttributeModifiers", 9)) {
+- multimap = HashMultimap.create();
+- ListTag list = this.tag.getList("AttributeModifiers", 10);
++ object = HashMultimap.create();
++ ListTag nbttaglist = this.tag.getList("AttributeModifiers", 10);
+
+- for (int i = 0; i < list.size(); i++) {
+- CompoundTag compound = list.getCompound(i);
+- if (!compound.contains("Slot", 8) || compound.getString("Slot").equals(slot.getName())) {
+- Optional<Attribute> optional = BuiltInRegistries.ATTRIBUTE.getOptional(ResourceLocation.tryParse(compound.getString("AttributeName")));
++ for (int i = 0; i < nbttaglist.size(); ++i) {
++ CompoundTag nbttagcompound = nbttaglist.getCompound(i);
++
++ if (!nbttagcompound.contains("Slot", 8) || nbttagcompound.getString("Slot").equals(slot.getName())) {
++ Optional<Attribute> optional = BuiltInRegistries.ATTRIBUTE.getOptional(ResourceLocation.tryParse(nbttagcompound.getString("AttributeName")));
++
+ if (!optional.isEmpty()) {
+- AttributeModifier attributeModifier = AttributeModifier.load(compound);
+- if (attributeModifier != null
+- && attributeModifier.getId().getLeastSignificantBits() != 0L
+- && attributeModifier.getId().getMostSignificantBits() != 0L) {
+- multimap.put(optional.get(), attributeModifier);
++ AttributeModifier attributemodifier = AttributeModifier.load(nbttagcompound);
++
++ if (attributemodifier != null && attributemodifier.getId().getLeastSignificantBits() != 0L && attributemodifier.getId().getMostSignificantBits() != 0L) {
++ ((Multimap) object).put((Attribute) optional.get(), attributemodifier);
+ }
+ }
+ }
+ }
+ } else {
+- multimap = this.getItem().getDefaultAttributeModifiers(slot);
++ object = this.getItem().getDefaultAttributeModifiers(slot);
+ }
+
+- return multimap;
++ return (Multimap) object;
+ }
+
+ public void addAttributeModifier(Attribute attribute, AttributeModifier modifier, @Nullable EquipmentSlot slot) {
+@@ -915,29 +1199,40 @@
+ this.tag.put("AttributeModifiers", new ListTag());
+ }
+
+- ListTag list = this.tag.getList("AttributeModifiers", 10);
+- CompoundTag compoundTag = modifier.save();
+- compoundTag.putString("AttributeName", BuiltInRegistries.ATTRIBUTE.getKey(attribute).toString());
++ ListTag nbttaglist = this.tag.getList("AttributeModifiers", 10);
++ CompoundTag nbttagcompound = modifier.save();
++
++ nbttagcompound.putString("AttributeName", BuiltInRegistries.ATTRIBUTE.getKey(attribute).toString());
+ if (slot != null) {
+- compoundTag.putString("Slot", slot.getName());
++ nbttagcompound.putString("Slot", slot.getName());
+ }
+
+- list.add(compoundTag);
++ nbttaglist.add(nbttagcompound);
+ }
+
++ // CraftBukkit start
++ @Deprecated
++ public void setItem(Item item) {
++ this.item = item;
++ }
++ // CraftBukkit end
++
+ public Component getDisplayName() {
+- MutableComponent mutableComponent = Component.empty().append(this.getHoverName());
++ MutableComponent ichatmutablecomponent = Component.empty().append(this.getHoverName());
++
+ if (this.hasCustomHoverName()) {
+- mutableComponent.withStyle(ChatFormatting.ITALIC);
++ ichatmutablecomponent.withStyle(ChatFormatting.ITALIC);
+ }
+
+- MutableComponent mutableComponent1 = ComponentUtils.wrapInSquareBrackets(mutableComponent);
++ MutableComponent ichatmutablecomponent1 = ComponentUtils.wrapInSquareBrackets(ichatmutablecomponent);
++
+ if (!this.isEmpty()) {
+- mutableComponent1.withStyle(this.getRarity().color)
+- .withStyle(style -> style.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_ITEM, new HoverEvent.ItemStackInfo(this))));
++ ichatmutablecomponent1.withStyle(this.getRarity().color).withStyle((chatmodifier) -> {
++ return chatmodifier.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_ITEM, new HoverEvent.ItemStackInfo(this)));
++ });
+ }
+
+- return mutableComponent1;
++ return ichatmutablecomponent1;
+ }
+
+ public boolean hasAdventureModePlaceTagForBlock(Registry<Block> blockRegistry, BlockInWorld block) {
+@@ -1000,18 +1295,14 @@
+ return this.getItem().getEatingSound();
+ }
+
+- public static enum TooltipPart {
+- ENCHANTMENTS,
+- MODIFIERS,
+- UNBREAKABLE,
+- CAN_DESTROY,
+- CAN_PLACE,
+- ADDITIONAL,
+- DYE,
+- UPGRADES;
++ public static enum HideFlags {
+
++ ENCHANTMENTS, MODIFIERS, UNBREAKABLE, CAN_DESTROY, CAN_PLACE, ADDITIONAL, DYE, UPGRADES;
++
+ private final int mask = 1 << this.ordinal();
+
++ private HideFlags() {}
++
+ public int getMask() {
+ return this.mask;
+ }