194 lines
5.8 KiB
Java
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;
|
|
}
|
|
}
|