100 lines
		
	
	
	
		
			3.5 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			100 lines
		
	
	
	
		
			3.5 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
| 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.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 = simpleCodec(SculkBlock::new);
 | |
| 
 | |
| 	@Override
 | |
| 	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 pos, RandomSource random, SculkSpreader spreader, boolean shouldConvertBlocks
 | |
| 	) {
 | |
| 		int i = cursor.getCharge();
 | |
| 		if (i != 0 && random.nextInt(spreader.chargeDecayRate()) == 0) {
 | |
| 			BlockPos blockPos = cursor.getPos();
 | |
| 			boolean bl = blockPos.closerThan(pos, spreader.noGrowthRadius());
 | |
| 			if (!bl && canPlaceGrowth(level, blockPos)) {
 | |
| 				int j = spreader.growthSpawnCost();
 | |
| 				if (random.nextInt(j) < i) {
 | |
| 					BlockPos blockPos2 = blockPos.above();
 | |
| 					BlockState blockState = this.getRandomGrowthState(level, blockPos2, random, spreader.isWorldGeneration());
 | |
| 					level.setBlock(blockPos2, blockState, 3);
 | |
| 					level.playSound(null, blockPos, blockState.getSoundType().getPlaceSound(), SoundSource.BLOCKS, 1.0F, 1.0F);
 | |
| 				}
 | |
| 
 | |
| 				return Math.max(0, i - j);
 | |
| 			} else {
 | |
| 				return random.nextInt(spreader.additionalDecayRate()) != 0 ? i : i - (bl ? 1 : getDecayPenalty(spreader, blockPos, pos, i));
 | |
| 			}
 | |
| 		} else {
 | |
| 			return i;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	private static int getDecayPenalty(SculkSpreader spreader, BlockPos cursorPos, BlockPos rootPos, int charge) {
 | |
| 		int i = spreader.noGrowthRadius();
 | |
| 		float f = Mth.square((float)Math.sqrt(cursorPos.distSqr(rootPos)) - i);
 | |
| 		int j = Mth.square(24 - i);
 | |
| 		float g = Math.min(1.0F, f / j);
 | |
| 		return Math.max(1, (int)(charge * g * 0.5F));
 | |
| 	}
 | |
| 
 | |
| 	private BlockState getRandomGrowthState(LevelAccessor level, BlockPos pos, RandomSource random, boolean isWorldGeneration) {
 | |
| 		BlockState blockState;
 | |
| 		if (random.nextInt(11) == 0) {
 | |
| 			blockState = Blocks.SCULK_SHRIEKER.defaultBlockState().setValue(SculkShriekerBlock.CAN_SUMMON, isWorldGeneration);
 | |
| 		} else {
 | |
| 			blockState = Blocks.SCULK_SENSOR.defaultBlockState();
 | |
| 		}
 | |
| 
 | |
| 		return blockState.hasProperty(BlockStateProperties.WATERLOGGED) && !level.getFluidState(pos).isEmpty()
 | |
| 			? blockState.setValue(BlockStateProperties.WATERLOGGED, true)
 | |
| 			: blockState;
 | |
| 	}
 | |
| 
 | |
| 	private static boolean canPlaceGrowth(LevelAccessor level, BlockPos pos) {
 | |
| 		BlockState blockState = level.getBlockState(pos.above());
 | |
| 		if (blockState.isAir() || blockState.is(Blocks.WATER) && blockState.getFluidState().is(Fluids.WATER)) {
 | |
| 			int i = 0;
 | |
| 
 | |
| 			for (BlockPos blockPos : BlockPos.betweenClosed(pos.offset(-4, 0, -4), pos.offset(4, 2, 4))) {
 | |
| 				BlockState blockState2 = level.getBlockState(blockPos);
 | |
| 				if (blockState2.is(Blocks.SCULK_SENSOR) || blockState2.is(Blocks.SCULK_SHRIEKER)) {
 | |
| 					i++;
 | |
| 				}
 | |
| 
 | |
| 				if (i > 2) {
 | |
| 					return false;
 | |
| 				}
 | |
| 			}
 | |
| 
 | |
| 			return true;
 | |
| 		} else {
 | |
| 			return false;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	public boolean canChangeBlockStateOnSpread() {
 | |
| 		return false;
 | |
| 	}
 | |
| }
 |