/* * Decompiled with CFR 0.152. * * Could not load the following classes: * com.mojang.datafixers.kinds.App * com.mojang.datafixers.kinds.Applicative * com.mojang.serialization.Codec * com.mojang.serialization.codecs.RecordCodecBuilder */ package net.minecraft.world.item.equipment; import com.mojang.datafixers.kinds.App; import com.mojang.datafixers.kinds.Applicative; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; import java.util.Optional; import net.minecraft.core.Holder; import net.minecraft.core.HolderGetter; import net.minecraft.core.HolderSet; import net.minecraft.core.RegistryCodecs; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.Registries; import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; import net.minecraft.resources.Identifier; import net.minecraft.resources.ResourceKey; import net.minecraft.sounds.SoundEvent; import net.minecraft.sounds.SoundEvents; import net.minecraft.stats.Stats; import net.minecraft.tags.EntityTypeTags; import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.DyeColor; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.enchantment.EnchantmentEffectComponents; import net.minecraft.world.item.enchantment.EnchantmentHelper; import net.minecraft.world.item.equipment.EquipmentAsset; import net.minecraft.world.item.equipment.EquipmentAssets; public record Equippable(EquipmentSlot slot, Holder equipSound, Optional> assetId, Optional cameraOverlay, Optional>> allowedEntities, boolean dispensable, boolean swappable, boolean damageOnHurt, boolean equipOnInteract, boolean canBeSheared, Holder shearingSound) { public static final Codec CODEC = RecordCodecBuilder.create(i -> i.group((App)EquipmentSlot.CODEC.fieldOf("slot").forGetter(Equippable::slot), (App)SoundEvent.CODEC.optionalFieldOf("equip_sound", SoundEvents.ARMOR_EQUIP_GENERIC).forGetter(Equippable::equipSound), (App)ResourceKey.codec(EquipmentAssets.ROOT_ID).optionalFieldOf("asset_id").forGetter(Equippable::assetId), (App)Identifier.CODEC.optionalFieldOf("camera_overlay").forGetter(Equippable::cameraOverlay), (App)RegistryCodecs.homogeneousList(Registries.ENTITY_TYPE).optionalFieldOf("allowed_entities").forGetter(Equippable::allowedEntities), (App)Codec.BOOL.optionalFieldOf("dispensable", (Object)true).forGetter(Equippable::dispensable), (App)Codec.BOOL.optionalFieldOf("swappable", (Object)true).forGetter(Equippable::swappable), (App)Codec.BOOL.optionalFieldOf("damage_on_hurt", (Object)true).forGetter(Equippable::damageOnHurt), (App)Codec.BOOL.optionalFieldOf("equip_on_interact", (Object)false).forGetter(Equippable::equipOnInteract), (App)Codec.BOOL.optionalFieldOf("can_be_sheared", (Object)false).forGetter(Equippable::canBeSheared), (App)SoundEvent.CODEC.optionalFieldOf("shearing_sound", BuiltInRegistries.SOUND_EVENT.wrapAsHolder(SoundEvents.SHEARS_SNIP)).forGetter(Equippable::shearingSound)).apply((Applicative)i, Equippable::new)); public static final StreamCodec STREAM_CODEC = StreamCodec.composite(EquipmentSlot.STREAM_CODEC, Equippable::slot, SoundEvent.STREAM_CODEC, Equippable::equipSound, ResourceKey.streamCodec(EquipmentAssets.ROOT_ID).apply(ByteBufCodecs::optional), Equippable::assetId, Identifier.STREAM_CODEC.apply(ByteBufCodecs::optional), Equippable::cameraOverlay, ByteBufCodecs.holderSet(Registries.ENTITY_TYPE).apply(ByteBufCodecs::optional), Equippable::allowedEntities, ByteBufCodecs.BOOL, Equippable::dispensable, ByteBufCodecs.BOOL, Equippable::swappable, ByteBufCodecs.BOOL, Equippable::damageOnHurt, ByteBufCodecs.BOOL, Equippable::equipOnInteract, ByteBufCodecs.BOOL, Equippable::canBeSheared, SoundEvent.STREAM_CODEC, Equippable::shearingSound, Equippable::new); public static Equippable llamaSwag(DyeColor color) { return Equippable.builder(EquipmentSlot.BODY).setEquipSound(SoundEvents.LLAMA_SWAG).setAsset(EquipmentAssets.CARPETS.get(color)).setAllowedEntities(EntityType.LLAMA, EntityType.TRADER_LLAMA).setCanBeSheared(true).setShearingSound(SoundEvents.LLAMA_CARPET_UNEQUIP).build(); } public static Equippable saddle() { HolderGetter> entityGetter = BuiltInRegistries.acquireBootstrapRegistrationLookup(BuiltInRegistries.ENTITY_TYPE); return Equippable.builder(EquipmentSlot.SADDLE).setEquipSound(SoundEvents.HORSE_SADDLE).setAsset(EquipmentAssets.SADDLE).setAllowedEntities(entityGetter.getOrThrow(EntityTypeTags.CAN_EQUIP_SADDLE)).setEquipOnInteract(true).setCanBeSheared(true).setShearingSound(SoundEvents.SADDLE_UNEQUIP).build(); } public static Equippable harness(DyeColor color) { HolderGetter> entityGetter = BuiltInRegistries.acquireBootstrapRegistrationLookup(BuiltInRegistries.ENTITY_TYPE); return Equippable.builder(EquipmentSlot.BODY).setEquipSound(SoundEvents.HARNESS_EQUIP).setAsset(EquipmentAssets.HARNESSES.get(color)).setAllowedEntities(entityGetter.getOrThrow(EntityTypeTags.CAN_EQUIP_HARNESS)).setEquipOnInteract(true).setCanBeSheared(true).setShearingSound(BuiltInRegistries.SOUND_EVENT.wrapAsHolder(SoundEvents.HARNESS_UNEQUIP)).build(); } public static Builder builder(EquipmentSlot slot) { return new Builder(slot); } public InteractionResult swapWithEquipmentSlot(ItemStack inHand, Player player) { if (!player.canUseSlot(this.slot) || !this.canBeEquippedBy(player.getType())) { return InteractionResult.PASS; } ItemStack inEquipmentSlot = player.getItemBySlot(this.slot); if (EnchantmentHelper.has(inEquipmentSlot, EnchantmentEffectComponents.PREVENT_ARMOR_CHANGE) && !player.isCreative() || ItemStack.isSameItemSameComponents(inHand, inEquipmentSlot)) { return InteractionResult.FAIL; } if (!player.level().isClientSide()) { player.awardStat(Stats.ITEM_USED.get(inHand.getItem())); } if (inHand.getCount() <= 1) { ItemStack swappedToHand = inEquipmentSlot.isEmpty() ? inHand : inEquipmentSlot.copyAndClear(); ItemStack swappedToEquipment = player.isCreative() ? inHand.copy() : inHand.copyAndClear(); player.setItemSlot(this.slot, swappedToEquipment); return InteractionResult.SUCCESS.heldItemTransformedTo(swappedToHand); } ItemStack swappedToInventory = inEquipmentSlot.copyAndClear(); ItemStack swappedToEquipment = inHand.consumeAndReturn(1, player); player.setItemSlot(this.slot, swappedToEquipment); if (!player.getInventory().add(swappedToInventory)) { player.drop(swappedToInventory, false); } return InteractionResult.SUCCESS.heldItemTransformedTo(inHand); } public InteractionResult equipOnTarget(Player player, LivingEntity target, ItemStack itemStack) { if (!target.isEquippableInSlot(itemStack, this.slot) || target.hasItemInSlot(this.slot) || !target.isAlive()) { return InteractionResult.PASS; } if (!player.level().isClientSide()) { target.setItemSlot(this.slot, itemStack.split(1)); if (target instanceof Mob) { Mob mob = (Mob)target; mob.setGuaranteedDrop(this.slot); } } return InteractionResult.SUCCESS; } public boolean canBeEquippedBy(EntityType type) { return this.allowedEntities.isEmpty() || this.allowedEntities.get().contains(type.builtInRegistryHolder()); } public static class Builder { private final EquipmentSlot slot; private Holder equipSound = SoundEvents.ARMOR_EQUIP_GENERIC; private Optional> assetId = Optional.empty(); private Optional cameraOverlay = Optional.empty(); private Optional>> allowedEntities = Optional.empty(); private boolean dispensable = true; private boolean swappable = true; private boolean damageOnHurt = true; private boolean equipOnInteract; private boolean canBeSheared; private Holder shearingSound = BuiltInRegistries.SOUND_EVENT.wrapAsHolder(SoundEvents.SHEARS_SNIP); private Builder(EquipmentSlot slot) { this.slot = slot; } public Builder setEquipSound(Holder equipSound) { this.equipSound = equipSound; return this; } public Builder setAsset(ResourceKey assetId) { this.assetId = Optional.of(assetId); return this; } public Builder setCameraOverlay(Identifier cameraOverlay) { this.cameraOverlay = Optional.of(cameraOverlay); return this; } public Builder setAllowedEntities(EntityType ... allowedEntities) { return this.setAllowedEntities(HolderSet.direct(EntityType::builtInRegistryHolder, allowedEntities)); } public Builder setAllowedEntities(HolderSet> allowedEntities) { this.allowedEntities = Optional.of(allowedEntities); return this; } public Builder setDispensable(boolean dispensable) { this.dispensable = dispensable; return this; } public Builder setSwappable(boolean swappable) { this.swappable = swappable; return this; } public Builder setDamageOnHurt(boolean damageOnHurt) { this.damageOnHurt = damageOnHurt; return this; } public Builder setEquipOnInteract(boolean equipOnInteract) { this.equipOnInteract = equipOnInteract; return this; } public Builder setCanBeSheared(boolean canBeSheared) { this.canBeSheared = canBeSheared; return this; } public Builder setShearingSound(Holder shearingSound) { this.shearingSound = shearingSound; return this; } public Equippable build() { return new Equippable(this.slot, this.equipSound, this.assetId, this.cameraOverlay, this.allowedEntities, this.dispensable, this.swappable, this.damageOnHurt, this.equipOnInteract, this.canBeSheared, this.shearingSound); } } }