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

181 lines
7.8 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 java.util.Optional;
import javax.annotation.Nullable;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.util.RandomSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.InsideBlockEffectApplier;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
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.ScheduledTickAccess;
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.material.FluidState;
import net.minecraft.world.level.material.Fluids;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape;
public class BubbleColumnBlock extends Block implements BucketPickup {
public static final MapCodec<BubbleColumnBlock> CODEC = simpleCodec(BubbleColumnBlock::new);
public static final BooleanProperty DRAG_DOWN = BlockStateProperties.DRAG;
private static final int CHECK_PERIOD = 5;
@Override
public MapCodec<BubbleColumnBlock> codec() {
return CODEC;
}
public BubbleColumnBlock(BlockBehaviour.Properties p_50959_) {
super(p_50959_);
this.registerDefaultState(this.stateDefinition.any().setValue(DRAG_DOWN, true));
}
@Override
protected void entityInside(BlockState p_50976_, Level p_50977_, BlockPos p_50978_, Entity p_50979_, InsideBlockEffectApplier p_395598_) {
BlockState blockstate = p_50977_.getBlockState(p_50978_.above());
boolean flag = blockstate.getCollisionShape(p_50977_, p_50978_).isEmpty() && blockstate.getFluidState().isEmpty();
if (flag) {
p_50979_.onAboveBubbleColumn(p_50976_.getValue(DRAG_DOWN), p_50978_);
} else {
p_50979_.onInsideBubbleColumn(p_50976_.getValue(DRAG_DOWN));
}
}
@Override
protected void tick(BlockState p_220888_, ServerLevel p_220889_, BlockPos p_220890_, RandomSource p_220891_) {
updateColumn(p_220889_, p_220890_, p_220888_, p_220889_.getBlockState(p_220890_.below()));
}
@Override
protected FluidState getFluidState(BlockState p_51016_) {
return Fluids.WATER.getSource(false);
}
public static void updateColumn(LevelAccessor p_152708_, BlockPos p_152709_, BlockState p_152710_) {
updateColumn(p_152708_, p_152709_, p_152708_.getBlockState(p_152709_), p_152710_);
}
public static void updateColumn(LevelAccessor p_152703_, BlockPos p_152704_, BlockState p_152705_, BlockState p_152706_) {
if (canExistIn(p_152705_)) {
BlockState blockstate = getColumnState(p_152706_);
p_152703_.setBlock(p_152704_, blockstate, 2);
BlockPos.MutableBlockPos blockpos$mutableblockpos = p_152704_.mutable().move(Direction.UP);
while (canExistIn(p_152703_.getBlockState(blockpos$mutableblockpos))) {
if (!p_152703_.setBlock(blockpos$mutableblockpos, blockstate, 2)) {
return;
}
blockpos$mutableblockpos.move(Direction.UP);
}
}
}
private static boolean canExistIn(BlockState p_152716_) {
return p_152716_.is(Blocks.BUBBLE_COLUMN)
|| p_152716_.is(Blocks.WATER) && p_152716_.getFluidState().getAmount() >= 8 && p_152716_.getFluidState().isSource();
}
private static BlockState getColumnState(BlockState p_152718_) {
if (p_152718_.is(Blocks.BUBBLE_COLUMN)) {
return p_152718_;
} else if (p_152718_.is(Blocks.SOUL_SAND)) {
return Blocks.BUBBLE_COLUMN.defaultBlockState().setValue(DRAG_DOWN, false);
} else {
return p_152718_.is(Blocks.MAGMA_BLOCK) ? Blocks.BUBBLE_COLUMN.defaultBlockState().setValue(DRAG_DOWN, true) : Blocks.WATER.defaultBlockState();
}
}
@Override
public void animateTick(BlockState p_220893_, Level p_220894_, BlockPos p_220895_, RandomSource p_220896_) {
double d0 = p_220895_.getX();
double d1 = p_220895_.getY();
double d2 = p_220895_.getZ();
if (p_220893_.getValue(DRAG_DOWN)) {
p_220894_.addAlwaysVisibleParticle(ParticleTypes.CURRENT_DOWN, d0 + 0.5, d1 + 0.8, d2, 0.0, 0.0, 0.0);
if (p_220896_.nextInt(200) == 0) {
p_220894_.playLocalSound(
d0, d1, d2, SoundEvents.BUBBLE_COLUMN_WHIRLPOOL_AMBIENT, SoundSource.BLOCKS, 0.2F + p_220896_.nextFloat() * 0.2F, 0.9F + p_220896_.nextFloat() * 0.15F, false
);
}
} else {
p_220894_.addAlwaysVisibleParticle(ParticleTypes.BUBBLE_COLUMN_UP, d0 + 0.5, d1, d2 + 0.5, 0.0, 0.04, 0.0);
p_220894_.addAlwaysVisibleParticle(ParticleTypes.BUBBLE_COLUMN_UP, d0 + p_220896_.nextFloat(), d1 + p_220896_.nextFloat(), d2 + p_220896_.nextFloat(), 0.0, 0.04, 0.0);
if (p_220896_.nextInt(200) == 0) {
p_220894_.playLocalSound(
d0, d1, d2, SoundEvents.BUBBLE_COLUMN_UPWARDS_AMBIENT, SoundSource.BLOCKS, 0.2F + p_220896_.nextFloat() * 0.2F, 0.9F + p_220896_.nextFloat() * 0.15F, false
);
}
}
}
@Override
protected BlockState updateShape(
BlockState p_50990_,
LevelReader p_366024_,
ScheduledTickAccess p_365544_,
BlockPos p_50994_,
Direction p_50991_,
BlockPos p_50995_,
BlockState p_50992_,
RandomSource p_363879_
) {
p_365544_.scheduleTick(p_50994_, Fluids.WATER, Fluids.WATER.getTickDelay(p_366024_));
if (!p_50990_.canSurvive(p_366024_, p_50994_)
|| p_50991_ == Direction.DOWN
|| p_50991_ == Direction.UP && !p_50992_.is(Blocks.BUBBLE_COLUMN) && canExistIn(p_50992_)) {
p_365544_.scheduleTick(p_50994_, this, 5);
}
return super.updateShape(p_50990_, p_366024_, p_365544_, p_50994_, p_50991_, p_50995_, p_50992_, p_363879_);
}
@Override
protected boolean canSurvive(BlockState p_50986_, LevelReader p_50987_, BlockPos p_50988_) {
BlockState blockstate = p_50987_.getBlockState(p_50988_.below());
return blockstate.is(Blocks.BUBBLE_COLUMN) || blockstate.is(Blocks.MAGMA_BLOCK) || blockstate.is(Blocks.SOUL_SAND);
}
@Override
protected VoxelShape getShape(BlockState p_51005_, BlockGetter p_51006_, BlockPos p_51007_, CollisionContext p_51008_) {
return Shapes.empty();
}
@Override
protected RenderShape getRenderShape(BlockState p_51003_) {
return RenderShape.INVISIBLE;
}
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> p_50997_) {
p_50997_.add(DRAG_DOWN);
}
@Override
public ItemStack pickupBlock(@Nullable LivingEntity p_392392_, LevelAccessor p_152712_, BlockPos p_152713_, BlockState p_152714_) {
p_152712_.setBlock(p_152713_, Blocks.AIR.defaultBlockState(), 11);
return new ItemStack(Items.WATER_BUCKET);
}
@Override
public Optional<SoundEvent> getPickupSound() {
return Fluids.WATER.getPickupSound();
}
}