2025-11-24 22:52:51 +03:00

178 lines
7.8 KiB
Java

/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* com.mojang.serialization.MapCodec
*/
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.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.MultifaceBlock;
import net.minecraft.world.level.block.MultifaceSpreadeableBlock;
import net.minecraft.world.level.block.MultifaceSpreader;
import net.minecraft.world.level.block.SculkBehaviour;
import net.minecraft.world.level.block.SculkSpreader;
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 = SculkVeinBlock.simpleCodec(SculkVeinBlock::new);
private final MultifaceSpreader veinSpreader = new MultifaceSpreader(new SculkVeinSpreaderConfig(this, MultifaceSpreader.DEFAULT_SPREAD_ORDER));
private final MultifaceSpreader sameSpaceSpreader = new MultifaceSpreader(new SculkVeinSpreaderConfig(this, MultifaceSpreader.SpreadType.SAME_POSITION));
public MapCodec<SculkVeinBlock> codec() {
return CODEC;
}
public SculkVeinBlock(BlockBehaviour.Properties properties) {
super(properties);
}
@Override
public MultifaceSpreader getSpreader() {
return this.veinSpreader;
}
public MultifaceSpreader getSameSpaceSpreader() {
return this.sameSpaceSpreader;
}
public static boolean regrow(LevelAccessor level, BlockPos pos, BlockState existing, Collection<Direction> faces) {
boolean hasAtLeastOneFace = false;
BlockState newState = Blocks.SCULK_VEIN.defaultBlockState();
for (Direction face : faces) {
if (!SculkVeinBlock.canAttachTo(level, pos, face)) continue;
newState = (BlockState)newState.setValue(SculkVeinBlock.getFaceProperty(face), true);
hasAtLeastOneFace = true;
}
if (!hasAtLeastOneFace) {
return false;
}
if (!existing.getFluidState().isEmpty()) {
newState = (BlockState)newState.setValue(MultifaceBlock.WATERLOGGED, true);
}
level.setBlock(pos, newState, 3);
return true;
}
@Override
public void onDischarged(LevelAccessor level, BlockState state, BlockPos pos, RandomSource random) {
if (!state.is(this)) {
return;
}
for (Direction dir : DIRECTIONS) {
BooleanProperty sideProperty = SculkVeinBlock.getFaceProperty(dir);
if (!state.getValue(sideProperty).booleanValue() || !level.getBlockState(pos.relative(dir)).is(Blocks.SCULK)) continue;
state = (BlockState)state.setValue(sideProperty, false);
}
if (!SculkVeinBlock.hasAnyFace(state)) {
FluidState fluidState = level.getFluidState(pos);
state = (fluidState.isEmpty() ? Blocks.AIR : Blocks.WATER).defaultBlockState();
}
level.setBlock(pos, state, 3);
SculkBehaviour.super.onDischarged(level, state, pos, random);
}
@Override
public int attemptUseCharge(SculkSpreader.ChargeCursor cursor, LevelAccessor level, BlockPos originPos, RandomSource random, SculkSpreader spreader, boolean spreadVeins) {
if (spreadVeins && this.attemptPlaceSculk(spreader, level, cursor.getPos(), random)) {
return cursor.getCharge() - 1;
}
return random.nextInt(spreader.chargeDecayRate()) == 0 ? Mth.floor((float)cursor.getCharge() * 0.5f) : cursor.getCharge();
}
private boolean attemptPlaceSculk(SculkSpreader spreader, LevelAccessor level, BlockPos pos, RandomSource random) {
BlockState state = level.getBlockState(pos);
TagKey<Block> replaceTag = spreader.replaceableBlocks();
for (Direction support : Direction.allShuffled(random)) {
BlockPos supportPos;
BlockState supportState;
if (!SculkVeinBlock.hasFace(state, support) || !(supportState = level.getBlockState(supportPos = pos.relative(support))).is(replaceTag)) continue;
BlockState defaultSculk = Blocks.SCULK.defaultBlockState();
level.setBlock(supportPos, defaultSculk, 3);
Block.pushEntitiesUp(supportState, defaultSculk, level, supportPos);
level.playSound(null, supportPos, SoundEvents.SCULK_BLOCK_SPREAD, SoundSource.BLOCKS, 1.0f, 1.0f);
this.veinSpreader.spreadAll(defaultSculk, level, supportPos, spreader.isWorldGeneration());
Direction skip = support.getOpposite();
for (Direction veinBlocks : DIRECTIONS) {
BlockPos veinPos;
BlockState possibleVeinBlock;
if (veinBlocks == skip || !(possibleVeinBlock = level.getBlockState(veinPos = supportPos.relative(veinBlocks))).is(this)) continue;
this.onDischarged(level, possibleVeinBlock, veinPos, random);
}
return true;
}
return false;
}
public static boolean hasSubstrateAccess(LevelAccessor level, BlockState state, BlockPos pos) {
if (!state.is(Blocks.SCULK_VEIN)) {
return false;
}
for (Direction direction : DIRECTIONS) {
if (!SculkVeinBlock.hasFace(state, direction) || !level.getBlockState(pos.relative(direction)).is(BlockTags.SCULK_REPLACEABLE)) continue;
return true;
}
return false;
}
private class SculkVeinSpreaderConfig
extends MultifaceSpreader.DefaultSpreaderConfig {
private final MultifaceSpreader.SpreadType[] spreadTypes;
public SculkVeinSpreaderConfig(SculkVeinBlock sculkVeinBlock, MultifaceSpreader.SpreadType ... spreadTypes) {
super(sculkVeinBlock);
this.spreadTypes = spreadTypes;
}
@Override
public boolean stateCanBeReplaced(BlockGetter level, BlockPos sourcePos, BlockPos placementPos, Direction placementDirection, BlockState existingState) {
BlockPos neighourPos;
BlockState againstState = level.getBlockState(placementPos.relative(placementDirection));
if (againstState.is(Blocks.SCULK) || againstState.is(Blocks.SCULK_CATALYST) || againstState.is(Blocks.MOVING_PISTON)) {
return false;
}
if (sourcePos.distManhattan(placementPos) == 2 && level.getBlockState(neighourPos = sourcePos.relative(placementDirection.getOpposite())).isFaceSturdy(level, neighourPos, placementDirection)) {
return false;
}
FluidState fluidState = existingState.getFluidState();
if (!fluidState.isEmpty() && !fluidState.is(Fluids.WATER)) {
return false;
}
if (existingState.is(BlockTags.FIRE)) {
return false;
}
return existingState.canBeReplaced() || super.stateCanBeReplaced(level, sourcePos, placementPos, placementDirection, existingState);
}
@Override
public MultifaceSpreader.SpreadType[] getSpreadTypes() {
return this.spreadTypes;
}
@Override
public boolean isOtherBlockValidAsSource(BlockState state) {
return !state.is(Blocks.SCULK_VEIN);
}
}
}