Code/net/minecraft/world/level/block/CropBlock.java

189 lines
7.0 KiB
Java

package net.minecraft.world.level.block;
import com.mojang.serialization.MapCodec;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.Mth;
import net.minecraft.util.RandomSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.InsideBlockEffectApplier;
import net.minecraft.world.entity.monster.Ravager;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.GameRules;
import net.minecraft.world.level.ItemLike;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.block.state.properties.IntegerProperty;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
public class CropBlock extends VegetationBlock implements BonemealableBlock {
public static final MapCodec<CropBlock> CODEC = simpleCodec(CropBlock::new);
public static final int MAX_AGE = 7;
public static final IntegerProperty AGE = BlockStateProperties.AGE_7;
private static final VoxelShape[] SHAPES = Block.boxes(7, p_397339_ -> Block.column(16.0, 0.0, 2 + p_397339_ * 2));
@Override
public MapCodec<? extends CropBlock> codec() {
return CODEC;
}
protected CropBlock(BlockBehaviour.Properties p_52247_) {
super(p_52247_);
this.registerDefaultState(this.stateDefinition.any().setValue(this.getAgeProperty(), 0));
}
@Override
protected VoxelShape getShape(BlockState p_52297_, BlockGetter p_52298_, BlockPos p_52299_, CollisionContext p_52300_) {
return SHAPES[this.getAge(p_52297_)];
}
@Override
protected boolean mayPlaceOn(BlockState p_52302_, BlockGetter p_52303_, BlockPos p_52304_) {
return p_52302_.is(Blocks.FARMLAND);
}
protected IntegerProperty getAgeProperty() {
return AGE;
}
public int getMaxAge() {
return 7;
}
public int getAge(BlockState p_52306_) {
return p_52306_.getValue(this.getAgeProperty());
}
public BlockState getStateForAge(int p_52290_) {
return this.defaultBlockState().setValue(this.getAgeProperty(), p_52290_);
}
public final boolean isMaxAge(BlockState p_52308_) {
return this.getAge(p_52308_) >= this.getMaxAge();
}
@Override
protected boolean isRandomlyTicking(BlockState p_52288_) {
return !this.isMaxAge(p_52288_);
}
@Override
protected void randomTick(BlockState p_221050_, ServerLevel p_221051_, BlockPos p_221052_, RandomSource p_221053_) {
if (p_221051_.getRawBrightness(p_221052_, 0) >= 9) {
int i = this.getAge(p_221050_);
if (i < this.getMaxAge()) {
float f = getGrowthSpeed(this, p_221051_, p_221052_);
if (p_221053_.nextInt((int)(25.0F / f) + 1) == 0) {
p_221051_.setBlock(p_221052_, this.getStateForAge(i + 1), 2);
}
}
}
}
public void growCrops(Level p_52264_, BlockPos p_52265_, BlockState p_52266_) {
int i = Math.min(this.getMaxAge(), this.getAge(p_52266_) + this.getBonemealAgeIncrease(p_52264_));
p_52264_.setBlock(p_52265_, this.getStateForAge(i), 2);
}
protected int getBonemealAgeIncrease(Level p_52262_) {
return Mth.nextInt(p_52262_.random, 2, 5);
}
protected static float getGrowthSpeed(Block p_52273_, BlockGetter p_52274_, BlockPos p_52275_) {
float f = 1.0F;
BlockPos blockpos = p_52275_.below();
for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
float f1 = 0.0F;
BlockState blockstate = p_52274_.getBlockState(blockpos.offset(i, 0, j));
if (blockstate.is(Blocks.FARMLAND)) {
f1 = 1.0F;
if (blockstate.getValue(FarmBlock.MOISTURE) > 0) {
f1 = 3.0F;
}
}
if (i != 0 || j != 0) {
f1 /= 4.0F;
}
f += f1;
}
}
BlockPos blockpos1 = p_52275_.north();
BlockPos blockpos2 = p_52275_.south();
BlockPos blockpos3 = p_52275_.west();
BlockPos blockpos4 = p_52275_.east();
boolean flag = p_52274_.getBlockState(blockpos3).is(p_52273_) || p_52274_.getBlockState(blockpos4).is(p_52273_);
boolean flag1 = p_52274_.getBlockState(blockpos1).is(p_52273_) || p_52274_.getBlockState(blockpos2).is(p_52273_);
if (flag && flag1) {
f /= 2.0F;
} else {
boolean flag2 = p_52274_.getBlockState(blockpos3.north()).is(p_52273_)
|| p_52274_.getBlockState(blockpos4.north()).is(p_52273_)
|| p_52274_.getBlockState(blockpos4.south()).is(p_52273_)
|| p_52274_.getBlockState(blockpos3.south()).is(p_52273_);
if (flag2) {
f /= 2.0F;
}
}
return f;
}
@Override
protected boolean canSurvive(BlockState p_52282_, LevelReader p_52283_, BlockPos p_52284_) {
return hasSufficientLight(p_52283_, p_52284_) && super.canSurvive(p_52282_, p_52283_, p_52284_);
}
protected static boolean hasSufficientLight(LevelReader p_300321_, BlockPos p_300219_) {
return p_300321_.getRawBrightness(p_300219_, 0) >= 8;
}
@Override
protected void entityInside(BlockState p_52277_, Level p_52278_, BlockPos p_52279_, Entity p_52280_, InsideBlockEffectApplier p_391246_) {
if (p_52278_ instanceof ServerLevel serverlevel && p_52280_ instanceof Ravager && serverlevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) {
serverlevel.destroyBlock(p_52279_, true, p_52280_);
}
super.entityInside(p_52277_, p_52278_, p_52279_, p_52280_, p_391246_);
}
protected ItemLike getBaseSeedId() {
return Items.WHEAT_SEEDS;
}
@Override
protected ItemStack getCloneItemStack(LevelReader p_310461_, BlockPos p_52255_, BlockState p_52256_, boolean p_377901_) {
return new ItemStack(this.getBaseSeedId());
}
@Override
public boolean isValidBonemealTarget(LevelReader p_255715_, BlockPos p_52259_, BlockState p_52260_) {
return !this.isMaxAge(p_52260_);
}
@Override
public boolean isBonemealSuccess(Level p_221045_, RandomSource p_221046_, BlockPos p_221047_, BlockState p_221048_) {
return true;
}
@Override
public void performBonemeal(ServerLevel p_221040_, RandomSource p_221041_, BlockPos p_221042_, BlockState p_221043_) {
this.growCrops(p_221040_, p_221042_, p_221043_);
}
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> p_52286_) {
p_52286_.add(AGE);
}
}