ModernLifePatch/src-source/main/java/com/dairymoose/modernlife/blocks/GrateBlock.java
2024-10-26 09:40:21 +08:00

365 lines
19 KiB
Java

package com.dairymoose.modernlife.blocks;
import com.dairymoose.modernlife.core.CustomBlocks;
import com.dairymoose.modernlife.core.McpConstants;
import com.dairymoose.modernlife.core.ModernLifeCommon;
import com.dairymoose.modernlife.util.ModernLifeUtil;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;
import javax.annotation.Nullable;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TextComponent;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.StringRepresentable;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.ExperienceOrb;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.LiquidBlock;
import net.minecraft.world.level.block.SimpleWaterloggedBlock;
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.AttachFace;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.block.state.properties.BooleanProperty;
import net.minecraft.world.level.block.state.properties.EnumProperty;
import net.minecraft.world.level.block.state.properties.IntegerProperty;
import net.minecraft.world.level.block.state.properties.Property;
import net.minecraft.world.level.material.FlowingFluid;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.level.material.Fluids;
import net.minecraft.world.level.material.LavaFluid;
import net.minecraft.world.level.material.WaterFluid;
import net.minecraft.world.phys.shapes.BooleanOp;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.EntityCollisionContext;
import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
/* loaded from: outputsrg.jar:com/dairymoose/modernlife/blocks/GrateBlock.class */
public class
GrateBlock extends AbstractPanelBlock implements SimpleWaterloggedBlock {
private boolean allowAllLiquids = true;
private static final int MS_PER_TICK = 50;
private static final float GRATE_SLOWDOWN_FACTOR = 1.0f;
private final ScheduledExecutorService scheduler;
public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED;
public static final IntegerProperty LEVEL = IntegerProperty.create("level", 0, 8);
public static final EnumProperty<FluidType> FLUIDTYPE = EnumProperty.create("fluidtype", FluidType.class);
private static final HashSet<BlockPos> respawning = new HashSet<>();
private static final HashMap<BlockPos, Integer> waterLevel = new HashMap<>();
protected static final VoxelShape SHAPE_FLOOR_NORTH = (VoxelShape) Stream.of(Block.box(0.0d, 0.0d, 0.0d, 16.0d, 1.0d, 16.0d)).reduce((v1, v2) -> {
return Shapes.join(v1, v2, BooleanOp.OR);
}).get();
protected static final VoxelShape SHAPE_WALL_NORTH = (VoxelShape) Stream.of(Block.box(0.0d, 0.0d, 15.0d, 16.0d, 16.0d, 16.0d)).reduce((v1, v2) -> {
return Shapes.join(v1, v2, BooleanOp.OR);
}).get();
protected static final VoxelShape SHAPE_WALL_EAST = ModernLifeUtil.RotateVoxelShapeClockwise(SHAPE_WALL_NORTH);
protected static final VoxelShape SHAPE_WALL_SOUTH = ModernLifeUtil.RotateVoxelShapeClockwise(SHAPE_WALL_EAST);
protected static final VoxelShape SHAPE_WALL_WEST = ModernLifeUtil.RotateVoxelShapeClockwise(SHAPE_WALL_SOUTH);
protected static final VoxelShape SHAPE_CEILING_NORTH = (VoxelShape) Stream.of(Block.box(0.0d, 15.0d, 0.0d, 16.0d, 16.0d, 16.0d)).reduce((v1, v2) -> {
return Shapes.join(v1, v2, BooleanOp.OR);
}).get();
/* loaded from: outputsrg.jar:com/dairymoose/modernlife/blocks/GrateBlock$FluidType.class */
public enum FluidType implements StringRepresentable {
water,
lava;
public String getSerializedName() {
return name().toLowerCase();
}
}
public GrateBlock(Properties props) {
super(props);
this.allowAllLiquids = true;
this.scheduler = Executors.newScheduledThreadPool(1);
registerDefaultState((BlockState) ((BlockState) ((BlockState) ((BlockState) this.stateDefinition.any().setValue(AbstractPanelBlock.FACING, Direction.NORTH)).setValue(AbstractPanelBlock.FACE, AttachFace.FLOOR)).setValue(WATERLOGGED, false)).setValue(LEVEL, 0));
}
public ItemStack pickupBlock(LevelAccessor p_154560_, BlockPos p_154561_, BlockState p_154562_) {
ItemStack fluid = pickupBlock(p_154560_, p_154561_, p_154562_);
BlockState newState = p_154560_.getBlockState(p_154561_);
if (!((Boolean) newState.getValue(WATERLOGGED)).booleanValue()) {
ModernLifeCommon.LOGGER.debug("Set level to 0");
p_154560_.setBlock(p_154561_, (BlockState) newState.setValue(LEVEL, 0), 3);
}
return fluid;
}
@OnlyIn(Dist.CLIENT)
public void appendHoverText(ItemStack itemStack, @Nullable BlockGetter blockReader, List<Component> list, TooltipFlag tooltipFlag) {
list.add(new TextComponent("Allows water and items to flow through freely"));
}
public boolean placeLiquid(LevelAccessor p_204509_1_, BlockPos p_204509_2_, BlockState p_204509_3_, FluidState p_204509_4_) {
if ((p_204509_4_.getType() instanceof WaterFluid) || (p_204509_4_.getType() instanceof LavaFluid)) {
if (p_204509_1_ instanceof ServerLevel) {
ServerLevel world = (ServerLevel) p_204509_1_;
FluidType f = FluidType.water;
if (p_204509_4_.getType() instanceof WaterFluid) {
f = FluidType.water;
} else if (p_204509_4_.getType() instanceof LavaFluid) {
f = FluidType.lava;
}
int newLevel = p_204509_4_.getAmount();
ModernLifeCommon.LOGGER.debug("placeLiquid update: " + p_204509_4_);
if (p_204509_4_.isSource()) {
world.setBlock(p_204509_2_, (BlockState) ((BlockState) ((BlockState) p_204509_3_.setValue(WATERLOGGED, true)).setValue(FLUIDTYPE, f)).setValue(LEVEL, Integer.valueOf(newLevel)), 3);
return true;
}
world.setBlock(p_204509_2_, (BlockState) ((BlockState) p_204509_3_.setValue(LEVEL, Integer.valueOf(newLevel))).setValue(FLUIDTYPE, f), 3);
return true;
}
return true;
}
return false;
}
public boolean canPlaceLiquid(BlockGetter p_204510_1_, BlockPos p_204510_2_, BlockState p_204510_3_, Fluid p_204510_4_) {
if (this.allowAllLiquids) {
return true;
}
return canPlaceLiquid(p_204510_1_, p_204510_2_, p_204510_3_, p_204510_4_);
}
public BlockState updateShape(BlockState grate, Direction dir, BlockState updater, LevelAccessor world, BlockPos gratePos, BlockPos updaterPos) {
ModernLifeCommon.LOGGER.debug("world = " + world);
ModernLifeCommon.LOGGER.debug("updateShape, bs1: " + grate + " with pos = " + gratePos);
ModernLifeCommon.LOGGER.debug("updateShape, bs2: " + updater + " with pos = " + updaterPos);
ModernLifeCommon.LOGGER.debug("direction = " + dir);
final BlockPos originalGratePos = gratePos.mutable();
final GrateBlock grateBlock = this;
this.scheduler.schedule(new Runnable() { // from class: com.dairymoose.modernlife.blocks.GrateBlock.1
@Override // java.lang.Runnable
public void run() {
Method newLiquidMethod = null;
try {
try {
int currentLevel = ((Integer) grate.getValue(GrateBlock.LEVEL)).intValue();
try {
newLiquidMethod = FlowingFluid.class.getDeclaredMethod(McpConstants.FLOWING_FLUID_getNewLiquid, LevelReader.class, BlockPos.class, BlockState.class);
} catch (NoSuchMethodException e) {
}
if (newLiquidMethod == null) {
newLiquidMethod = FlowingFluid.class.getDeclaredMethod("getNewLiquid", LevelReader.class, BlockPos.class, BlockState.class);
}
newLiquidMethod.setAccessible(true);
FluidState newFluid = (FluidState) newLiquidMethod.invoke(Fluids.FLOWING_WATER, world, originalGratePos, grate);
int newLevel = newFluid.getAmount();
if (newLevel < currentLevel) {
BlockState newGrateState = world.getBlockState(originalGratePos);
if (newGrateState.is(CustomBlocks.BLOCK_METAL_GRATE.get()) && !((Boolean) newGrateState.getValue(GrateBlock.WATERLOGGED)).booleanValue()) {
world.setBlock(originalGratePos, (BlockState) grate.setValue(GrateBlock.LEVEL, Integer.valueOf(newLevel)), 3);
}
ModernLifeCommon.LOGGER.debug("Set to new state: " + grate.setValue(GrateBlock.LEVEL, Integer.valueOf(newLevel)));
}
allowAllLiquids = true;
} catch (Throwable th) {
allowAllLiquids = true;
throw th;
}
} catch (IllegalAccessException | IllegalArgumentException | NoSuchMethodException | SecurityException | InvocationTargetException e1) {
ModernLifeCommon.LOGGER.error("getNewLiquid error", e1);
allowAllLiquids = true;
}
}
}, (int) (MS_PER_TICK * updater.getFluidState().getType().getTickDelay(world) * GRATE_SLOWDOWN_FACTOR), TimeUnit.MILLISECONDS);
return grate;
}
public VoxelShape getCollisionShape(BlockState state, BlockGetter blockReader, BlockPos blockPos, CollisionContext ctx) {
Entity collisionEntity = null;
if (ctx instanceof EntityCollisionContext) {
collisionEntity = ((EntityCollisionContext) ctx).getEntity() != null ? ((EntityCollisionContext) ctx).getEntity() : null;
}
if (ctx == CollisionContext.empty() || (collisionEntity != null && ((collisionEntity instanceof ItemEntity) || (collisionEntity instanceof ExperienceOrb)))) {
return Shapes.empty();
}
return super.getCollisionShape(state, blockReader, blockPos, ctx);
}
@Override // com.dairymoose.modernlife.blocks.AbstractPanelBlock
public BlockState getStateForPlacement(BlockPlaceContext context) {
FluidType f = FluidType.water;
Level world = context.getLevel();
BlockPos pos = context.getClickedPos();
BlockState oldState = world.getBlockState(pos);
if (oldState.getFluidState().getType() instanceof WaterFluid) {
f = FluidType.water;
} else if (oldState.getFluidState().getType() instanceof LavaFluid) {
f = FluidType.lava;
}
boolean waterlogged = false;
if (!oldState.getFluidState().isEmpty() && oldState.getFluidState().isSource()) {
waterlogged = true;
}
return (BlockState) ((BlockState) ((BlockState) super.getStateForPlacement(context).setValue(LEVEL, Integer.valueOf(oldState.getFluidState().getAmount()))).setValue(FLUIDTYPE, f)).setValue(WATERLOGGED, Boolean.valueOf(waterlogged));
}
@Deprecated
public void onPlace(BlockState newState, Level world, BlockPos pos, BlockState oldState, boolean p_220082_5_) {
ModernLifeCommon.LOGGER.debug("onPlace newState = " + newState + ", bool=" + p_220082_5_);
if (!(oldState.getBlock() instanceof LiquidBlock) || !oldState.getFluidState().isEmpty()) {
}
int level = ((Integer) newState.getValue(LEVEL)).intValue();
if (level >= 0) {
this.scheduler.schedule(new Runnable() { // from class: com.dairymoose.modernlife.blocks.GrateBlock.2
@Override // java.lang.Runnable
public void run() {
FlowingFluid fluid = Fluids.WATER;
if (newState.getValue(GrateBlock.FLUIDTYPE) == FluidType.water) {
fluid = Fluids.WATER;
} else if (newState.getValue(GrateBlock.FLUIDTYPE) == FluidType.lava) {
fluid = Fluids.LAVA;
}
int level2 = ((Integer) newState.getValue(GrateBlock.LEVEL)).intValue();
Method m = null;
try {
try {
m = FlowingFluid.class.getDeclaredMethod(McpConstants.FLOWING_FLUID_spread, LevelAccessor.class, BlockPos.class, FluidState.class);
} catch (NoSuchMethodException e) {
}
if (m == null) {
m = FlowingFluid.class.getDeclaredMethod("spread", LevelAccessor.class, BlockPos.class, FluidState.class);
}
m.setAccessible(true);
Fluids.EMPTY.defaultFluidState();
if (level2 > 0 && (fluid instanceof FlowingFluid)) {
FluidState fs = fluid.getFlowing(level2, false);
m.invoke(fluid, world, pos, fs);
}
} catch (IllegalAccessException | IllegalArgumentException | NoSuchMethodException | SecurityException | InvocationTargetException e2) {
ModernLifeCommon.LOGGER.error("Fluid error", e2);
}
world.updateNeighborsAt(pos, newState.getBlock());
}
}, MS_PER_TICK * getFluidState(newState).getType().getTickDelay(world), TimeUnit.MILLISECONDS);
} else {
world.updateNeighborsAt(pos, newState.getBlock());
}
}
@Deprecated
public FluidState getFluidState(BlockState state) {
if (((Boolean) state.getValue(WATERLOGGED)).booleanValue() && state.getValue(FLUIDTYPE) == FluidType.water) {
return Fluids.WATER.getSource(false);
}
if (((Boolean) state.getValue(WATERLOGGED)).booleanValue() && state.getValue(FLUIDTYPE) == FluidType.lava) {
return Fluids.LAVA.getSource(false);
}
if (((Integer) state.getValue(LEVEL)).intValue() > 0 && state.getValue(FLUIDTYPE) == FluidType.water) {
return Fluids.WATER.getFlowing(((Integer) state.getValue(LEVEL)).intValue(), false);
}
if (((Integer) state.getValue(LEVEL)).intValue() > 0 && state.getValue(FLUIDTYPE) == FluidType.lava) {
return Fluids.LAVA.getFlowing(((Integer) state.getValue(LEVEL)).intValue(), false);
}
return Fluids.EMPTY.defaultFluidState();
}
public void onRemove(BlockState oldState, Level p_196243_2_, BlockPos pos, BlockState newState, boolean p_196243_5_) {
ModernLifeCommon.LOGGER.debug("Being changed to : " + newState);
if (newState.is(Blocks.WATER) || newState.is(Blocks.AIR)) {
ModernLifeCommon.LOGGER.debug("Respawn: " + oldState);
}
if (newState.is(Blocks.LAVA)) {
}
}
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
builder.add(new Property[]{AbstractPanelBlock.FACING, AbstractPanelBlock.FACE, WATERLOGGED, LEVEL, FLUIDTYPE});
}
/* renamed from: com.dairymoose.modernlife.blocks.GrateBlock$3 */
/* loaded from: outputsrg.jar:com/dairymoose/modernlife/blocks/GrateBlock$3.class */
static /* synthetic */ class C00263 {
static final /* synthetic */ int[] $SwitchMap$net$minecraft$core$Direction;
/* renamed from: $SwitchMap$net$minecraft$world$level$block$state$properties$AttachFace */
static final /* synthetic */ int[] f3x6a19ab39 = new int[AttachFace.values().length];
static {
try {
f3x6a19ab39[AttachFace.FLOOR.ordinal()] = 1;
} catch (NoSuchFieldError e) {
}
try {
f3x6a19ab39[AttachFace.WALL.ordinal()] = 2;
} catch (NoSuchFieldError e2) {
}
try {
f3x6a19ab39[AttachFace.CEILING.ordinal()] = 3;
} catch (NoSuchFieldError e3) {
}
$SwitchMap$net$minecraft$core$Direction = new int[Direction.values().length];
try {
$SwitchMap$net$minecraft$core$Direction[Direction.NORTH.ordinal()] = 1;
} catch (NoSuchFieldError e4) {
}
try {
$SwitchMap$net$minecraft$core$Direction[Direction.EAST.ordinal()] = 2;
} catch (NoSuchFieldError e5) {
}
try {
$SwitchMap$net$minecraft$core$Direction[Direction.WEST.ordinal()] = 3;
} catch (NoSuchFieldError e6) {
}
try {
$SwitchMap$net$minecraft$core$Direction[Direction.SOUTH.ordinal()] = 4;
} catch (NoSuchFieldError e7) {
}
}
}
public VoxelShape getShape(BlockState bs, BlockGetter reader, BlockPos pos, CollisionContext sel) {
switch (C00263.f3x6a19ab39[bs.getValue(AbstractPanelBlock.FACE).ordinal()]) {
case 1:
return SHAPE_FLOOR_NORTH;
case 2:
switch (C00263.$SwitchMap$net$minecraft$core$Direction[bs.getValue(AbstractPanelBlock.FACING).ordinal()]) {
case 1:
return SHAPE_WALL_NORTH;
case 2:
return SHAPE_WALL_EAST;
case 3:
return SHAPE_WALL_WEST;
case 4:
return SHAPE_WALL_SOUTH;
}
case 3:
break;
default:
return SHAPE_FLOOR_NORTH;
}
return SHAPE_CEILING_NORTH;
}
}