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

194 lines
5.8 KiB
Java

package net.minecraft.world.level.block.entity;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
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.server.level.ServerLevel;
import net.minecraft.world.level.BaseCommandBlock;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.CommandBlock;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.Vec2;
import net.minecraft.world.phys.Vec3;
public class CommandBlockEntity extends BlockEntity {
private boolean powered;
private boolean auto;
private boolean conditionMet;
private final BaseCommandBlock commandBlock = new BaseCommandBlock() {
@Override
public void setCommand(String command) {
super.setCommand(command);
CommandBlockEntity.this.setChanged();
}
@Override
public ServerLevel getLevel() {
return (ServerLevel)CommandBlockEntity.this.level;
}
@Override
public void onUpdated() {
BlockState blockState = CommandBlockEntity.this.level.getBlockState(CommandBlockEntity.this.worldPosition);
this.getLevel().sendBlockUpdated(CommandBlockEntity.this.worldPosition, blockState, blockState, 3);
}
@Override
public Vec3 getPosition() {
return Vec3.atCenterOf(CommandBlockEntity.this.worldPosition);
}
@Override
public CommandSourceStack createCommandSourceStack() {
Direction direction = CommandBlockEntity.this.getBlockState().getValue(CommandBlock.FACING);
return new CommandSourceStack(
this,
Vec3.atCenterOf(CommandBlockEntity.this.worldPosition),
new Vec2(0.0F, direction.toYRot()),
this.getLevel(),
2,
this.getName().getString(),
this.getName(),
this.getLevel().getServer(),
null
);
}
@Override
public boolean isValid() {
return !CommandBlockEntity.this.isRemoved();
}
};
public CommandBlockEntity(BlockPos pos, BlockState blockState) {
super(BlockEntityType.COMMAND_BLOCK, pos, blockState);
}
@Override
protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) {
super.saveAdditional(tag, registries);
this.commandBlock.save(tag, registries);
tag.putBoolean("powered", this.isPowered());
tag.putBoolean("conditionMet", this.wasConditionMet());
tag.putBoolean("auto", this.isAutomatic());
}
@Override
protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) {
super.loadAdditional(tag, registries);
this.commandBlock.load(tag, registries);
this.powered = tag.getBoolean("powered");
this.conditionMet = tag.getBoolean("conditionMet");
this.setAutomatic(tag.getBoolean("auto"));
}
@Override
public boolean onlyOpCanSetNbt() {
return true;
}
public BaseCommandBlock getCommandBlock() {
return this.commandBlock;
}
public void setPowered(boolean powered) {
this.powered = powered;
}
public boolean isPowered() {
return this.powered;
}
public boolean isAutomatic() {
return this.auto;
}
public void setAutomatic(boolean auto) {
boolean bl = this.auto;
this.auto = auto;
if (!bl && auto && !this.powered && this.level != null && this.getMode() != CommandBlockEntity.Mode.SEQUENCE) {
this.scheduleTick();
}
}
public void onModeSwitch() {
CommandBlockEntity.Mode mode = this.getMode();
if (mode == CommandBlockEntity.Mode.AUTO && (this.powered || this.auto) && this.level != null) {
this.scheduleTick();
}
}
private void scheduleTick() {
Block block = this.getBlockState().getBlock();
if (block instanceof CommandBlock) {
this.markConditionMet();
this.level.scheduleTick(this.worldPosition, block, 1);
}
}
public boolean wasConditionMet() {
return this.conditionMet;
}
public boolean markConditionMet() {
this.conditionMet = true;
if (this.isConditional()) {
BlockPos blockPos = this.worldPosition.relative(((Direction)this.level.getBlockState(this.worldPosition).getValue(CommandBlock.FACING)).getOpposite());
if (this.level.getBlockState(blockPos).getBlock() instanceof CommandBlock) {
BlockEntity blockEntity = this.level.getBlockEntity(blockPos);
this.conditionMet = blockEntity instanceof CommandBlockEntity && ((CommandBlockEntity)blockEntity).getCommandBlock().getSuccessCount() > 0;
} else {
this.conditionMet = false;
}
}
return this.conditionMet;
}
public CommandBlockEntity.Mode getMode() {
BlockState blockState = this.getBlockState();
if (blockState.is(Blocks.COMMAND_BLOCK)) {
return CommandBlockEntity.Mode.REDSTONE;
} else if (blockState.is(Blocks.REPEATING_COMMAND_BLOCK)) {
return CommandBlockEntity.Mode.AUTO;
} else {
return blockState.is(Blocks.CHAIN_COMMAND_BLOCK) ? CommandBlockEntity.Mode.SEQUENCE : CommandBlockEntity.Mode.REDSTONE;
}
}
public boolean isConditional() {
BlockState blockState = this.level.getBlockState(this.getBlockPos());
return blockState.getBlock() instanceof CommandBlock ? (Boolean)blockState.getValue(CommandBlock.CONDITIONAL) : false;
}
@Override
protected void applyImplicitComponents(BlockEntity.DataComponentInput componentInput) {
super.applyImplicitComponents(componentInput);
this.commandBlock.setCustomName(componentInput.get(DataComponents.CUSTOM_NAME));
}
@Override
protected void collectImplicitComponents(Builder components) {
super.collectImplicitComponents(components);
components.set(DataComponents.CUSTOM_NAME, this.commandBlock.getCustomName());
}
@Override
public void removeComponentsFromTag(CompoundTag tag) {
super.removeComponentsFromTag(tag);
tag.remove("CustomName");
tag.remove("conditionMet");
tag.remove("powered");
}
public static enum Mode {
SEQUENCE,
AUTO,
REDSTONE;
}
}