158 lines
		
	
	
	
		
			6.1 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			158 lines
		
	
	
	
		
			6.1 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
| package net.minecraft.world.item;
 | |
| 
 | |
| import net.minecraft.core.BlockPos;
 | |
| import net.minecraft.core.Direction;
 | |
| import net.minecraft.core.Holder;
 | |
| import net.minecraft.core.particles.ParticleTypes;
 | |
| import net.minecraft.core.registries.BuiltInRegistries;
 | |
| import net.minecraft.server.level.ServerLevel;
 | |
| import net.minecraft.tags.BiomeTags;
 | |
| import net.minecraft.tags.BlockTags;
 | |
| import net.minecraft.util.ParticleUtils;
 | |
| import net.minecraft.util.RandomSource;
 | |
| import net.minecraft.world.InteractionResult;
 | |
| import net.minecraft.world.item.context.UseOnContext;
 | |
| import net.minecraft.world.level.Level;
 | |
| import net.minecraft.world.level.LevelAccessor;
 | |
| import net.minecraft.world.level.biome.Biome;
 | |
| import net.minecraft.world.level.block.BaseCoralWallFanBlock;
 | |
| import net.minecraft.world.level.block.Block;
 | |
| import net.minecraft.world.level.block.Blocks;
 | |
| import net.minecraft.world.level.block.BonemealableBlock;
 | |
| import net.minecraft.world.level.block.state.BlockState;
 | |
| import net.minecraft.world.level.gameevent.GameEvent;
 | |
| import org.jetbrains.annotations.Nullable;
 | |
| 
 | |
| public class BoneMealItem extends Item {
 | |
| 	public static final int GRASS_SPREAD_WIDTH = 3;
 | |
| 	public static final int GRASS_SPREAD_HEIGHT = 1;
 | |
| 	public static final int GRASS_COUNT_MULTIPLIER = 3;
 | |
| 
 | |
| 	public BoneMealItem(Item.Properties properties) {
 | |
| 		super(properties);
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	public InteractionResult useOn(UseOnContext context) {
 | |
| 		Level level = context.getLevel();
 | |
| 		BlockPos blockPos = context.getClickedPos();
 | |
| 		BlockPos blockPos2 = blockPos.relative(context.getClickedFace());
 | |
| 		if (growCrop(context.getItemInHand(), level, blockPos)) {
 | |
| 			if (!level.isClientSide) {
 | |
| 				context.getPlayer().gameEvent(GameEvent.ITEM_INTERACT_FINISH);
 | |
| 				level.levelEvent(1505, blockPos, 15);
 | |
| 			}
 | |
| 
 | |
| 			return InteractionResult.SUCCESS;
 | |
| 		} else {
 | |
| 			BlockState blockState = level.getBlockState(blockPos);
 | |
| 			boolean bl = blockState.isFaceSturdy(level, blockPos, context.getClickedFace());
 | |
| 			if (bl && growWaterPlant(context.getItemInHand(), level, blockPos2, context.getClickedFace())) {
 | |
| 				if (!level.isClientSide) {
 | |
| 					context.getPlayer().gameEvent(GameEvent.ITEM_INTERACT_FINISH);
 | |
| 					level.levelEvent(1505, blockPos2, 15);
 | |
| 				}
 | |
| 
 | |
| 				return InteractionResult.SUCCESS;
 | |
| 			} else {
 | |
| 				return InteractionResult.PASS;
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	public static boolean growCrop(ItemStack stack, Level level, BlockPos pos) {
 | |
| 		BlockState blockState = level.getBlockState(pos);
 | |
| 		if (blockState.getBlock() instanceof BonemealableBlock bonemealableBlock && bonemealableBlock.isValidBonemealTarget(level, pos, blockState)) {
 | |
| 			if (level instanceof ServerLevel) {
 | |
| 				if (bonemealableBlock.isBonemealSuccess(level, level.random, pos, blockState)) {
 | |
| 					bonemealableBlock.performBonemeal((ServerLevel)level, level.random, pos, blockState);
 | |
| 				}
 | |
| 
 | |
| 				stack.shrink(1);
 | |
| 			}
 | |
| 
 | |
| 			return true;
 | |
| 		} else {
 | |
| 			return false;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	public static boolean growWaterPlant(ItemStack stack, Level level, BlockPos pos, @Nullable Direction clickedSide) {
 | |
| 		if (level.getBlockState(pos).is(Blocks.WATER) && level.getFluidState(pos).getAmount() == 8) {
 | |
| 			if (!(level instanceof ServerLevel)) {
 | |
| 				return true;
 | |
| 			} else {
 | |
| 				RandomSource randomSource = level.getRandom();
 | |
| 
 | |
| 				label80:
 | |
| 				for (int i = 0; i < 128; i++) {
 | |
| 					BlockPos blockPos = pos;
 | |
| 					BlockState blockState = Blocks.SEAGRASS.defaultBlockState();
 | |
| 
 | |
| 					for (int j = 0; j < i / 16; j++) {
 | |
| 						blockPos = blockPos.offset(randomSource.nextInt(3) - 1, (randomSource.nextInt(3) - 1) * randomSource.nextInt(3) / 2, randomSource.nextInt(3) - 1);
 | |
| 						if (level.getBlockState(blockPos).isCollisionShapeFullBlock(level, blockPos)) {
 | |
| 							continue label80;
 | |
| 						}
 | |
| 					}
 | |
| 
 | |
| 					Holder<Biome> holder = level.getBiome(blockPos);
 | |
| 					if (holder.is(BiomeTags.PRODUCES_CORALS_FROM_BONEMEAL)) {
 | |
| 						if (i == 0 && clickedSide != null && clickedSide.getAxis().isHorizontal()) {
 | |
| 							blockState = (BlockState)BuiltInRegistries.BLOCK
 | |
| 								.getRandomElementOf(BlockTags.WALL_CORALS, level.random)
 | |
| 								.map(holderx -> ((Block)holderx.value()).defaultBlockState())
 | |
| 								.orElse(blockState);
 | |
| 							if (blockState.hasProperty(BaseCoralWallFanBlock.FACING)) {
 | |
| 								blockState = blockState.setValue(BaseCoralWallFanBlock.FACING, clickedSide);
 | |
| 							}
 | |
| 						} else if (randomSource.nextInt(4) == 0) {
 | |
| 							blockState = (BlockState)BuiltInRegistries.BLOCK
 | |
| 								.getRandomElementOf(BlockTags.UNDERWATER_BONEMEALS, level.random)
 | |
| 								.map(holderx -> ((Block)holderx.value()).defaultBlockState())
 | |
| 								.orElse(blockState);
 | |
| 						}
 | |
| 					}
 | |
| 
 | |
| 					if (blockState.is(BlockTags.WALL_CORALS, blockStateBase -> blockStateBase.hasProperty(BaseCoralWallFanBlock.FACING))) {
 | |
| 						for (int k = 0; !blockState.canSurvive(level, blockPos) && k < 4; k++) {
 | |
| 							blockState = blockState.setValue(BaseCoralWallFanBlock.FACING, Direction.Plane.HORIZONTAL.getRandomDirection(randomSource));
 | |
| 						}
 | |
| 					}
 | |
| 
 | |
| 					if (blockState.canSurvive(level, blockPos)) {
 | |
| 						BlockState blockState2 = level.getBlockState(blockPos);
 | |
| 						if (blockState2.is(Blocks.WATER) && level.getFluidState(blockPos).getAmount() == 8) {
 | |
| 							level.setBlock(blockPos, blockState, 3);
 | |
| 						} else if (blockState2.is(Blocks.SEAGRASS)
 | |
| 							&& ((BonemealableBlock)Blocks.SEAGRASS).isValidBonemealTarget(level, blockPos, blockState2)
 | |
| 							&& randomSource.nextInt(10) == 0) {
 | |
| 							((BonemealableBlock)Blocks.SEAGRASS).performBonemeal((ServerLevel)level, randomSource, blockPos, blockState2);
 | |
| 						}
 | |
| 					}
 | |
| 				}
 | |
| 
 | |
| 				stack.shrink(1);
 | |
| 				return true;
 | |
| 			}
 | |
| 		} else {
 | |
| 			return false;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	public static void addGrowthParticles(LevelAccessor level, BlockPos pos, int data) {
 | |
| 		BlockState blockState = level.getBlockState(pos);
 | |
| 		if (blockState.getBlock() instanceof BonemealableBlock bonemealableBlock) {
 | |
| 			BlockPos blockPos = bonemealableBlock.getParticlePos(pos);
 | |
| 			switch (bonemealableBlock.getType()) {
 | |
| 				case NEIGHBOR_SPREADER:
 | |
| 					ParticleUtils.spawnParticles(level, blockPos, data * 3, 3.0, 1.0, false, ParticleTypes.HAPPY_VILLAGER);
 | |
| 					break;
 | |
| 				case GROWER:
 | |
| 					ParticleUtils.spawnParticleInBlock(level, blockPos, data, ParticleTypes.HAPPY_VILLAGER);
 | |
| 			}
 | |
| 		} else if (blockState.is(Blocks.WATER)) {
 | |
| 			ParticleUtils.spawnParticles(level, pos, data * 3, 3.0, 1.0, false, ParticleTypes.HAPPY_VILLAGER);
 | |
| 		}
 | |
| 	}
 | |
| }
 |