package net.minecraft.world.level.block.entity; import com.mojang.logging.LogUtils; import net.minecraft.core.BlockPos; import net.minecraft.core.HolderLookup; import net.minecraft.core.component.DataComponents; import net.minecraft.core.component.DataComponentMap.Builder; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.NbtOps; import net.minecraft.network.chat.Component; import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; import net.minecraft.world.Nameable; import net.minecraft.world.item.DyeColor; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.block.AbstractBannerBlock; import net.minecraft.world.level.block.BannerBlock; import net.minecraft.world.level.block.state.BlockState; import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; public class BannerBlockEntity extends BlockEntity implements Nameable { private static final Logger LOGGER = LogUtils.getLogger(); public static final int MAX_PATTERNS = 6; private static final String TAG_PATTERNS = "patterns"; @Nullable private Component name; private DyeColor baseColor; /** * A list of all patterns stored on this banner. */ private BannerPatternLayers patterns = BannerPatternLayers.EMPTY; public BannerBlockEntity(BlockPos pos, BlockState blockState) { super(BlockEntityType.BANNER, pos, blockState); this.baseColor = ((AbstractBannerBlock)blockState.getBlock()).getColor(); } public BannerBlockEntity(BlockPos pos, BlockState blockState, DyeColor baseColor) { this(pos, blockState); this.baseColor = baseColor; } public void fromItem(ItemStack stack, DyeColor color) { this.baseColor = color; this.applyComponentsFromItemStack(stack); } @Override public Component getName() { return (Component)(this.name != null ? this.name : Component.translatable("block.minecraft.banner")); } @Nullable @Override public Component getCustomName() { return this.name; } @Override protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) { super.saveAdditional(tag, registries); if (!this.patterns.equals(BannerPatternLayers.EMPTY)) { tag.put("patterns", BannerPatternLayers.CODEC.encodeStart(registries.createSerializationContext(NbtOps.INSTANCE), this.patterns).getOrThrow()); } if (this.name != null) { tag.putString("CustomName", Component.Serializer.toJson(this.name, registries)); } } @Override protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) { super.loadAdditional(tag, registries); if (tag.contains("CustomName", 8)) { this.name = parseCustomNameSafe(tag.getString("CustomName"), registries); } if (tag.contains("patterns")) { BannerPatternLayers.CODEC .parse(registries.createSerializationContext(NbtOps.INSTANCE), tag.get("patterns")) .resultOrPartial(string -> LOGGER.error("Failed to parse banner patterns: '{}'", string)) .ifPresent(bannerPatternLayers -> this.patterns = bannerPatternLayers); } } public ClientboundBlockEntityDataPacket getUpdatePacket() { return ClientboundBlockEntityDataPacket.create(this); } @Override public CompoundTag getUpdateTag(HolderLookup.Provider registries) { return this.saveWithoutMetadata(registries); } public BannerPatternLayers getPatterns() { return this.patterns; } public ItemStack getItem() { ItemStack itemStack = new ItemStack(BannerBlock.byColor(this.baseColor)); itemStack.applyComponents(this.collectComponents()); return itemStack; } public DyeColor getBaseColor() { return this.baseColor; } @Override protected void applyImplicitComponents(BlockEntity.DataComponentInput componentInput) { super.applyImplicitComponents(componentInput); this.patterns = componentInput.getOrDefault(DataComponents.BANNER_PATTERNS, BannerPatternLayers.EMPTY); this.name = componentInput.get(DataComponents.CUSTOM_NAME); } @Override protected void collectImplicitComponents(Builder components) { super.collectImplicitComponents(components); components.set(DataComponents.BANNER_PATTERNS, this.patterns); components.set(DataComponents.CUSTOM_NAME, this.name); } @Override public void removeComponentsFromTag(CompoundTag tag) { tag.remove("patterns"); tag.remove("CustomName"); } }