188 lines
7.9 KiB
Java
188 lines
7.9 KiB
Java
package net.minecraft.world.level.block;
|
|
|
|
import com.mojang.serialization.MapCodec;
|
|
import java.util.Collection;
|
|
import net.minecraft.core.BlockPos;
|
|
import net.minecraft.core.Direction;
|
|
import net.minecraft.sounds.SoundEvents;
|
|
import net.minecraft.sounds.SoundSource;
|
|
import net.minecraft.tags.BlockTags;
|
|
import net.minecraft.tags.TagKey;
|
|
import net.minecraft.util.Mth;
|
|
import net.minecraft.util.RandomSource;
|
|
import net.minecraft.world.level.BlockGetter;
|
|
import net.minecraft.world.level.LevelAccessor;
|
|
import net.minecraft.world.level.block.state.BlockBehaviour;
|
|
import net.minecraft.world.level.block.state.BlockState;
|
|
import net.minecraft.world.level.block.state.properties.BooleanProperty;
|
|
import net.minecraft.world.level.material.FluidState;
|
|
import net.minecraft.world.level.material.Fluids;
|
|
|
|
public class SculkVeinBlock extends MultifaceSpreadeableBlock implements SculkBehaviour {
|
|
public static final MapCodec<SculkVeinBlock> CODEC = simpleCodec(SculkVeinBlock::new);
|
|
private final MultifaceSpreader veinSpreader = new MultifaceSpreader(new SculkVeinBlock.SculkVeinSpreaderConfig(MultifaceSpreader.DEFAULT_SPREAD_ORDER));
|
|
private final MultifaceSpreader sameSpaceSpreader = new MultifaceSpreader(new SculkVeinBlock.SculkVeinSpreaderConfig(MultifaceSpreader.SpreadType.SAME_POSITION));
|
|
|
|
@Override
|
|
public MapCodec<SculkVeinBlock> codec() {
|
|
return CODEC;
|
|
}
|
|
|
|
public SculkVeinBlock(BlockBehaviour.Properties p_222353_) {
|
|
super(p_222353_);
|
|
}
|
|
|
|
@Override
|
|
public MultifaceSpreader getSpreader() {
|
|
return this.veinSpreader;
|
|
}
|
|
|
|
public MultifaceSpreader getSameSpaceSpreader() {
|
|
return this.sameSpaceSpreader;
|
|
}
|
|
|
|
public static boolean regrow(LevelAccessor p_222364_, BlockPos p_222365_, BlockState p_222366_, Collection<Direction> p_222367_) {
|
|
boolean flag = false;
|
|
BlockState blockstate = Blocks.SCULK_VEIN.defaultBlockState();
|
|
|
|
for (Direction direction : p_222367_) {
|
|
if (canAttachTo(p_222364_, p_222365_, direction)) {
|
|
blockstate = blockstate.setValue(getFaceProperty(direction), true);
|
|
flag = true;
|
|
}
|
|
}
|
|
|
|
if (!flag) {
|
|
return false;
|
|
} else {
|
|
if (!p_222366_.getFluidState().isEmpty()) {
|
|
blockstate = blockstate.setValue(MultifaceBlock.WATERLOGGED, true);
|
|
}
|
|
|
|
p_222364_.setBlock(p_222365_, blockstate, 3);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onDischarged(LevelAccessor p_222359_, BlockState p_222360_, BlockPos p_222361_, RandomSource p_222362_) {
|
|
if (p_222360_.is(this)) {
|
|
for (Direction direction : DIRECTIONS) {
|
|
BooleanProperty booleanproperty = getFaceProperty(direction);
|
|
if (p_222360_.getValue(booleanproperty) && p_222359_.getBlockState(p_222361_.relative(direction)).is(Blocks.SCULK)) {
|
|
p_222360_ = p_222360_.setValue(booleanproperty, false);
|
|
}
|
|
}
|
|
|
|
if (!hasAnyFace(p_222360_)) {
|
|
FluidState fluidstate = p_222359_.getFluidState(p_222361_);
|
|
p_222360_ = (fluidstate.isEmpty() ? Blocks.AIR : Blocks.WATER).defaultBlockState();
|
|
}
|
|
|
|
p_222359_.setBlock(p_222361_, p_222360_, 3);
|
|
SculkBehaviour.super.onDischarged(p_222359_, p_222360_, p_222361_, p_222362_);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public int attemptUseCharge(
|
|
SculkSpreader.ChargeCursor p_222369_, LevelAccessor p_222370_, BlockPos p_222371_, RandomSource p_222372_, SculkSpreader p_222373_, boolean p_222374_
|
|
) {
|
|
if (p_222374_ && this.attemptPlaceSculk(p_222373_, p_222370_, p_222369_.getPos(), p_222372_)) {
|
|
return p_222369_.getCharge() - 1;
|
|
} else {
|
|
return p_222372_.nextInt(p_222373_.chargeDecayRate()) == 0 ? Mth.floor(p_222369_.getCharge() * 0.5F) : p_222369_.getCharge();
|
|
}
|
|
}
|
|
|
|
private boolean attemptPlaceSculk(SculkSpreader p_222376_, LevelAccessor p_222377_, BlockPos p_222378_, RandomSource p_222379_) {
|
|
BlockState blockstate = p_222377_.getBlockState(p_222378_);
|
|
TagKey<Block> tagkey = p_222376_.replaceableBlocks();
|
|
|
|
for (Direction direction : Direction.allShuffled(p_222379_)) {
|
|
if (hasFace(blockstate, direction)) {
|
|
BlockPos blockpos = p_222378_.relative(direction);
|
|
BlockState blockstate1 = p_222377_.getBlockState(blockpos);
|
|
if (blockstate1.is(tagkey)) {
|
|
BlockState blockstate2 = Blocks.SCULK.defaultBlockState();
|
|
p_222377_.setBlock(blockpos, blockstate2, 3);
|
|
Block.pushEntitiesUp(blockstate1, blockstate2, p_222377_, blockpos);
|
|
p_222377_.playSound(null, blockpos, SoundEvents.SCULK_BLOCK_SPREAD, SoundSource.BLOCKS, 1.0F, 1.0F);
|
|
this.veinSpreader.spreadAll(blockstate2, p_222377_, blockpos, p_222376_.isWorldGeneration());
|
|
Direction direction1 = direction.getOpposite();
|
|
|
|
for (Direction direction2 : DIRECTIONS) {
|
|
if (direction2 != direction1) {
|
|
BlockPos blockpos1 = blockpos.relative(direction2);
|
|
BlockState blockstate3 = p_222377_.getBlockState(blockpos1);
|
|
if (blockstate3.is(this)) {
|
|
this.onDischarged(p_222377_, blockstate3, blockpos1, p_222379_);
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public static boolean hasSubstrateAccess(LevelAccessor p_222355_, BlockState p_222356_, BlockPos p_222357_) {
|
|
if (!p_222356_.is(Blocks.SCULK_VEIN)) {
|
|
return false;
|
|
} else {
|
|
for (Direction direction : DIRECTIONS) {
|
|
if (hasFace(p_222356_, direction) && p_222355_.getBlockState(p_222357_.relative(direction)).is(BlockTags.SCULK_REPLACEABLE)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
class SculkVeinSpreaderConfig extends MultifaceSpreader.DefaultSpreaderConfig {
|
|
private final MultifaceSpreader.SpreadType[] spreadTypes;
|
|
|
|
public SculkVeinSpreaderConfig(final MultifaceSpreader.SpreadType... p_222402_) {
|
|
super(SculkVeinBlock.this);
|
|
this.spreadTypes = p_222402_;
|
|
}
|
|
|
|
@Override
|
|
public boolean stateCanBeReplaced(BlockGetter p_222405_, BlockPos p_222406_, BlockPos p_222407_, Direction p_222408_, BlockState p_222409_) {
|
|
BlockState blockstate = p_222405_.getBlockState(p_222407_.relative(p_222408_));
|
|
if (!blockstate.is(Blocks.SCULK) && !blockstate.is(Blocks.SCULK_CATALYST) && !blockstate.is(Blocks.MOVING_PISTON)) {
|
|
if (p_222406_.distManhattan(p_222407_) == 2) {
|
|
BlockPos blockpos = p_222406_.relative(p_222408_.getOpposite());
|
|
if (p_222405_.getBlockState(blockpos).isFaceSturdy(p_222405_, blockpos, p_222408_)) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
FluidState fluidstate = p_222409_.getFluidState();
|
|
if (!fluidstate.isEmpty() && !fluidstate.is(Fluids.WATER)) {
|
|
return false;
|
|
} else {
|
|
return p_222409_.is(BlockTags.FIRE)
|
|
? false
|
|
: p_222409_.canBeReplaced() || super.stateCanBeReplaced(p_222405_, p_222406_, p_222407_, p_222408_, p_222409_);
|
|
}
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public MultifaceSpreader.SpreadType[] getSpreadTypes() {
|
|
return this.spreadTypes;
|
|
}
|
|
|
|
@Override
|
|
public boolean isOtherBlockValidAsSource(BlockState p_222411_) {
|
|
return !p_222411_.is(Blocks.SCULK_VEIN);
|
|
}
|
|
}
|
|
} |