Code/net/minecraft/world/level/block/DiodeBlock.java

201 lines
8.5 KiB
Java
Raw Permalink Normal View History

2025-07-01 06:20:03 +00:00
package net.minecraft.world.level.block;
import com.mojang.serialization.MapCodec;
import javax.annotation.Nullable;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.RandomSource;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.SignalGetter;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.block.state.properties.BooleanProperty;
import net.minecraft.world.level.redstone.ExperimentalRedstoneUtils;
import net.minecraft.world.level.redstone.Orientation;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
import net.minecraft.world.ticks.TickPriority;
public abstract class DiodeBlock extends HorizontalDirectionalBlock {
public static final BooleanProperty POWERED = BlockStateProperties.POWERED;
private static final VoxelShape SHAPE = Block.column(16.0, 0.0, 2.0);
protected DiodeBlock(BlockBehaviour.Properties p_52499_) {
super(p_52499_);
}
@Override
protected abstract MapCodec<? extends DiodeBlock> codec();
@Override
protected VoxelShape getShape(BlockState p_52556_, BlockGetter p_52557_, BlockPos p_52558_, CollisionContext p_52559_) {
return SHAPE;
}
@Override
protected boolean canSurvive(BlockState p_52538_, LevelReader p_52539_, BlockPos p_52540_) {
BlockPos blockpos = p_52540_.below();
return this.canSurviveOn(p_52539_, blockpos, p_52539_.getBlockState(blockpos));
}
protected boolean canSurviveOn(LevelReader p_299987_, BlockPos p_298116_, BlockState p_297597_) {
return p_297597_.isFaceSturdy(p_299987_, p_298116_, Direction.UP, SupportType.RIGID);
}
@Override
protected void tick(BlockState p_221065_, ServerLevel p_221066_, BlockPos p_221067_, RandomSource p_221068_) {
if (!this.isLocked(p_221066_, p_221067_, p_221065_)) {
boolean flag = p_221065_.getValue(POWERED);
boolean flag1 = this.shouldTurnOn(p_221066_, p_221067_, p_221065_);
if (flag && !flag1) {
p_221066_.setBlock(p_221067_, p_221065_.setValue(POWERED, false), 2);
} else if (!flag) {
p_221066_.setBlock(p_221067_, p_221065_.setValue(POWERED, true), 2);
if (!flag1) {
p_221066_.scheduleTick(p_221067_, this, this.getDelay(p_221065_), TickPriority.VERY_HIGH);
}
}
}
}
@Override
protected int getDirectSignal(BlockState p_52561_, BlockGetter p_52562_, BlockPos p_52563_, Direction p_52564_) {
return p_52561_.getSignal(p_52562_, p_52563_, p_52564_);
}
@Override
protected int getSignal(BlockState p_52520_, BlockGetter p_52521_, BlockPos p_52522_, Direction p_52523_) {
if (!p_52520_.getValue(POWERED)) {
return 0;
} else {
return p_52520_.getValue(FACING) == p_52523_ ? this.getOutputSignal(p_52521_, p_52522_, p_52520_) : 0;
}
}
@Override
protected void neighborChanged(BlockState p_52525_, Level p_52526_, BlockPos p_52527_, Block p_52528_, @Nullable Orientation p_363702_, boolean p_52530_) {
if (p_52525_.canSurvive(p_52526_, p_52527_)) {
this.checkTickOnNeighbor(p_52526_, p_52527_, p_52525_);
} else {
BlockEntity blockentity = p_52525_.hasBlockEntity() ? p_52526_.getBlockEntity(p_52527_) : null;
dropResources(p_52525_, p_52526_, p_52527_, blockentity);
p_52526_.removeBlock(p_52527_, false);
for (Direction direction : Direction.values()) {
p_52526_.updateNeighborsAt(p_52527_.relative(direction), this);
}
}
}
protected void checkTickOnNeighbor(Level p_52577_, BlockPos p_52578_, BlockState p_52579_) {
if (!this.isLocked(p_52577_, p_52578_, p_52579_)) {
boolean flag = p_52579_.getValue(POWERED);
boolean flag1 = this.shouldTurnOn(p_52577_, p_52578_, p_52579_);
if (flag != flag1 && !p_52577_.getBlockTicks().willTickThisTick(p_52578_, this)) {
TickPriority tickpriority = TickPriority.HIGH;
if (this.shouldPrioritize(p_52577_, p_52578_, p_52579_)) {
tickpriority = TickPriority.EXTREMELY_HIGH;
} else if (flag) {
tickpriority = TickPriority.VERY_HIGH;
}
p_52577_.scheduleTick(p_52578_, this, this.getDelay(p_52579_), tickpriority);
}
}
}
public boolean isLocked(LevelReader p_52511_, BlockPos p_52512_, BlockState p_52513_) {
return false;
}
protected boolean shouldTurnOn(Level p_52502_, BlockPos p_52503_, BlockState p_52504_) {
return this.getInputSignal(p_52502_, p_52503_, p_52504_) > 0;
}
protected int getInputSignal(Level p_52544_, BlockPos p_52545_, BlockState p_52546_) {
Direction direction = p_52546_.getValue(FACING);
BlockPos blockpos = p_52545_.relative(direction);
int i = p_52544_.getSignal(blockpos, direction);
if (i >= 15) {
return i;
} else {
BlockState blockstate = p_52544_.getBlockState(blockpos);
return Math.max(i, blockstate.is(Blocks.REDSTONE_WIRE) ? blockstate.getValue(RedStoneWireBlock.POWER) : 0);
}
}
protected int getAlternateSignal(SignalGetter p_277358_, BlockPos p_277763_, BlockState p_277604_) {
Direction direction = p_277604_.getValue(FACING);
Direction direction1 = direction.getClockWise();
Direction direction2 = direction.getCounterClockWise();
boolean flag = this.sideInputDiodesOnly();
return Math.max(
p_277358_.getControlInputSignal(p_277763_.relative(direction1), direction1, flag), p_277358_.getControlInputSignal(p_277763_.relative(direction2), direction2, flag)
);
}
@Override
protected boolean isSignalSource(BlockState p_52572_) {
return true;
}
@Override
public BlockState getStateForPlacement(BlockPlaceContext p_52501_) {
return this.defaultBlockState().setValue(FACING, p_52501_.getHorizontalDirection().getOpposite());
}
@Override
public void setPlacedBy(Level p_52506_, BlockPos p_52507_, BlockState p_52508_, LivingEntity p_52509_, ItemStack p_52510_) {
if (this.shouldTurnOn(p_52506_, p_52507_, p_52508_)) {
p_52506_.scheduleTick(p_52507_, this, 1);
}
}
@Override
protected void onPlace(BlockState p_52566_, Level p_52567_, BlockPos p_52568_, BlockState p_52569_, boolean p_52570_) {
this.updateNeighborsInFront(p_52567_, p_52568_, p_52566_);
}
@Override
protected void affectNeighborsAfterRemoval(BlockState p_397978_, ServerLevel p_391595_, BlockPos p_392425_, boolean p_397263_) {
if (!p_397263_) {
this.updateNeighborsInFront(p_391595_, p_392425_, p_397978_);
}
}
protected void updateNeighborsInFront(Level p_52581_, BlockPos p_52582_, BlockState p_52583_) {
Direction direction = p_52583_.getValue(FACING);
BlockPos blockpos = p_52582_.relative(direction.getOpposite());
Orientation orientation = ExperimentalRedstoneUtils.initialOrientation(p_52581_, direction.getOpposite(), Direction.UP);
p_52581_.neighborChanged(blockpos, this, orientation);
p_52581_.updateNeighborsAtExceptFromFacing(blockpos, this, direction, orientation);
}
protected boolean sideInputDiodesOnly() {
return false;
}
protected int getOutputSignal(BlockGetter p_52541_, BlockPos p_52542_, BlockState p_52543_) {
return 15;
}
public static boolean isDiode(BlockState p_52587_) {
return p_52587_.getBlock() instanceof DiodeBlock;
}
public boolean shouldPrioritize(BlockGetter p_52574_, BlockPos p_52575_, BlockState p_52576_) {
Direction direction = p_52576_.getValue(FACING).getOpposite();
BlockState blockstate = p_52574_.getBlockState(p_52575_.relative(direction));
return isDiode(blockstate) && blockstate.getValue(FACING) != direction;
}
protected abstract int getDelay(BlockState p_52584_);
}