203 lines
8.7 KiB
Java
203 lines
8.7 KiB
Java
|
package net.minecraft.world.level.block;
|
||
|
|
||
|
import com.mojang.serialization.MapCodec;
|
||
|
import java.util.List;
|
||
|
import javax.annotation.Nullable;
|
||
|
import net.minecraft.core.BlockPos;
|
||
|
import net.minecraft.core.Direction;
|
||
|
import net.minecraft.server.level.ServerLevel;
|
||
|
import net.minecraft.sounds.SoundEvents;
|
||
|
import net.minecraft.sounds.SoundSource;
|
||
|
import net.minecraft.util.RandomSource;
|
||
|
import net.minecraft.world.InteractionResult;
|
||
|
import net.minecraft.world.entity.decoration.ItemFrame;
|
||
|
import net.minecraft.world.entity.player.Player;
|
||
|
import net.minecraft.world.level.BlockGetter;
|
||
|
import net.minecraft.world.level.Level;
|
||
|
import net.minecraft.world.level.LevelReader;
|
||
|
import net.minecraft.world.level.ScheduledTickAccess;
|
||
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||
|
import net.minecraft.world.level.block.entity.ComparatorBlockEntity;
|
||
|
import net.minecraft.world.level.block.state.BlockBehaviour;
|
||
|
import net.minecraft.world.level.block.state.BlockState;
|
||
|
import net.minecraft.world.level.block.state.StateDefinition;
|
||
|
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||
|
import net.minecraft.world.level.block.state.properties.ComparatorMode;
|
||
|
import net.minecraft.world.level.block.state.properties.EnumProperty;
|
||
|
import net.minecraft.world.phys.AABB;
|
||
|
import net.minecraft.world.phys.BlockHitResult;
|
||
|
import net.minecraft.world.ticks.TickPriority;
|
||
|
|
||
|
public class ComparatorBlock extends DiodeBlock implements EntityBlock {
|
||
|
public static final MapCodec<ComparatorBlock> CODEC = simpleCodec(ComparatorBlock::new);
|
||
|
public static final EnumProperty<ComparatorMode> MODE = BlockStateProperties.MODE_COMPARATOR;
|
||
|
|
||
|
@Override
|
||
|
public MapCodec<ComparatorBlock> codec() {
|
||
|
return CODEC;
|
||
|
}
|
||
|
|
||
|
public ComparatorBlock(BlockBehaviour.Properties p_51857_) {
|
||
|
super(p_51857_);
|
||
|
this.registerDefaultState(this.stateDefinition.any().setValue(FACING, Direction.NORTH).setValue(POWERED, false).setValue(MODE, ComparatorMode.COMPARE));
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
protected int getDelay(BlockState p_51912_) {
|
||
|
return 2;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public BlockState updateShape(
|
||
|
BlockState p_298756_,
|
||
|
LevelReader p_361531_,
|
||
|
ScheduledTickAccess p_368115_,
|
||
|
BlockPos p_299729_,
|
||
|
Direction p_300136_,
|
||
|
BlockPos p_297639_,
|
||
|
BlockState p_299304_,
|
||
|
RandomSource p_368851_
|
||
|
) {
|
||
|
return p_300136_ == Direction.DOWN && !this.canSurviveOn(p_361531_, p_297639_, p_299304_)
|
||
|
? Blocks.AIR.defaultBlockState()
|
||
|
: super.updateShape(p_298756_, p_361531_, p_368115_, p_299729_, p_300136_, p_297639_, p_299304_, p_368851_);
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
protected int getOutputSignal(BlockGetter p_51892_, BlockPos p_51893_, BlockState p_51894_) {
|
||
|
BlockEntity blockentity = p_51892_.getBlockEntity(p_51893_);
|
||
|
return blockentity instanceof ComparatorBlockEntity ? ((ComparatorBlockEntity)blockentity).getOutputSignal() : 0;
|
||
|
}
|
||
|
|
||
|
private int calculateOutputSignal(Level p_51904_, BlockPos p_51905_, BlockState p_51906_) {
|
||
|
int i = this.getInputSignal(p_51904_, p_51905_, p_51906_);
|
||
|
if (i == 0) {
|
||
|
return 0;
|
||
|
} else {
|
||
|
int j = this.getAlternateSignal(p_51904_, p_51905_, p_51906_);
|
||
|
if (j > i) {
|
||
|
return 0;
|
||
|
} else {
|
||
|
return p_51906_.getValue(MODE) == ComparatorMode.SUBTRACT ? i - j : i;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
protected boolean shouldTurnOn(Level p_51861_, BlockPos p_51862_, BlockState p_51863_) {
|
||
|
int i = this.getInputSignal(p_51861_, p_51862_, p_51863_);
|
||
|
if (i == 0) {
|
||
|
return false;
|
||
|
} else {
|
||
|
int j = this.getAlternateSignal(p_51861_, p_51862_, p_51863_);
|
||
|
return i > j ? true : i == j && p_51863_.getValue(MODE) == ComparatorMode.COMPARE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
protected int getInputSignal(Level p_51896_, BlockPos p_51897_, BlockState p_51898_) {
|
||
|
int i = super.getInputSignal(p_51896_, p_51897_, p_51898_);
|
||
|
Direction direction = p_51898_.getValue(FACING);
|
||
|
BlockPos blockpos = p_51897_.relative(direction);
|
||
|
BlockState blockstate = p_51896_.getBlockState(blockpos);
|
||
|
if (blockstate.hasAnalogOutputSignal()) {
|
||
|
i = blockstate.getAnalogOutputSignal(p_51896_, blockpos);
|
||
|
} else if (i < 15 && blockstate.isRedstoneConductor(p_51896_, blockpos)) {
|
||
|
blockpos = blockpos.relative(direction);
|
||
|
blockstate = p_51896_.getBlockState(blockpos);
|
||
|
ItemFrame itemframe = this.getItemFrame(p_51896_, direction, blockpos);
|
||
|
int j = Math.max(
|
||
|
itemframe == null ? Integer.MIN_VALUE : itemframe.getAnalogOutput(),
|
||
|
blockstate.hasAnalogOutputSignal() ? blockstate.getAnalogOutputSignal(p_51896_, blockpos) : Integer.MIN_VALUE
|
||
|
);
|
||
|
if (j != Integer.MIN_VALUE) {
|
||
|
i = j;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return i;
|
||
|
}
|
||
|
|
||
|
@Nullable
|
||
|
private ItemFrame getItemFrame(Level p_51865_, Direction p_51866_, BlockPos p_51867_) {
|
||
|
List<ItemFrame> list = p_51865_.getEntitiesOfClass(
|
||
|
ItemFrame.class,
|
||
|
new AABB(
|
||
|
p_51867_.getX(), p_51867_.getY(), p_51867_.getZ(), p_51867_.getX() + 1, p_51867_.getY() + 1, p_51867_.getZ() + 1
|
||
|
),
|
||
|
p_360423_ -> p_360423_ != null && p_360423_.getDirection() == p_51866_
|
||
|
);
|
||
|
return list.size() == 1 ? list.get(0) : null;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
protected InteractionResult useWithoutItem(BlockState p_51880_, Level p_51881_, BlockPos p_51882_, Player p_51883_, BlockHitResult p_51885_) {
|
||
|
if (!p_51883_.getAbilities().mayBuild) {
|
||
|
return InteractionResult.PASS;
|
||
|
} else {
|
||
|
p_51880_ = p_51880_.cycle(MODE);
|
||
|
float f = p_51880_.getValue(MODE) == ComparatorMode.SUBTRACT ? 0.55F : 0.5F;
|
||
|
p_51881_.playSound(p_51883_, p_51882_, SoundEvents.COMPARATOR_CLICK, SoundSource.BLOCKS, 0.3F, f);
|
||
|
p_51881_.setBlock(p_51882_, p_51880_, 2);
|
||
|
this.refreshOutputState(p_51881_, p_51882_, p_51880_);
|
||
|
return InteractionResult.SUCCESS;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
protected void checkTickOnNeighbor(Level p_51900_, BlockPos p_51901_, BlockState p_51902_) {
|
||
|
if (!p_51900_.getBlockTicks().willTickThisTick(p_51901_, this)) {
|
||
|
int i = this.calculateOutputSignal(p_51900_, p_51901_, p_51902_);
|
||
|
BlockEntity blockentity = p_51900_.getBlockEntity(p_51901_);
|
||
|
int j = blockentity instanceof ComparatorBlockEntity ? ((ComparatorBlockEntity)blockentity).getOutputSignal() : 0;
|
||
|
if (i != j || p_51902_.getValue(POWERED) != this.shouldTurnOn(p_51900_, p_51901_, p_51902_)) {
|
||
|
TickPriority tickpriority = this.shouldPrioritize(p_51900_, p_51901_, p_51902_) ? TickPriority.HIGH : TickPriority.NORMAL;
|
||
|
p_51900_.scheduleTick(p_51901_, this, 2, tickpriority);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void refreshOutputState(Level p_51908_, BlockPos p_51909_, BlockState p_51910_) {
|
||
|
int i = this.calculateOutputSignal(p_51908_, p_51909_, p_51910_);
|
||
|
BlockEntity blockentity = p_51908_.getBlockEntity(p_51909_);
|
||
|
int j = 0;
|
||
|
if (blockentity instanceof ComparatorBlockEntity comparatorblockentity) {
|
||
|
j = comparatorblockentity.getOutputSignal();
|
||
|
comparatorblockentity.setOutputSignal(i);
|
||
|
}
|
||
|
|
||
|
if (j != i || p_51910_.getValue(MODE) == ComparatorMode.COMPARE) {
|
||
|
boolean flag1 = this.shouldTurnOn(p_51908_, p_51909_, p_51910_);
|
||
|
boolean flag = p_51910_.getValue(POWERED);
|
||
|
if (flag && !flag1) {
|
||
|
p_51908_.setBlock(p_51909_, p_51910_.setValue(POWERED, false), 2);
|
||
|
} else if (!flag && flag1) {
|
||
|
p_51908_.setBlock(p_51909_, p_51910_.setValue(POWERED, true), 2);
|
||
|
}
|
||
|
|
||
|
this.updateNeighborsInFront(p_51908_, p_51909_, p_51910_);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
protected void tick(BlockState p_221010_, ServerLevel p_221011_, BlockPos p_221012_, RandomSource p_221013_) {
|
||
|
this.refreshOutputState(p_221011_, p_221012_, p_221010_);
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
protected boolean triggerEvent(BlockState p_51874_, Level p_51875_, BlockPos p_51876_, int p_51877_, int p_51878_) {
|
||
|
super.triggerEvent(p_51874_, p_51875_, p_51876_, p_51877_, p_51878_);
|
||
|
BlockEntity blockentity = p_51875_.getBlockEntity(p_51876_);
|
||
|
return blockentity != null && blockentity.triggerEvent(p_51877_, p_51878_);
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public BlockEntity newBlockEntity(BlockPos p_153086_, BlockState p_153087_) {
|
||
|
return new ComparatorBlockEntity(p_153086_, p_153087_);
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> p_51887_) {
|
||
|
p_51887_.add(FACING, MODE, POWERED);
|
||
|
}
|
||
|
}
|