104 lines
3.1 KiB
Java
104 lines
3.1 KiB
Java
package net.minecraft.commands.arguments.blocks;
|
|
|
|
import java.util.Set;
|
|
import java.util.function.Predicate;
|
|
import net.minecraft.core.BlockPos;
|
|
import net.minecraft.nbt.CompoundTag;
|
|
import net.minecraft.nbt.NbtUtils;
|
|
import net.minecraft.server.level.ServerLevel;
|
|
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 org.jetbrains.annotations.Nullable;
|
|
|
|
public class BlockInput implements Predicate<BlockInWorld> {
|
|
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) {
|
|
CompoundTag compoundTag = blockEntity.saveWithoutMetadata(level.registryAccess());
|
|
blockEntity.loadWithComponents(this.tag, level.registryAccess());
|
|
CompoundTag compoundTag2 = blockEntity.saveWithoutMetadata(level.registryAccess());
|
|
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));
|
|
}
|
|
}
|