minecraft-src/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java
2025-07-04 02:00:41 +03:00

169 lines
5 KiB
Java

package net.minecraft.world.level.block.entity;
import net.minecraft.core.BlockPos;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.NonNullList;
import net.minecraft.core.component.DataComponents;
import net.minecraft.core.component.DataComponentMap.Builder;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.Container;
import net.minecraft.world.ContainerHelper;
import net.minecraft.world.LockCode;
import net.minecraft.world.MenuProvider;
import net.minecraft.world.Nameable;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.component.ItemContainerContents;
import net.minecraft.world.level.block.state.BlockState;
import org.jetbrains.annotations.Nullable;
public abstract class BaseContainerBlockEntity extends BlockEntity implements Container, MenuProvider, Nameable {
private LockCode lockKey = LockCode.NO_LOCK;
@Nullable
private Component name;
protected BaseContainerBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState blockState) {
super(type, pos, blockState);
}
@Override
protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) {
super.loadAdditional(tag, registries);
this.lockKey = LockCode.fromTag(tag, registries);
if (tag.contains("CustomName", 8)) {
this.name = parseCustomNameSafe(tag.getString("CustomName"), registries);
}
}
@Override
protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) {
super.saveAdditional(tag, registries);
this.lockKey.addToTag(tag, registries);
if (this.name != null) {
tag.putString("CustomName", Component.Serializer.toJson(this.name, registries));
}
}
@Override
public Component getName() {
return this.name != null ? this.name : this.getDefaultName();
}
@Override
public Component getDisplayName() {
return this.getName();
}
@Nullable
@Override
public Component getCustomName() {
return this.name;
}
protected abstract Component getDefaultName();
public boolean canOpen(Player player) {
return canUnlock(player, this.lockKey, this.getDisplayName());
}
public static boolean canUnlock(Player player, LockCode code, Component displayName) {
if (!player.isSpectator() && !code.unlocksWith(player.getMainHandItem())) {
player.displayClientMessage(Component.translatable("container.isLocked", displayName), true);
player.playNotifySound(SoundEvents.CHEST_LOCKED, SoundSource.BLOCKS, 1.0F, 1.0F);
return false;
} else {
return true;
}
}
protected abstract NonNullList<ItemStack> getItems();
protected abstract void setItems(NonNullList<ItemStack> items);
@Override
public boolean isEmpty() {
for (ItemStack itemStack : this.getItems()) {
if (!itemStack.isEmpty()) {
return false;
}
}
return true;
}
@Override
public ItemStack getItem(int slot) {
return this.getItems().get(slot);
}
@Override
public ItemStack removeItem(int slot, int amount) {
ItemStack itemStack = ContainerHelper.removeItem(this.getItems(), slot, amount);
if (!itemStack.isEmpty()) {
this.setChanged();
}
return itemStack;
}
@Override
public ItemStack removeItemNoUpdate(int slot) {
return ContainerHelper.takeItem(this.getItems(), slot);
}
@Override
public void setItem(int slot, ItemStack stack) {
this.getItems().set(slot, stack);
stack.limitSize(this.getMaxStackSize(stack));
this.setChanged();
}
@Override
public boolean stillValid(Player player) {
return Container.stillValidBlockEntity(this, player);
}
@Override
public void clearContent() {
this.getItems().clear();
}
@Nullable
@Override
public AbstractContainerMenu createMenu(int i, Inventory inventory, Player player) {
return this.canOpen(player) ? this.createMenu(i, inventory) : null;
}
protected abstract AbstractContainerMenu createMenu(int containerId, Inventory inventory);
@Override
protected void applyImplicitComponents(BlockEntity.DataComponentInput componentInput) {
super.applyImplicitComponents(componentInput);
this.name = componentInput.get(DataComponents.CUSTOM_NAME);
this.lockKey = componentInput.getOrDefault(DataComponents.LOCK, LockCode.NO_LOCK);
componentInput.getOrDefault(DataComponents.CONTAINER, ItemContainerContents.EMPTY).copyInto(this.getItems());
}
@Override
protected void collectImplicitComponents(Builder components) {
super.collectImplicitComponents(components);
components.set(DataComponents.CUSTOM_NAME, this.name);
if (!this.lockKey.equals(LockCode.NO_LOCK)) {
components.set(DataComponents.LOCK, this.lockKey);
}
components.set(DataComponents.CONTAINER, ItemContainerContents.fromItems(this.getItems()));
}
@Override
public void removeComponentsFromTag(CompoundTag tag) {
tag.remove("CustomName");
tag.remove("lock");
tag.remove("Items");
}
}