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

102 lines
4.5 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 net.minecraft.core.BlockPos;
import net.minecraft.sounds.SoundSource;
import net.minecraft.util.Mth;
import net.minecraft.util.RandomSource;
import net.minecraft.util.valueproviders.ConstantInt;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.DropExperienceBlock;
import net.minecraft.world.level.block.SculkBehaviour;
import net.minecraft.world.level.block.SculkShriekerBlock;
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.BlockStateProperties;
import net.minecraft.world.level.material.Fluids;
public class SculkBlock
extends DropExperienceBlock
implements SculkBehaviour {
public static final MapCodec<SculkBlock> CODEC = SculkBlock.simpleCodec(SculkBlock::new);
public MapCodec<SculkBlock> codec() {
return CODEC;
}
public SculkBlock(BlockBehaviour.Properties properties) {
super(ConstantInt.of(1), properties);
}
@Override
public int attemptUseCharge(SculkSpreader.ChargeCursor cursor, LevelAccessor level, BlockPos originPos, RandomSource random, SculkSpreader spreader, boolean spreadVein) {
int charge = cursor.getCharge();
if (charge == 0 || random.nextInt(spreader.chargeDecayRate()) != 0) {
return charge;
}
BlockPos chargePos = cursor.getPos();
boolean isCloseToCatalyst = chargePos.closerThan(originPos, spreader.noGrowthRadius());
if (isCloseToCatalyst || !SculkBlock.canPlaceGrowth(level, chargePos)) {
if (random.nextInt(spreader.additionalDecayRate()) != 0) {
return charge;
}
return charge - (isCloseToCatalyst ? 1 : SculkBlock.getDecayPenalty(spreader, chargePos, originPos, charge));
}
int xpPerGrowthSpawn = spreader.growthSpawnCost();
if (random.nextInt(xpPerGrowthSpawn) < charge) {
BlockPos growthPlacement = chargePos.above();
BlockState growthState = this.getRandomGrowthState(level, growthPlacement, random, spreader.isWorldGeneration());
level.setBlock(growthPlacement, growthState, 3);
level.playSound(null, chargePos, growthState.getSoundType().getPlaceSound(), SoundSource.BLOCKS, 1.0f, 1.0f);
}
return Math.max(0, charge - xpPerGrowthSpawn);
}
private static int getDecayPenalty(SculkSpreader spreader, BlockPos pos, BlockPos originPos, int charge) {
int noGrowthRadius = spreader.noGrowthRadius();
float outerDistanceSquared = Mth.square((float)Math.sqrt(pos.distSqr(originPos)) - (float)noGrowthRadius);
int maxReachSquared = Mth.square(24 - noGrowthRadius);
float distanceFactor = Math.min(1.0f, outerDistanceSquared / (float)maxReachSquared);
return Math.max(1, (int)((float)charge * distanceFactor * 0.5f));
}
private BlockState getRandomGrowthState(LevelAccessor level, BlockPos pos, RandomSource random, boolean isWorldGen) {
BlockState state = random.nextInt(11) == 0 ? (BlockState)Blocks.SCULK_SHRIEKER.defaultBlockState().setValue(SculkShriekerBlock.CAN_SUMMON, isWorldGen) : Blocks.SCULK_SENSOR.defaultBlockState();
if (state.hasProperty(BlockStateProperties.WATERLOGGED) && !level.getFluidState(pos).isEmpty()) {
return (BlockState)state.setValue(BlockStateProperties.WATERLOGGED, true);
}
return state;
}
private static boolean canPlaceGrowth(LevelAccessor level, BlockPos pos) {
BlockState stateAbove = level.getBlockState(pos.above());
if (!(stateAbove.isAir() || stateAbove.is(Blocks.WATER) && stateAbove.getFluidState().is(Fluids.WATER))) {
return false;
}
int growthCount = 0;
for (BlockPos blockPos : BlockPos.betweenClosed(pos.offset(-4, 0, -4), pos.offset(4, 2, 4))) {
BlockState state = level.getBlockState(blockPos);
if (state.is(Blocks.SCULK_SENSOR) || state.is(Blocks.SCULK_SHRIEKER)) {
++growthCount;
}
if (growthCount <= 2) continue;
return false;
}
return true;
}
@Override
public boolean canChangeBlockStateOnSpread() {
return false;
}
}