225 lines
10 KiB
Java
225 lines
10 KiB
Java
/*
|
|
* Decompiled with CFR 0.152.
|
|
*
|
|
* Could not load the following classes:
|
|
* com.mojang.datafixers.kinds.App
|
|
* com.mojang.datafixers.kinds.Applicative
|
|
* com.mojang.serialization.MapCodec
|
|
* com.mojang.serialization.codecs.RecordCodecBuilder
|
|
*/
|
|
package net.minecraft.world.level.block;
|
|
|
|
import com.mojang.datafixers.kinds.App;
|
|
import com.mojang.datafixers.kinds.Applicative;
|
|
import com.mojang.serialization.MapCodec;
|
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import net.minecraft.core.BlockPos;
|
|
import net.minecraft.core.Direction;
|
|
import net.minecraft.core.registries.BuiltInRegistries;
|
|
import net.minecraft.server.level.ServerLevel;
|
|
import net.minecraft.util.RandomSource;
|
|
import net.minecraft.world.entity.Entity;
|
|
import net.minecraft.world.entity.InsideBlockEffectApplier;
|
|
import net.minecraft.world.entity.player.Player;
|
|
import net.minecraft.world.item.Items;
|
|
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.ScheduledTickAccess;
|
|
import net.minecraft.world.level.block.Block;
|
|
import net.minecraft.world.level.block.CrossCollisionBlock;
|
|
import net.minecraft.world.level.block.Mirror;
|
|
import net.minecraft.world.level.block.PipeBlock;
|
|
import net.minecraft.world.level.block.Rotation;
|
|
import net.minecraft.world.level.block.TripWireHookBlock;
|
|
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.BooleanProperty;
|
|
import net.minecraft.world.level.gameevent.GameEvent;
|
|
import net.minecraft.world.phys.shapes.CollisionContext;
|
|
import net.minecraft.world.phys.shapes.VoxelShape;
|
|
|
|
public class TripWireBlock
|
|
extends Block {
|
|
public static final MapCodec<TripWireBlock> CODEC = RecordCodecBuilder.mapCodec(i -> i.group((App)BuiltInRegistries.BLOCK.byNameCodec().fieldOf("hook").forGetter(b -> b.hook), TripWireBlock.propertiesCodec()).apply((Applicative)i, TripWireBlock::new));
|
|
public static final BooleanProperty POWERED = BlockStateProperties.POWERED;
|
|
public static final BooleanProperty ATTACHED = BlockStateProperties.ATTACHED;
|
|
public static final BooleanProperty DISARMED = BlockStateProperties.DISARMED;
|
|
public static final BooleanProperty NORTH = PipeBlock.NORTH;
|
|
public static final BooleanProperty EAST = PipeBlock.EAST;
|
|
public static final BooleanProperty SOUTH = PipeBlock.SOUTH;
|
|
public static final BooleanProperty WEST = PipeBlock.WEST;
|
|
private static final Map<Direction, BooleanProperty> PROPERTY_BY_DIRECTION = CrossCollisionBlock.PROPERTY_BY_DIRECTION;
|
|
private static final VoxelShape SHAPE_ATTACHED = Block.column(16.0, 1.0, 2.5);
|
|
private static final VoxelShape SHAPE_NOT_ATTACHED = Block.column(16.0, 0.0, 8.0);
|
|
private static final int RECHECK_PERIOD = 10;
|
|
private final Block hook;
|
|
|
|
public MapCodec<TripWireBlock> codec() {
|
|
return CODEC;
|
|
}
|
|
|
|
public TripWireBlock(Block hook, BlockBehaviour.Properties properties) {
|
|
super(properties);
|
|
this.registerDefaultState((BlockState)((BlockState)((BlockState)((BlockState)((BlockState)((BlockState)((BlockState)((BlockState)this.stateDefinition.any()).setValue(POWERED, false)).setValue(ATTACHED, false)).setValue(DISARMED, false)).setValue(NORTH, false)).setValue(EAST, false)).setValue(SOUTH, false)).setValue(WEST, false));
|
|
this.hook = hook;
|
|
}
|
|
|
|
@Override
|
|
protected VoxelShape getShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext context) {
|
|
return state.getValue(ATTACHED) != false ? SHAPE_ATTACHED : SHAPE_NOT_ATTACHED;
|
|
}
|
|
|
|
@Override
|
|
public BlockState getStateForPlacement(BlockPlaceContext context) {
|
|
Level level = context.getLevel();
|
|
BlockPos pos = context.getClickedPos();
|
|
return (BlockState)((BlockState)((BlockState)((BlockState)this.defaultBlockState().setValue(NORTH, this.shouldConnectTo(level.getBlockState(pos.north()), Direction.NORTH))).setValue(EAST, this.shouldConnectTo(level.getBlockState(pos.east()), Direction.EAST))).setValue(SOUTH, this.shouldConnectTo(level.getBlockState(pos.south()), Direction.SOUTH))).setValue(WEST, this.shouldConnectTo(level.getBlockState(pos.west()), Direction.WEST));
|
|
}
|
|
|
|
@Override
|
|
protected BlockState updateShape(BlockState state, LevelReader level, ScheduledTickAccess ticks, BlockPos pos, Direction directionToNeighbour, BlockPos neighbourPos, BlockState neighbourState, RandomSource random) {
|
|
if (directionToNeighbour.getAxis().isHorizontal()) {
|
|
return (BlockState)state.setValue(PROPERTY_BY_DIRECTION.get(directionToNeighbour), this.shouldConnectTo(neighbourState, directionToNeighbour));
|
|
}
|
|
return super.updateShape(state, level, ticks, pos, directionToNeighbour, neighbourPos, neighbourState, random);
|
|
}
|
|
|
|
@Override
|
|
protected void onPlace(BlockState state, Level level, BlockPos pos, BlockState oldState, boolean movedByPiston) {
|
|
if (oldState.is(state.getBlock())) {
|
|
return;
|
|
}
|
|
this.updateSource(level, pos, state);
|
|
}
|
|
|
|
@Override
|
|
protected void affectNeighborsAfterRemoval(BlockState state, ServerLevel level, BlockPos pos, boolean movedByPiston) {
|
|
if (!movedByPiston) {
|
|
this.updateSource(level, pos, (BlockState)state.setValue(POWERED, true));
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public BlockState playerWillDestroy(Level level, BlockPos pos, BlockState state, Player player) {
|
|
if (!level.isClientSide() && !player.getMainHandItem().isEmpty() && player.getMainHandItem().is(Items.SHEARS)) {
|
|
level.setBlock(pos, (BlockState)state.setValue(DISARMED, true), 260);
|
|
level.gameEvent((Entity)player, GameEvent.SHEAR, pos);
|
|
}
|
|
return super.playerWillDestroy(level, pos, state, player);
|
|
}
|
|
|
|
private void updateSource(Level level, BlockPos pos, BlockState state) {
|
|
block0: for (Direction direction : new Direction[]{Direction.SOUTH, Direction.WEST}) {
|
|
for (int i = 1; i < 42; ++i) {
|
|
BlockPos testPos = pos.relative(direction, i);
|
|
BlockState block = level.getBlockState(testPos);
|
|
if (block.is(this.hook)) {
|
|
if (block.getValue(TripWireHookBlock.FACING) != direction.getOpposite()) continue block0;
|
|
TripWireHookBlock.calculateState(level, testPos, block, false, true, i, state);
|
|
continue block0;
|
|
}
|
|
if (!block.is(this)) continue block0;
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
protected VoxelShape getEntityInsideCollisionShape(BlockState state, BlockGetter level, BlockPos pos, Entity entity) {
|
|
return state.getShape(level, pos);
|
|
}
|
|
|
|
@Override
|
|
protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity, InsideBlockEffectApplier effectApplier, boolean isPrecise) {
|
|
if (level.isClientSide()) {
|
|
return;
|
|
}
|
|
if (state.getValue(POWERED).booleanValue()) {
|
|
return;
|
|
}
|
|
this.checkPressed(level, pos, List.of(entity));
|
|
}
|
|
|
|
@Override
|
|
protected void tick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) {
|
|
if (!level.getBlockState(pos).getValue(POWERED).booleanValue()) {
|
|
return;
|
|
}
|
|
this.checkPressed(level, pos);
|
|
}
|
|
|
|
private void checkPressed(Level level, BlockPos pos) {
|
|
BlockState state = level.getBlockState(pos);
|
|
List<Entity> entities = level.getEntities(null, state.getShape(level, pos).bounds().move(pos));
|
|
this.checkPressed(level, pos, entities);
|
|
}
|
|
|
|
private void checkPressed(Level level, BlockPos pos, List<? extends Entity> entities) {
|
|
BlockState state = level.getBlockState(pos);
|
|
boolean wasPressed = state.getValue(POWERED);
|
|
boolean shouldBePressed = false;
|
|
if (!entities.isEmpty()) {
|
|
for (Entity entity : entities) {
|
|
if (entity.isIgnoringBlockTriggers()) continue;
|
|
shouldBePressed = true;
|
|
break;
|
|
}
|
|
}
|
|
if (shouldBePressed != wasPressed) {
|
|
state = (BlockState)state.setValue(POWERED, shouldBePressed);
|
|
level.setBlock(pos, state, 3);
|
|
this.updateSource(level, pos, state);
|
|
}
|
|
if (shouldBePressed) {
|
|
level.scheduleTick(new BlockPos(pos), this, 10);
|
|
}
|
|
}
|
|
|
|
public boolean shouldConnectTo(BlockState blockState, Direction direction) {
|
|
if (blockState.is(this.hook)) {
|
|
return blockState.getValue(TripWireHookBlock.FACING) == direction.getOpposite();
|
|
}
|
|
return blockState.is(this);
|
|
}
|
|
|
|
@Override
|
|
protected BlockState rotate(BlockState state, Rotation rotation) {
|
|
switch (rotation) {
|
|
case CLOCKWISE_180: {
|
|
return (BlockState)((BlockState)((BlockState)((BlockState)state.setValue(NORTH, state.getValue(SOUTH))).setValue(EAST, state.getValue(WEST))).setValue(SOUTH, state.getValue(NORTH))).setValue(WEST, state.getValue(EAST));
|
|
}
|
|
case COUNTERCLOCKWISE_90: {
|
|
return (BlockState)((BlockState)((BlockState)((BlockState)state.setValue(NORTH, state.getValue(EAST))).setValue(EAST, state.getValue(SOUTH))).setValue(SOUTH, state.getValue(WEST))).setValue(WEST, state.getValue(NORTH));
|
|
}
|
|
case CLOCKWISE_90: {
|
|
return (BlockState)((BlockState)((BlockState)((BlockState)state.setValue(NORTH, state.getValue(WEST))).setValue(EAST, state.getValue(NORTH))).setValue(SOUTH, state.getValue(EAST))).setValue(WEST, state.getValue(SOUTH));
|
|
}
|
|
}
|
|
return state;
|
|
}
|
|
|
|
@Override
|
|
protected BlockState mirror(BlockState state, Mirror mirror) {
|
|
switch (mirror) {
|
|
case LEFT_RIGHT: {
|
|
return (BlockState)((BlockState)state.setValue(NORTH, state.getValue(SOUTH))).setValue(SOUTH, state.getValue(NORTH));
|
|
}
|
|
case FRONT_BACK: {
|
|
return (BlockState)((BlockState)state.setValue(EAST, state.getValue(WEST))).setValue(WEST, state.getValue(EAST));
|
|
}
|
|
}
|
|
return super.mirror(state, mirror);
|
|
}
|
|
|
|
@Override
|
|
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
|
|
builder.add(POWERED, ATTACHED, DISARMED, NORTH, EAST, WEST, SOUTH);
|
|
}
|
|
}
|
|
|