Code/net/minecraft/world/item/ItemStack.java

1154 lines
48 KiB
Java

package net.minecraft.world.item;
import com.google.common.collect.Lists;
import com.mojang.logging.LogUtils;
import com.mojang.serialization.Codec;
import com.mojang.serialization.DataResult;
import com.mojang.serialization.MapCodec;
import com.mojang.serialization.DataResult.Error;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import com.mojang.serialization.codecs.RecordCodecBuilder.Instance;
import io.netty.handler.codec.DecoderException;
import io.netty.handler.codec.EncoderException;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;
import java.util.stream.Stream;
import javax.annotation.Nullable;
import net.minecraft.ChatFormatting;
import net.minecraft.advancements.CriteriaTriggers;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Holder;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.HolderSet;
import net.minecraft.core.NonNullList;
import net.minecraft.core.component.DataComponentGetter;
import net.minecraft.core.component.DataComponentHolder;
import net.minecraft.core.component.DataComponentMap;
import net.minecraft.core.component.DataComponentPatch;
import net.minecraft.core.component.DataComponentType;
import net.minecraft.core.component.DataComponents;
import net.minecraft.core.component.PatchedDataComponentMap;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.nbt.NbtOps;
import net.minecraft.nbt.Tag;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.chat.CommonComponents;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.ComponentUtils;
import net.minecraft.network.chat.HoverEvent;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.network.chat.Style;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.resources.RegistryOps;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.stats.Stats;
import net.minecraft.tags.TagKey;
import net.minecraft.util.ExtraCodecs;
import net.minecraft.util.Mth;
import net.minecraft.util.NullOps;
import net.minecraft.util.StringUtil;
import net.minecraft.util.Unit;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.EquipmentSlotGroup;
import net.minecraft.world.entity.LivingEntity;
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;
import net.minecraft.world.inventory.tooltip.TooltipComponent;
import net.minecraft.world.item.component.Consumable;
import net.minecraft.world.item.component.CustomData;
import net.minecraft.world.item.component.DamageResistant;
import net.minecraft.world.item.component.ItemAttributeModifiers;
import net.minecraft.world.item.component.ItemContainerContents;
import net.minecraft.world.item.component.TooltipDisplay;
import net.minecraft.world.item.component.TooltipProvider;
import net.minecraft.world.item.component.UseCooldown;
import net.minecraft.world.item.component.UseRemainder;
import net.minecraft.world.item.component.Weapon;
import net.minecraft.world.item.component.WrittenBookContent;
import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.world.item.enchantment.Enchantment;
import net.minecraft.world.item.enchantment.EnchantmentHelper;
import net.minecraft.world.item.enchantment.ItemEnchantments;
import net.minecraft.world.item.enchantment.Repairable;
import net.minecraft.world.item.equipment.Equippable;
import net.minecraft.world.level.ItemLike;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.Spawner;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.pattern.BlockInWorld;
import org.apache.commons.lang3.mutable.MutableBoolean;
import org.slf4j.Logger;
public final class ItemStack implements DataComponentHolder {
private static final List<Component> OP_NBT_WARNING = List.of(
Component.translatable("item.op_warning.line1").withStyle(ChatFormatting.RED, ChatFormatting.BOLD),
Component.translatable("item.op_warning.line2").withStyle(ChatFormatting.RED),
Component.translatable("item.op_warning.line3").withStyle(ChatFormatting.RED)
);
private static final Component UNBREAKABLE_TOOLTIP = Component.translatable("item.unbreakable").withStyle(ChatFormatting.BLUE);
public static final MapCodec<ItemStack> MAP_CODEC = MapCodec.recursive(
"ItemStack",
p_390809_ -> RecordCodecBuilder.mapCodec(
p_359412_ -> p_359412_.group(
Item.CODEC.fieldOf("id").forGetter(ItemStack::getItemHolder),
ExtraCodecs.intRange(1, 99).fieldOf("count").orElse(1).forGetter(ItemStack::getCount),
DataComponentPatch.CODEC
.optionalFieldOf("components", DataComponentPatch.EMPTY)
.forGetter(p_327171_ -> p_327171_.components.asPatch())
)
.apply(p_359412_, ItemStack::new)
)
);
public static final Codec<ItemStack> CODEC = Codec.lazyInitialized(MAP_CODEC::codec);
public static final Codec<ItemStack> SINGLE_ITEM_CODEC = Codec.lazyInitialized(
() -> RecordCodecBuilder.create(
p_359410_ -> p_359410_.group(
Item.CODEC.fieldOf("id").forGetter(ItemStack::getItemHolder),
DataComponentPatch.CODEC
.optionalFieldOf("components", DataComponentPatch.EMPTY)
.forGetter(p_327155_ -> p_327155_.components.asPatch())
)
.apply(p_359410_, (p_327172_, p_327173_) -> new ItemStack(p_327172_, 1, p_327173_))
)
);
public static final Codec<ItemStack> STRICT_CODEC = CODEC.validate(ItemStack::validateStrict);
public static final Codec<ItemStack> STRICT_SINGLE_ITEM_CODEC = SINGLE_ITEM_CODEC.validate(ItemStack::validateStrict);
public static final Codec<ItemStack> OPTIONAL_CODEC = ExtraCodecs.optionalEmptyMap(CODEC)
.xmap(p_327153_ -> p_327153_.orElse(ItemStack.EMPTY), p_327154_ -> p_327154_.isEmpty() ? Optional.empty() : Optional.of(p_327154_));
public static final Codec<ItemStack> SIMPLE_ITEM_CODEC = Item.CODEC.xmap(ItemStack::new, ItemStack::getItemHolder);
public static final StreamCodec<RegistryFriendlyByteBuf, ItemStack> OPTIONAL_STREAM_CODEC = createOptionalStreamCodec(DataComponentPatch.STREAM_CODEC);
public static final StreamCodec<RegistryFriendlyByteBuf, ItemStack> OPTIONAL_UNTRUSTED_STREAM_CODEC = createOptionalStreamCodec(DataComponentPatch.DELIMITED_STREAM_CODEC);
public static final StreamCodec<RegistryFriendlyByteBuf, ItemStack> STREAM_CODEC = new StreamCodec<RegistryFriendlyByteBuf, ItemStack>() {
public ItemStack decode(RegistryFriendlyByteBuf p_327992_) {
ItemStack itemstack = ItemStack.OPTIONAL_STREAM_CODEC.decode(p_327992_);
if (itemstack.isEmpty()) {
throw new DecoderException("Empty ItemStack not allowed");
} else {
return itemstack;
}
}
public void encode(RegistryFriendlyByteBuf p_331904_, ItemStack p_328866_) {
if (p_328866_.isEmpty()) {
throw new EncoderException("Empty ItemStack not allowed");
} else {
ItemStack.OPTIONAL_STREAM_CODEC.encode(p_331904_, p_328866_);
}
}
};
public static final StreamCodec<RegistryFriendlyByteBuf, List<ItemStack>> OPTIONAL_LIST_STREAM_CODEC = OPTIONAL_STREAM_CODEC.apply(ByteBufCodecs.collection(NonNullList::createWithCapacity));
private static final Logger LOGGER = LogUtils.getLogger();
public static final ItemStack EMPTY = new ItemStack((Void)null);
private static final Component DISABLED_ITEM_TOOLTIP = Component.translatable("item.disabled").withStyle(ChatFormatting.RED);
private int count;
private int popTime;
@Deprecated
@Nullable
private final Item item;
final PatchedDataComponentMap components;
@Nullable
private Entity entityRepresentation;
public static DataResult<ItemStack> validateStrict(ItemStack p_332181_) {
DataResult<Unit> dataresult = validateComponents(p_332181_.getComponents());
if (dataresult.isError()) {
return dataresult.map(p_327165_ -> p_332181_);
} else {
return p_332181_.getCount() > p_332181_.getMaxStackSize()
? DataResult.error(() -> "Item stack with stack size of " + p_332181_.getCount() + " was larger than maximum: " + p_332181_.getMaxStackSize())
: DataResult.success(p_332181_);
}
}
private static StreamCodec<RegistryFriendlyByteBuf, ItemStack> createOptionalStreamCodec(final StreamCodec<RegistryFriendlyByteBuf, DataComponentPatch> p_393485_) {
return new StreamCodec<RegistryFriendlyByteBuf, ItemStack>() {
public ItemStack decode(RegistryFriendlyByteBuf p_328393_) {
int i = p_328393_.readVarInt();
if (i <= 0) {
return ItemStack.EMPTY;
} else {
Holder<Item> holder = Item.STREAM_CODEC.decode(p_328393_);
DataComponentPatch datacomponentpatch = p_393485_.decode(p_328393_);
return new ItemStack(holder, i, datacomponentpatch);
}
}
public void encode(RegistryFriendlyByteBuf p_332266_, ItemStack p_335702_) {
if (p_335702_.isEmpty()) {
p_332266_.writeVarInt(0);
} else {
p_332266_.writeVarInt(p_335702_.getCount());
Item.STREAM_CODEC.encode(p_332266_, p_335702_.getItemHolder());
p_393485_.encode(p_332266_, p_335702_.components.asPatch());
}
}
};
}
public static StreamCodec<RegistryFriendlyByteBuf, ItemStack> validatedStreamCodec(final StreamCodec<RegistryFriendlyByteBuf, ItemStack> p_332790_) {
return new StreamCodec<RegistryFriendlyByteBuf, ItemStack>() {
public ItemStack decode(RegistryFriendlyByteBuf p_330762_) {
ItemStack itemstack = p_332790_.decode(p_330762_);
if (!itemstack.isEmpty()) {
RegistryOps<Unit> registryops = p_330762_.registryAccess().createSerializationContext(NullOps.INSTANCE);
ItemStack.CODEC.encodeStart(registryops, itemstack).getOrThrow(DecoderException::new);
}
return itemstack;
}
public void encode(RegistryFriendlyByteBuf p_336131_, ItemStack p_329943_) {
p_332790_.encode(p_336131_, p_329943_);
}
};
}
public Optional<TooltipComponent> getTooltipImage() {
return this.getItem().getTooltipImage(this);
}
@Override
public DataComponentMap getComponents() {
return (DataComponentMap)(!this.isEmpty() ? this.components : DataComponentMap.EMPTY);
}
public DataComponentMap getPrototype() {
return !this.isEmpty() ? this.getItem().components() : DataComponentMap.EMPTY;
}
public DataComponentPatch getComponentsPatch() {
return !this.isEmpty() ? this.components.asPatch() : DataComponentPatch.EMPTY;
}
public DataComponentMap immutableComponents() {
return !this.isEmpty() ? this.components.toImmutableMap() : DataComponentMap.EMPTY;
}
public boolean hasNonDefault(DataComponentType<?> p_377204_) {
return !this.isEmpty() && this.components.hasNonDefault(p_377204_);
}
public ItemStack(ItemLike p_41599_) {
this(p_41599_, 1);
}
public ItemStack(Holder<Item> p_204116_) {
this(p_204116_.value(), 1);
}
public ItemStack(Holder<Item> p_310702_, int p_41605_, DataComponentPatch p_328221_) {
this(p_310702_.value(), p_41605_, PatchedDataComponentMap.fromPatch(p_310702_.value().components(), p_328221_));
}
public ItemStack(Holder<Item> p_220155_, int p_220156_) {
this(p_220155_.value(), p_220156_);
}
public ItemStack(ItemLike p_41601_, int p_41602_) {
this(p_41601_, p_41602_, new PatchedDataComponentMap(p_41601_.asItem().components()));
}
private ItemStack(ItemLike p_331826_, int p_332766_, PatchedDataComponentMap p_333722_) {
this.item = p_331826_.asItem();
this.count = p_332766_;
this.components = p_333722_;
this.getItem().verifyComponentsAfterLoad(this);
}
private ItemStack(@Nullable Void p_282703_) {
this.item = null;
this.components = new PatchedDataComponentMap(DataComponentMap.EMPTY);
}
public static DataResult<Unit> validateComponents(DataComponentMap p_336343_) {
if (p_336343_.has(DataComponents.MAX_DAMAGE) && p_336343_.getOrDefault(DataComponents.MAX_STACK_SIZE, 1) > 1) {
return DataResult.error(() -> "Item cannot be both damageable and stackable");
} else {
ItemContainerContents itemcontainercontents = p_336343_.getOrDefault(DataComponents.CONTAINER, ItemContainerContents.EMPTY);
for (ItemStack itemstack : itemcontainercontents.nonEmptyItems()) {
int i = itemstack.getCount();
int j = itemstack.getMaxStackSize();
if (i > j) {
return DataResult.error(() -> "Item stack with count of " + i + " was larger than maximum: " + j);
}
}
return DataResult.success(Unit.INSTANCE);
}
}
public static Optional<ItemStack> parse(HolderLookup.Provider p_332204_, Tag p_336056_) {
return CODEC.parse(p_332204_.createSerializationContext(NbtOps.INSTANCE), p_336056_)
.resultOrPartial(p_327167_ -> LOGGER.error("Tried to load invalid item: '{}'", p_327167_));
}
public boolean isEmpty() {
return this == EMPTY || this.item == Items.AIR || this.count <= 0;
}
public boolean isItemEnabled(FeatureFlagSet p_250869_) {
return this.isEmpty() || this.getItem().isEnabled(p_250869_);
}
public ItemStack split(int p_41621_) {
int i = Math.min(p_41621_, this.getCount());
ItemStack itemstack = this.copyWithCount(i);
this.shrink(i);
return itemstack;
}
public ItemStack copyAndClear() {
if (this.isEmpty()) {
return EMPTY;
} else {
ItemStack itemstack = this.copy();
this.setCount(0);
return itemstack;
}
}
public Item getItem() {
return this.isEmpty() ? Items.AIR : this.item;
}
public Holder<Item> getItemHolder() {
return this.getItem().builtInRegistryHolder();
}
public boolean is(TagKey<Item> p_204118_) {
return this.getItem().builtInRegistryHolder().is(p_204118_);
}
public boolean is(Item p_150931_) {
return this.getItem() == p_150931_;
}
public boolean is(Predicate<Holder<Item>> p_220168_) {
return p_220168_.test(this.getItem().builtInRegistryHolder());
}
public boolean is(Holder<Item> p_220166_) {
return this.getItem().builtInRegistryHolder() == p_220166_;
}
public boolean is(HolderSet<Item> p_299078_) {
return p_299078_.contains(this.getItemHolder());
}
public Stream<TagKey<Item>> getTags() {
return this.getItem().builtInRegistryHolder().tags();
}
public InteractionResult useOn(UseOnContext p_41662_) {
Player player = p_41662_.getPlayer();
BlockPos blockpos = p_41662_.getClickedPos();
if (player != null && !player.getAbilities().mayBuild && !this.canPlaceOnBlockInAdventureMode(new BlockInWorld(p_41662_.getLevel(), blockpos, false))) {
return InteractionResult.PASS;
} else {
Item item = this.getItem();
InteractionResult interactionresult = item.useOn(p_41662_);
if (player != null && interactionresult instanceof InteractionResult.Success interactionresult$success && interactionresult$success.wasItemInteraction()) {
player.awardStat(Stats.ITEM_USED.get(item));
}
return interactionresult;
}
}
public float getDestroySpeed(BlockState p_41692_) {
return this.getItem().getDestroySpeed(this, p_41692_);
}
public InteractionResult use(Level p_41683_, Player p_41684_, InteractionHand p_41685_) {
ItemStack itemstack = this.copy();
boolean flag = this.getUseDuration(p_41684_) <= 0;
InteractionResult interactionresult = this.getItem().use(p_41683_, p_41684_, p_41685_);
return (InteractionResult)(flag && interactionresult instanceof InteractionResult.Success interactionresult$success
? interactionresult$success.heldItemTransformedTo(
interactionresult$success.heldItemTransformedTo() == null
? this.applyAfterUseComponentSideEffects(p_41684_, itemstack)
: interactionresult$success.heldItemTransformedTo().applyAfterUseComponentSideEffects(p_41684_, itemstack)
)
: interactionresult);
}
public ItemStack finishUsingItem(Level p_41672_, LivingEntity p_41673_) {
ItemStack itemstack = this.copy();
ItemStack itemstack1 = this.getItem().finishUsingItem(this, p_41672_, p_41673_);
return itemstack1.applyAfterUseComponentSideEffects(p_41673_, itemstack);
}
private ItemStack applyAfterUseComponentSideEffects(LivingEntity p_367870_, ItemStack p_361647_) {
UseRemainder useremainder = p_361647_.get(DataComponents.USE_REMAINDER);
UseCooldown usecooldown = p_361647_.get(DataComponents.USE_COOLDOWN);
int i = p_361647_.getCount();
ItemStack itemstack = this;
if (useremainder != null) {
itemstack = useremainder.convertIntoRemainder(this, i, p_367870_.hasInfiniteMaterials(), p_367870_::handleExtraItemsCreatedOnUse);
}
if (usecooldown != null) {
usecooldown.apply(p_361647_, p_367870_);
}
return itemstack;
}
public Tag save(HolderLookup.Provider p_330500_, Tag p_332574_) {
if (this.isEmpty()) {
throw new IllegalStateException("Cannot encode empty ItemStack");
} else {
return CODEC.encode(this, p_330500_.createSerializationContext(NbtOps.INSTANCE), p_332574_).getOrThrow();
}
}
public Tag save(HolderLookup.Provider p_328490_) {
if (this.isEmpty()) {
throw new IllegalStateException("Cannot encode empty ItemStack");
} else {
return CODEC.encodeStart(p_328490_.createSerializationContext(NbtOps.INSTANCE), this).getOrThrow();
}
}
public int getMaxStackSize() {
return this.getOrDefault(DataComponents.MAX_STACK_SIZE, 1);
}
public boolean isStackable() {
return this.getMaxStackSize() > 1 && (!this.isDamageableItem() || !this.isDamaged());
}
public boolean isDamageableItem() {
return this.has(DataComponents.MAX_DAMAGE) && !this.has(DataComponents.UNBREAKABLE) && this.has(DataComponents.DAMAGE);
}
public boolean isDamaged() {
return this.isDamageableItem() && this.getDamageValue() > 0;
}
public int getDamageValue() {
return Mth.clamp(this.getOrDefault(DataComponents.DAMAGE, 0), 0, this.getMaxDamage());
}
public void setDamageValue(int p_41722_) {
this.set(DataComponents.DAMAGE, Mth.clamp(p_41722_, 0, this.getMaxDamage()));
}
public int getMaxDamage() {
return this.getOrDefault(DataComponents.MAX_DAMAGE, 0);
}
public boolean isBroken() {
return this.isDamageableItem() && this.getDamageValue() >= this.getMaxDamage();
}
public boolean nextDamageWillBreak() {
return this.isDamageableItem() && this.getDamageValue() >= this.getMaxDamage() - 1;
}
public void hurtAndBreak(int p_220158_, ServerLevel p_342197_, @Nullable ServerPlayer p_220160_, Consumer<Item> p_343361_) {
int i = this.processDurabilityChange(p_220158_, p_342197_, p_220160_);
if (i != 0) {
this.applyDamage(this.getDamageValue() + i, p_220160_, p_343361_);
}
}
private int processDurabilityChange(int p_362423_, ServerLevel p_364910_, @Nullable ServerPlayer p_365570_) {
if (!this.isDamageableItem()) {
return 0;
} else if (p_365570_ != null && p_365570_.hasInfiniteMaterials()) {
return 0;
} else {
return p_362423_ > 0 ? EnchantmentHelper.processDurabilityChange(p_364910_, this, p_362423_) : p_362423_;
}
}
private void applyDamage(int p_365629_, @Nullable ServerPlayer p_367167_, Consumer<Item> p_364849_) {
if (p_367167_ != null) {
CriteriaTriggers.ITEM_DURABILITY_CHANGED.trigger(p_367167_, this, p_365629_);
}
this.setDamageValue(p_365629_);
if (this.isBroken()) {
Item item = this.getItem();
this.shrink(1);
p_364849_.accept(item);
}
}
public void hurtWithoutBreaking(int p_363289_, Player p_369700_) {
if (p_369700_ instanceof ServerPlayer serverplayer) {
int i = this.processDurabilityChange(p_363289_, serverplayer.serverLevel(), serverplayer);
if (i == 0) {
return;
}
int j = Math.min(this.getDamageValue() + i, this.getMaxDamage() - 1);
this.applyDamage(j, serverplayer, p_359411_ -> {});
}
}
public void hurtAndBreak(int p_41623_, LivingEntity p_41624_, EquipmentSlot p_335324_) {
if (p_41624_.level() instanceof ServerLevel serverlevel) {
this.hurtAndBreak(
p_41623_,
serverlevel,
p_41624_ instanceof ServerPlayer serverplayer ? serverplayer : null,
p_341563_ -> p_41624_.onEquippedItemBroken(p_341563_, p_335324_)
);
}
}
public ItemStack hurtAndConvertOnBreak(int p_343792_, ItemLike p_344647_, LivingEntity p_342270_, EquipmentSlot p_345347_) {
this.hurtAndBreak(p_343792_, p_342270_, p_345347_);
if (this.isEmpty()) {
ItemStack itemstack = this.transmuteCopyIgnoreEmpty(p_344647_, 1);
if (itemstack.isDamageableItem()) {
itemstack.setDamageValue(0);
}
return itemstack;
} else {
return this;
}
}
public boolean isBarVisible() {
return this.getItem().isBarVisible(this);
}
public int getBarWidth() {
return this.getItem().getBarWidth(this);
}
public int getBarColor() {
return this.getItem().getBarColor(this);
}
public boolean overrideStackedOnOther(Slot p_150927_, ClickAction p_150928_, Player p_150929_) {
return this.getItem().overrideStackedOnOther(this, p_150927_, p_150928_, p_150929_);
}
public boolean overrideOtherStackedOnMe(ItemStack p_150933_, Slot p_150934_, ClickAction p_150935_, Player p_150936_, SlotAccess p_150937_) {
return this.getItem().overrideOtherStackedOnMe(this, p_150933_, p_150934_, p_150935_, p_150936_, p_150937_);
}
public boolean hurtEnemy(LivingEntity p_41641_, LivingEntity p_366644_) {
Item item = this.getItem();
item.hurtEnemy(this, p_41641_, p_366644_);
if (this.has(DataComponents.WEAPON)) {
if (p_366644_ instanceof Player player) {
player.awardStat(Stats.ITEM_USED.get(item));
}
return true;
} else {
return false;
}
}
public void postHurtEnemy(LivingEntity p_343236_, LivingEntity p_363977_) {
this.getItem().postHurtEnemy(this, p_343236_, p_363977_);
Weapon weapon = this.get(DataComponents.WEAPON);
if (weapon != null) {
this.hurtAndBreak(weapon.itemDamagePerAttack(), p_363977_, EquipmentSlot.MAINHAND);
}
}
public void mineBlock(Level p_41687_, BlockState p_41688_, BlockPos p_41689_, Player p_41690_) {
Item item = this.getItem();
if (item.mineBlock(this, p_41687_, p_41688_, p_41689_, p_41690_)) {
p_41690_.awardStat(Stats.ITEM_USED.get(item));
}
}
public boolean isCorrectToolForDrops(BlockState p_41736_) {
return this.getItem().isCorrectToolForDrops(this, p_41736_);
}
public InteractionResult interactLivingEntity(Player p_41648_, LivingEntity p_41649_, InteractionHand p_41650_) {
Equippable equippable = this.get(DataComponents.EQUIPPABLE);
if (equippable != null && equippable.equipOnInteract()) {
InteractionResult interactionresult = equippable.equipOnTarget(p_41648_, p_41649_, this);
if (interactionresult != InteractionResult.PASS) {
return interactionresult;
}
}
return this.getItem().interactLivingEntity(this, p_41648_, p_41649_, p_41650_);
}
public ItemStack copy() {
if (this.isEmpty()) {
return EMPTY;
} else {
ItemStack itemstack = new ItemStack(this.getItem(), this.count, this.components.copy());
itemstack.setPopTime(this.getPopTime());
return itemstack;
}
}
public ItemStack copyWithCount(int p_256354_) {
if (this.isEmpty()) {
return EMPTY;
} else {
ItemStack itemstack = this.copy();
itemstack.setCount(p_256354_);
return itemstack;
}
}
public ItemStack transmuteCopy(ItemLike p_345281_) {
return this.transmuteCopy(p_345281_, this.getCount());
}
public ItemStack transmuteCopy(ItemLike p_334328_, int p_334821_) {
return this.isEmpty() ? EMPTY : this.transmuteCopyIgnoreEmpty(p_334328_, p_334821_);
}
private ItemStack transmuteCopyIgnoreEmpty(ItemLike p_332114_, int p_333334_) {
return new ItemStack(p_332114_.asItem().builtInRegistryHolder(), p_333334_, this.components.asPatch());
}
public static boolean matches(ItemStack p_41729_, ItemStack p_41730_) {
if (p_41729_ == p_41730_) {
return true;
} else {
return p_41729_.getCount() != p_41730_.getCount() ? false : isSameItemSameComponents(p_41729_, p_41730_);
}
}
@Deprecated
public static boolean listMatches(List<ItemStack> p_335471_, List<ItemStack> p_334624_) {
if (p_335471_.size() != p_334624_.size()) {
return false;
} else {
for (int i = 0; i < p_335471_.size(); i++) {
if (!matches(p_335471_.get(i), p_334624_.get(i))) {
return false;
}
}
return true;
}
}
public static boolean isSameItem(ItemStack p_287761_, ItemStack p_287676_) {
return p_287761_.is(p_287676_.getItem());
}
public static boolean isSameItemSameComponents(ItemStack p_334397_, ItemStack p_331609_) {
if (!p_334397_.is(p_331609_.getItem())) {
return false;
} else {
return p_334397_.isEmpty() && p_331609_.isEmpty() ? true : Objects.equals(p_334397_.components, p_331609_.components);
}
}
public static MapCodec<ItemStack> lenientOptionalFieldOf(String p_336149_) {
return CODEC.lenientOptionalFieldOf(p_336149_)
.xmap(p_327174_ -> p_327174_.orElse(EMPTY), p_327162_ -> p_327162_.isEmpty() ? Optional.empty() : Optional.of(p_327162_));
}
public static int hashItemAndComponents(@Nullable ItemStack p_334004_) {
if (p_334004_ != null) {
int i = 31 + p_334004_.getItem().hashCode();
return 31 * i + p_334004_.getComponents().hashCode();
} else {
return 0;
}
}
@Deprecated
public static int hashStackList(List<ItemStack> p_333449_) {
int i = 0;
for (ItemStack itemstack : p_333449_) {
i = i * 31 + hashItemAndComponents(itemstack);
}
return i;
}
@Override
public String toString() {
return this.getCount() + " " + this.getItem();
}
public void inventoryTick(Level p_41667_, Entity p_41668_, @Nullable EquipmentSlot p_391620_) {
if (this.popTime > 0) {
this.popTime--;
}
if (p_41667_ instanceof ServerLevel serverlevel) {
this.getItem().inventoryTick(this, serverlevel, p_41668_, p_391620_);
}
}
public void onCraftedBy(Player p_41680_, int p_41681_) {
p_41680_.awardStat(Stats.ITEM_CRAFTED.get(this.getItem()), p_41681_);
this.getItem().onCraftedBy(this, p_41680_);
}
public void onCraftedBySystem(Level p_311164_) {
this.getItem().onCraftedPostProcess(this, p_311164_);
}
public int getUseDuration(LivingEntity p_343439_) {
return this.getItem().getUseDuration(this, p_343439_);
}
public ItemUseAnimation getUseAnimation() {
return this.getItem().getUseAnimation(this);
}
public void releaseUsing(Level p_41675_, LivingEntity p_41676_, int p_41677_) {
ItemStack itemstack = this.copy();
if (this.getItem().releaseUsing(this, p_41675_, p_41676_, p_41677_)) {
ItemStack itemstack1 = this.applyAfterUseComponentSideEffects(p_41676_, itemstack);
if (itemstack1 != this) {
p_41676_.setItemInHand(p_41676_.getUsedItemHand(), itemstack1);
}
}
}
public boolean useOnRelease() {
return this.getItem().useOnRelease(this);
}
@Nullable
public <T> T set(DataComponentType<T> p_332666_, @Nullable T p_335655_) {
return this.components.set(p_332666_, p_335655_);
}
public <T> void copyFrom(DataComponentType<T> p_391623_, DataComponentGetter p_394516_) {
this.set(p_391623_, p_394516_.get(p_391623_));
}
@Nullable
public <T, U> T update(DataComponentType<T> p_331418_, T p_327708_, U p_332086_, BiFunction<T, U, T> p_329834_) {
return this.set(p_331418_, p_329834_.apply(this.getOrDefault(p_331418_, p_327708_), p_332086_));
}
@Nullable
public <T> T update(DataComponentType<T> p_329905_, T p_329705_, UnaryOperator<T> p_335114_) {
T t = this.getOrDefault(p_329905_, p_329705_);
return this.set(p_329905_, p_335114_.apply(t));
}
@Nullable
public <T> T remove(DataComponentType<? extends T> p_333259_) {
return this.components.remove(p_333259_);
}
public void applyComponentsAndValidate(DataComponentPatch p_336111_) {
DataComponentPatch datacomponentpatch = this.components.asPatch();
this.components.applyPatch(p_336111_);
Optional<Error<ItemStack>> optional = validateStrict(this).error();
if (optional.isPresent()) {
LOGGER.error("Failed to apply component patch '{}' to item: '{}'", p_336111_, optional.get().message());
this.components.restorePatch(datacomponentpatch);
} else {
this.getItem().verifyComponentsAfterLoad(this);
}
}
public void applyComponents(DataComponentPatch p_328534_) {
this.components.applyPatch(p_328534_);
this.getItem().verifyComponentsAfterLoad(this);
}
public void applyComponents(DataComponentMap p_335208_) {
this.components.setAll(p_335208_);
this.getItem().verifyComponentsAfterLoad(this);
}
public Component getHoverName() {
Component component = this.getCustomName();
return component != null ? component : this.getItemName();
}
@Nullable
public Component getCustomName() {
Component component = this.get(DataComponents.CUSTOM_NAME);
if (component != null) {
return component;
} else {
WrittenBookContent writtenbookcontent = this.get(DataComponents.WRITTEN_BOOK_CONTENT);
if (writtenbookcontent != null) {
String s = writtenbookcontent.title().raw();
if (!StringUtil.isBlank(s)) {
return Component.literal(s);
}
}
return null;
}
}
public Component getItemName() {
return this.getItem().getName(this);
}
public Component getStyledHoverName() {
MutableComponent mutablecomponent = Component.empty().append(this.getHoverName()).withStyle(this.getRarity().color());
if (this.has(DataComponents.CUSTOM_NAME)) {
mutablecomponent.withStyle(ChatFormatting.ITALIC);
}
return mutablecomponent;
}
public <T extends TooltipProvider> void addToTooltip(
DataComponentType<T> p_331934_, Item.TooltipContext p_333562_, TooltipDisplay p_397538_, Consumer<Component> p_334534_, TooltipFlag p_333715_
) {
T t = (T)this.get(p_331934_);
if (t != null && p_397538_.shows(p_331934_)) {
t.addToTooltip(p_333562_, p_334534_, p_333715_, this.components);
}
}
public List<Component> getTooltipLines(Item.TooltipContext p_331329_, @Nullable Player p_41652_, TooltipFlag p_41653_) {
TooltipDisplay tooltipdisplay = this.getOrDefault(DataComponents.TOOLTIP_DISPLAY, TooltipDisplay.DEFAULT);
if (!p_41653_.isCreative() && tooltipdisplay.hideTooltip()) {
boolean flag = this.getItem().shouldPrintOpWarning(this, p_41652_);
return flag ? OP_NBT_WARNING : List.of();
} else {
List<Component> list = Lists.newArrayList();
list.add(this.getStyledHoverName());
this.addDetailsToTooltip(p_331329_, tooltipdisplay, p_41652_, p_41653_, list::add);
return list;
}
}
public void addDetailsToTooltip(
Item.TooltipContext p_396953_, TooltipDisplay p_394554_, @Nullable Player p_393346_, TooltipFlag p_392044_, Consumer<Component> p_396200_
) {
this.getItem().appendHoverText(this, p_396953_, p_394554_, p_396200_, p_392044_);
this.addToTooltip(DataComponents.TROPICAL_FISH_PATTERN, p_396953_, p_394554_, p_396200_, p_392044_);
this.addToTooltip(DataComponents.INSTRUMENT, p_396953_, p_394554_, p_396200_, p_392044_);
this.addToTooltip(DataComponents.MAP_ID, p_396953_, p_394554_, p_396200_, p_392044_);
this.addToTooltip(DataComponents.BEES, p_396953_, p_394554_, p_396200_, p_392044_);
this.addToTooltip(DataComponents.CONTAINER_LOOT, p_396953_, p_394554_, p_396200_, p_392044_);
this.addToTooltip(DataComponents.CONTAINER, p_396953_, p_394554_, p_396200_, p_392044_);
this.addToTooltip(DataComponents.BANNER_PATTERNS, p_396953_, p_394554_, p_396200_, p_392044_);
this.addToTooltip(DataComponents.POT_DECORATIONS, p_396953_, p_394554_, p_396200_, p_392044_);
this.addToTooltip(DataComponents.WRITTEN_BOOK_CONTENT, p_396953_, p_394554_, p_396200_, p_392044_);
this.addToTooltip(DataComponents.CHARGED_PROJECTILES, p_396953_, p_394554_, p_396200_, p_392044_);
this.addToTooltip(DataComponents.FIREWORKS, p_396953_, p_394554_, p_396200_, p_392044_);
this.addToTooltip(DataComponents.FIREWORK_EXPLOSION, p_396953_, p_394554_, p_396200_, p_392044_);
this.addToTooltip(DataComponents.POTION_CONTENTS, p_396953_, p_394554_, p_396200_, p_392044_);
this.addToTooltip(DataComponents.JUKEBOX_PLAYABLE, p_396953_, p_394554_, p_396200_, p_392044_);
this.addToTooltip(DataComponents.TRIM, p_396953_, p_394554_, p_396200_, p_392044_);
this.addToTooltip(DataComponents.STORED_ENCHANTMENTS, p_396953_, p_394554_, p_396200_, p_392044_);
this.addToTooltip(DataComponents.ENCHANTMENTS, p_396953_, p_394554_, p_396200_, p_392044_);
this.addToTooltip(DataComponents.DYED_COLOR, p_396953_, p_394554_, p_396200_, p_392044_);
this.addToTooltip(DataComponents.LORE, p_396953_, p_394554_, p_396200_, p_392044_);
this.addAttributeTooltips(p_396200_, p_394554_, p_393346_);
if (this.has(DataComponents.UNBREAKABLE) && p_394554_.shows(DataComponents.UNBREAKABLE)) {
p_396200_.accept(UNBREAKABLE_TOOLTIP);
}
this.addToTooltip(DataComponents.OMINOUS_BOTTLE_AMPLIFIER, p_396953_, p_394554_, p_396200_, p_392044_);
this.addToTooltip(DataComponents.SUSPICIOUS_STEW_EFFECTS, p_396953_, p_394554_, p_396200_, p_392044_);
this.addToTooltip(DataComponents.BLOCK_STATE, p_396953_, p_394554_, p_396200_, p_392044_);
if ((this.is(Items.SPAWNER) || this.is(Items.TRIAL_SPAWNER)) && p_394554_.shows(DataComponents.BLOCK_ENTITY_DATA)) {
CustomData customdata = this.getOrDefault(DataComponents.BLOCK_ENTITY_DATA, CustomData.EMPTY);
Spawner.appendHoverText(customdata, p_396200_, "SpawnData");
}
AdventureModePredicate adventuremodepredicate1 = this.get(DataComponents.CAN_BREAK);
if (adventuremodepredicate1 != null && p_394554_.shows(DataComponents.CAN_BREAK)) {
p_396200_.accept(CommonComponents.EMPTY);
p_396200_.accept(AdventureModePredicate.CAN_BREAK_HEADER);
adventuremodepredicate1.addToTooltip(p_396200_);
}
AdventureModePredicate adventuremodepredicate = this.get(DataComponents.CAN_PLACE_ON);
if (adventuremodepredicate != null && p_394554_.shows(DataComponents.CAN_PLACE_ON)) {
p_396200_.accept(CommonComponents.EMPTY);
p_396200_.accept(AdventureModePredicate.CAN_PLACE_HEADER);
adventuremodepredicate.addToTooltip(p_396200_);
}
if (p_392044_.isAdvanced()) {
if (this.isDamaged() && p_394554_.shows(DataComponents.DAMAGE)) {
p_396200_.accept(Component.translatable("item.durability", this.getMaxDamage() - this.getDamageValue(), this.getMaxDamage()));
}
p_396200_.accept(Component.literal(BuiltInRegistries.ITEM.getKey(this.getItem()).toString()).withStyle(ChatFormatting.DARK_GRAY));
int i = this.components.size();
if (i > 0) {
p_396200_.accept(Component.translatable("item.components", i).withStyle(ChatFormatting.DARK_GRAY));
}
}
if (p_393346_ != null && !this.getItem().isEnabled(p_393346_.level().enabledFeatures())) {
p_396200_.accept(DISABLED_ITEM_TOOLTIP);
}
boolean flag = this.getItem().shouldPrintOpWarning(this, p_393346_);
if (flag) {
OP_NBT_WARNING.forEach(p_396200_);
}
}
private void addAttributeTooltips(Consumer<Component> p_333346_, TooltipDisplay p_391795_, @Nullable Player p_332769_) {
if (p_391795_.shows(DataComponents.ATTRIBUTE_MODIFIERS)) {
for (EquipmentSlotGroup equipmentslotgroup : EquipmentSlotGroup.values()) {
MutableBoolean mutableboolean = new MutableBoolean(true);
this.forEachModifier(equipmentslotgroup, (p_341553_, p_341554_) -> {
if (mutableboolean.isTrue()) {
p_333346_.accept(CommonComponents.EMPTY);
p_333346_.accept(Component.translatable("item.modifiers." + equipmentslotgroup.getSerializedName()).withStyle(ChatFormatting.GRAY));
mutableboolean.setFalse();
}
this.addModifierTooltip(p_333346_, p_332769_, p_341553_, p_341554_);
});
}
}
}
private void addModifierTooltip(Consumer<Component> p_332944_, @Nullable Player p_328442_, Holder<Attribute> p_336373_, AttributeModifier p_332746_) {
double d0 = p_332746_.amount();
boolean flag = false;
if (p_328442_ != null) {
if (p_332746_.is(Item.BASE_ATTACK_DAMAGE_ID)) {
d0 += p_328442_.getAttributeBaseValue(Attributes.ATTACK_DAMAGE);
flag = true;
} else if (p_332746_.is(Item.BASE_ATTACK_SPEED_ID)) {
d0 += p_328442_.getAttributeBaseValue(Attributes.ATTACK_SPEED);
flag = true;
}
}
double d1;
if (p_332746_.operation() == AttributeModifier.Operation.ADD_MULTIPLIED_BASE || p_332746_.operation() == AttributeModifier.Operation.ADD_MULTIPLIED_TOTAL
)
{
d1 = d0 * 100.0;
} else if (p_336373_.is(Attributes.KNOCKBACK_RESISTANCE)) {
d1 = d0 * 10.0;
} else {
d1 = d0;
}
if (flag) {
p_332944_.accept(
CommonComponents.space()
.append(
Component.translatable(
"attribute.modifier.equals." + p_332746_.operation().id(),
ItemAttributeModifiers.ATTRIBUTE_MODIFIER_FORMAT.format(d1),
Component.translatable(p_336373_.value().getDescriptionId())
)
)
.withStyle(ChatFormatting.DARK_GREEN)
);
} else if (d0 > 0.0) {
p_332944_.accept(
Component.translatable(
"attribute.modifier.plus." + p_332746_.operation().id(),
ItemAttributeModifiers.ATTRIBUTE_MODIFIER_FORMAT.format(d1),
Component.translatable(p_336373_.value().getDescriptionId())
)
.withStyle(p_336373_.value().getStyle(true))
);
} else if (d0 < 0.0) {
p_332944_.accept(
Component.translatable(
"attribute.modifier.take." + p_332746_.operation().id(),
ItemAttributeModifiers.ATTRIBUTE_MODIFIER_FORMAT.format(-d1),
Component.translatable(p_336373_.value().getDescriptionId())
)
.withStyle(p_336373_.value().getStyle(false))
);
}
}
public boolean hasFoil() {
Boolean obool = this.get(DataComponents.ENCHANTMENT_GLINT_OVERRIDE);
return obool != null ? obool : this.getItem().isFoil(this);
}
public Rarity getRarity() {
Rarity rarity = this.getOrDefault(DataComponents.RARITY, Rarity.COMMON);
if (!this.isEnchanted()) {
return rarity;
} else {
return switch (rarity) {
case COMMON, UNCOMMON -> Rarity.RARE;
case RARE -> Rarity.EPIC;
default -> rarity;
};
}
}
public boolean isEnchantable() {
if (!this.has(DataComponents.ENCHANTABLE)) {
return false;
} else {
ItemEnchantments itemenchantments = this.get(DataComponents.ENCHANTMENTS);
return itemenchantments != null && itemenchantments.isEmpty();
}
}
public void enchant(Holder<Enchantment> p_342791_, int p_41665_) {
EnchantmentHelper.updateEnchantments(this, p_341557_ -> p_341557_.upgrade(p_342791_, p_41665_));
}
public boolean isEnchanted() {
return !this.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY).isEmpty();
}
public ItemEnchantments getEnchantments() {
return this.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY);
}
public boolean isFramed() {
return this.entityRepresentation instanceof ItemFrame;
}
public void setEntityRepresentation(@Nullable Entity p_41637_) {
if (!this.isEmpty()) {
this.entityRepresentation = p_41637_;
}
}
@Nullable
public ItemFrame getFrame() {
return this.entityRepresentation instanceof ItemFrame ? (ItemFrame)this.getEntityRepresentation() : null;
}
@Nullable
public Entity getEntityRepresentation() {
return !this.isEmpty() ? this.entityRepresentation : null;
}
public void forEachModifier(EquipmentSlotGroup p_344758_, BiConsumer<Holder<Attribute>, AttributeModifier> p_342345_) {
ItemAttributeModifiers itemattributemodifiers = this.getOrDefault(DataComponents.ATTRIBUTE_MODIFIERS, ItemAttributeModifiers.EMPTY);
itemattributemodifiers.forEach(p_344758_, p_342345_);
EnchantmentHelper.forEachModifier(this, p_344758_, p_342345_);
}
public void forEachModifier(EquipmentSlot p_331036_, BiConsumer<Holder<Attribute>, AttributeModifier> p_334430_) {
ItemAttributeModifiers itemattributemodifiers = this.getOrDefault(DataComponents.ATTRIBUTE_MODIFIERS, ItemAttributeModifiers.EMPTY);
itemattributemodifiers.forEach(p_331036_, p_334430_);
EnchantmentHelper.forEachModifier(this, p_331036_, p_334430_);
}
public Component getDisplayName() {
MutableComponent mutablecomponent = Component.empty().append(this.getHoverName());
if (this.has(DataComponents.CUSTOM_NAME)) {
mutablecomponent.withStyle(ChatFormatting.ITALIC);
}
MutableComponent mutablecomponent1 = ComponentUtils.wrapInSquareBrackets(mutablecomponent);
if (!this.isEmpty()) {
mutablecomponent1.withStyle(this.getRarity().color()).withStyle(p_390810_ -> p_390810_.withHoverEvent(new HoverEvent.ShowItem(this)));
}
return mutablecomponent1;
}
public boolean canPlaceOnBlockInAdventureMode(BlockInWorld p_331134_) {
AdventureModePredicate adventuremodepredicate = this.get(DataComponents.CAN_PLACE_ON);
return adventuremodepredicate != null && adventuremodepredicate.test(p_331134_);
}
public boolean canBreakBlockInAdventureMode(BlockInWorld p_333133_) {
AdventureModePredicate adventuremodepredicate = this.get(DataComponents.CAN_BREAK);
return adventuremodepredicate != null && adventuremodepredicate.test(p_333133_);
}
public int getPopTime() {
return this.popTime;
}
public void setPopTime(int p_41755_) {
this.popTime = p_41755_;
}
public int getCount() {
return this.isEmpty() ? 0 : this.count;
}
public void setCount(int p_41765_) {
this.count = p_41765_;
}
public void limitSize(int p_328100_) {
if (!this.isEmpty() && this.getCount() > p_328100_) {
this.setCount(p_328100_);
}
}
public void grow(int p_41770_) {
this.setCount(this.getCount() + p_41770_);
}
public void shrink(int p_41775_) {
this.grow(-p_41775_);
}
public void consume(int p_329683_, @Nullable LivingEntity p_334302_) {
if (p_334302_ == null || !p_334302_.hasInfiniteMaterials()) {
this.shrink(p_329683_);
}
}
public ItemStack consumeAndReturn(int p_343693_, @Nullable LivingEntity p_344112_) {
ItemStack itemstack = this.copyWithCount(p_343693_);
this.consume(p_343693_, p_344112_);
return itemstack;
}
public void onUseTick(Level p_41732_, LivingEntity p_41733_, int p_41734_) {
Consumable consumable = this.get(DataComponents.CONSUMABLE);
if (consumable != null && consumable.shouldEmitParticlesAndSounds(p_41734_)) {
consumable.emitParticlesAndSounds(p_41733_.getRandom(), p_41733_, this, 5);
}
this.getItem().onUseTick(p_41732_, p_41733_, this, p_41734_);
}
public void onDestroyed(ItemEntity p_150925_) {
this.getItem().onDestroyed(p_150925_);
}
public boolean canBeHurtBy(DamageSource p_334859_) {
DamageResistant damageresistant = this.get(DataComponents.DAMAGE_RESISTANT);
return damageresistant == null || !damageresistant.isResistantTo(p_334859_);
}
public boolean isValidRepairItem(ItemStack p_368140_) {
Repairable repairable = this.get(DataComponents.REPAIRABLE);
return repairable != null && repairable.isValidRepairItem(p_368140_);
}
public boolean canDestroyBlock(BlockState p_394125_, Level p_391865_, BlockPos p_396538_, Player p_395561_) {
return this.getItem().canDestroyBlock(this, p_394125_, p_391865_, p_396538_, p_395561_);
}
}