diff options
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.patch | 1384 |
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; + } |