169 lines
5 KiB
Java
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");
|
|
}
|
|
}
|