minecraft-src/net/minecraft/commands/arguments/blocks/BlockInput.java
2025-09-18 12:27:44 +00:00

119 lines
4 KiB
Java

package net.minecraft.commands.arguments.blocks;
import com.mojang.logging.LogUtils;
import java.util.Set;
import java.util.function.Predicate;
import net.minecraft.core.BlockPos;
import net.minecraft.core.HolderLookup;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtUtils;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.ProblemReporter;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.pattern.BlockInWorld;
import net.minecraft.world.level.block.state.properties.Property;
import net.minecraft.world.level.storage.TagValueInput;
import net.minecraft.world.level.storage.TagValueOutput;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
public class BlockInput implements Predicate<BlockInWorld> {
private static final Logger LOGGER = LogUtils.getLogger();
private final BlockState state;
private final Set<Property<?>> properties;
@Nullable
private final CompoundTag tag;
public BlockInput(BlockState state, Set<Property<?>> properties, @Nullable CompoundTag tag) {
this.state = state;
this.properties = properties;
this.tag = tag;
}
public BlockState getState() {
return this.state;
}
public Set<Property<?>> getDefinedProperties() {
return this.properties;
}
public boolean test(BlockInWorld block) {
BlockState blockState = block.getState();
if (!blockState.is(this.state.getBlock())) {
return false;
} else {
for (Property<?> property : this.properties) {
if (blockState.getValue(property) != this.state.getValue(property)) {
return false;
}
}
if (this.tag == null) {
return true;
} else {
BlockEntity blockEntity = block.getEntity();
return blockEntity != null && NbtUtils.compareNbt(this.tag, blockEntity.saveWithFullMetadata(block.getLevel().registryAccess()), true);
}
}
}
public boolean test(ServerLevel level, BlockPos pos) {
return this.test(new BlockInWorld(level, pos, false));
}
public boolean place(ServerLevel level, BlockPos pos, int flags) {
BlockState blockState = (flags & 16) != 0 ? this.state : Block.updateFromNeighbourShapes(this.state, level, pos);
if (blockState.isAir()) {
blockState = this.state;
}
blockState = this.overwriteWithDefinedProperties(blockState);
boolean bl = false;
if (level.setBlock(pos, blockState, flags)) {
bl = true;
}
if (this.tag != null) {
BlockEntity blockEntity = level.getBlockEntity(pos);
if (blockEntity != null) {
try (ProblemReporter.ScopedCollector scopedCollector = new ProblemReporter.ScopedCollector(LOGGER)) {
HolderLookup.Provider provider = level.registryAccess();
ProblemReporter problemReporter = scopedCollector.forChild(blockEntity.problemPath());
TagValueOutput tagValueOutput = TagValueOutput.createWithContext(problemReporter.forChild(() -> "(before)"), provider);
blockEntity.saveWithoutMetadata(tagValueOutput);
CompoundTag compoundTag = tagValueOutput.buildResult();
blockEntity.loadWithComponents(TagValueInput.create(scopedCollector, provider, this.tag));
TagValueOutput tagValueOutput2 = TagValueOutput.createWithContext(problemReporter.forChild(() -> "(after)"), provider);
blockEntity.saveWithoutMetadata(tagValueOutput2);
CompoundTag compoundTag2 = tagValueOutput2.buildResult();
if (!compoundTag2.equals(compoundTag)) {
bl = true;
blockEntity.setChanged();
level.getChunkSource().blockChanged(pos);
}
}
}
}
return bl;
}
private BlockState overwriteWithDefinedProperties(BlockState state) {
if (state == this.state) {
return state;
} else {
for (Property<?> property : this.properties) {
state = copyProperty(state, this.state, property);
}
return state;
}
}
private static <T extends Comparable<T>> BlockState copyProperty(BlockState source, BlockState target, Property<T> property) {
return source.trySetValue(property, target.getValue(property));
}
}