package net.minecraft.world.entity.vehicle; import net.minecraft.commands.CommandSourceStack; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.CommonComponents; import net.minecraft.network.chat.Component; import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.syncher.EntityDataSerializers; import net.minecraft.network.syncher.SynchedEntityData; import net.minecraft.network.syncher.SynchedEntityData.Builder; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.level.BaseCommandBlock; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.Vec3; public class MinecartCommandBlock extends AbstractMinecart { static final EntityDataAccessor DATA_ID_COMMAND_NAME = SynchedEntityData.defineId(MinecartCommandBlock.class, EntityDataSerializers.STRING); static final EntityDataAccessor DATA_ID_LAST_OUTPUT = SynchedEntityData.defineId(MinecartCommandBlock.class, EntityDataSerializers.COMPONENT); private final BaseCommandBlock commandBlock = new MinecartCommandBlock.MinecartCommandBase(); private static final int ACTIVATION_DELAY = 4; /** * Cooldown before command block logic runs again in ticks */ private int lastActivated; public MinecartCommandBlock(EntityType entityType, Level level) { super(entityType, level); } @Override protected Item getDropItem() { return Items.MINECART; } @Override public ItemStack getPickResult() { return new ItemStack(Items.COMMAND_BLOCK_MINECART); } @Override protected void defineSynchedData(Builder builder) { super.defineSynchedData(builder); builder.define(DATA_ID_COMMAND_NAME, ""); builder.define(DATA_ID_LAST_OUTPUT, CommonComponents.EMPTY); } @Override protected void readAdditionalSaveData(CompoundTag tag) { super.readAdditionalSaveData(tag); this.commandBlock.load(tag, this.registryAccess()); this.getEntityData().set(DATA_ID_COMMAND_NAME, this.getCommandBlock().getCommand()); this.getEntityData().set(DATA_ID_LAST_OUTPUT, this.getCommandBlock().getLastOutput()); } @Override protected void addAdditionalSaveData(CompoundTag tag) { super.addAdditionalSaveData(tag); this.commandBlock.save(tag, this.registryAccess()); } @Override public BlockState getDefaultDisplayBlockState() { return Blocks.COMMAND_BLOCK.defaultBlockState(); } public BaseCommandBlock getCommandBlock() { return this.commandBlock; } @Override public void activateMinecart(int x, int y, int z, boolean powered) { if (powered && this.tickCount - this.lastActivated >= 4) { this.getCommandBlock().performCommand(this.level()); this.lastActivated = this.tickCount; } } @Override public InteractionResult interact(Player player, InteractionHand hand) { return this.commandBlock.usedBy(player); } @Override public void onSyncedDataUpdated(EntityDataAccessor dataAccessor) { super.onSyncedDataUpdated(dataAccessor); if (DATA_ID_LAST_OUTPUT.equals(dataAccessor)) { try { this.commandBlock.setLastOutput(this.getEntityData().get(DATA_ID_LAST_OUTPUT)); } catch (Throwable var3) { } } else if (DATA_ID_COMMAND_NAME.equals(dataAccessor)) { this.commandBlock.setCommand(this.getEntityData().get(DATA_ID_COMMAND_NAME)); } } public class MinecartCommandBase extends BaseCommandBlock { @Override public ServerLevel getLevel() { return (ServerLevel)MinecartCommandBlock.this.level(); } @Override public void onUpdated() { MinecartCommandBlock.this.getEntityData().set(MinecartCommandBlock.DATA_ID_COMMAND_NAME, this.getCommand()); MinecartCommandBlock.this.getEntityData().set(MinecartCommandBlock.DATA_ID_LAST_OUTPUT, this.getLastOutput()); } @Override public Vec3 getPosition() { return MinecartCommandBlock.this.position(); } public MinecartCommandBlock getMinecart() { return MinecartCommandBlock.this; } @Override public CommandSourceStack createCommandSourceStack() { return new CommandSourceStack( this, MinecartCommandBlock.this.position(), MinecartCommandBlock.this.getRotationVector(), this.getLevel(), 2, this.getName().getString(), MinecartCommandBlock.this.getDisplayName(), this.getLevel().getServer(), MinecartCommandBlock.this ); } @Override public boolean isValid() { return !MinecartCommandBlock.this.isRemoved(); } } }