2020-04-15 14:22:03 +02:00
|
|
|
package com.minelittlepony.unicopia.block;
|
2018-09-25 23:30:21 +02:00
|
|
|
|
|
|
|
import java.util.Random;
|
|
|
|
|
2019-02-06 11:40:23 +01:00
|
|
|
import javax.annotation.Nullable;
|
|
|
|
|
2020-04-15 14:22:03 +02:00
|
|
|
import com.minelittlepony.unicopia.item.UItems;
|
2020-01-16 12:35:46 +01:00
|
|
|
|
2020-04-15 12:37:14 +02:00
|
|
|
import net.minecraft.block.Block;
|
2020-01-16 12:35:46 +01:00
|
|
|
import net.minecraft.block.BlockState;
|
|
|
|
import net.minecraft.block.CropBlock;
|
2020-04-15 12:37:14 +02:00
|
|
|
import net.minecraft.entity.EntityContext;
|
2020-01-16 12:35:46 +01:00
|
|
|
import net.minecraft.entity.player.PlayerEntity;
|
2018-09-25 23:30:21 +02:00
|
|
|
import net.minecraft.item.Item;
|
2020-04-22 16:28:20 +02:00
|
|
|
import net.minecraft.server.world.ServerWorld;
|
|
|
|
import net.minecraft.state.StateManager;
|
2020-01-16 12:35:46 +01:00
|
|
|
import net.minecraft.state.property.EnumProperty;
|
|
|
|
import net.minecraft.state.property.IntProperty;
|
|
|
|
import net.minecraft.util.StringIdentifiable;
|
2018-09-25 23:30:21 +02:00
|
|
|
import net.minecraft.util.math.BlockPos;
|
2020-04-15 12:37:14 +02:00
|
|
|
import net.minecraft.util.math.Vec3d;
|
|
|
|
import net.minecraft.util.shape.VoxelShape;
|
|
|
|
import net.minecraft.util.shape.VoxelShapes;
|
2020-01-16 12:35:46 +01:00
|
|
|
import net.minecraft.world.BlockView;
|
2018-09-25 23:30:21 +02:00
|
|
|
import net.minecraft.world.World;
|
2020-04-22 16:28:20 +02:00
|
|
|
import net.minecraft.world.WorldView;
|
2020-01-16 12:35:46 +01:00
|
|
|
|
2020-04-15 12:37:14 +02:00
|
|
|
public class TallCropBlock extends CropBlock {
|
2020-01-16 12:35:46 +01:00
|
|
|
|
|
|
|
public static final IntProperty AGE = IntProperty.of("age", 0, 4);
|
|
|
|
public static final EnumProperty<Half> HALF = EnumProperty.of("half", Half.class);
|
|
|
|
|
2020-04-15 12:37:14 +02:00
|
|
|
private static final VoxelShape[] SHAPES = new VoxelShape[] {
|
|
|
|
Block.createCuboidShape(0, 0, 0, 16, 1.6, 16),
|
|
|
|
Block.createCuboidShape(0, 0, 0, 16, 3.2, 16),
|
|
|
|
Block.createCuboidShape(0, 0, 0, 16, 4.4, 16),
|
|
|
|
Block.createCuboidShape(0, 0, 0, 16, 9.6, 16),
|
|
|
|
Block.createCuboidShape(0, 0, 0, 16, 12.8, 16),
|
|
|
|
Block.createCuboidShape(0, 0, 0, 16, 16, 16),
|
|
|
|
Block.createCuboidShape(0, 0, 0, 16, 17.6, 16),
|
|
|
|
Block.createCuboidShape(0, 0, 0, 16, 19.2, 16),
|
|
|
|
Block.createCuboidShape(0, 0, 0, 16, 20.4, 16),
|
|
|
|
Block.createCuboidShape(0, 0, 0, 16, 25.6, 16),
|
|
|
|
Block.createCuboidShape(0, 0, 0, 16, 32, 16),
|
|
|
|
Block.createCuboidShape(0, 0, 0, 16, 33.6, 16),
|
|
|
|
Block.createCuboidShape(0, 0, 0, 16, 38.4, 16),
|
|
|
|
Block.createCuboidShape(0, 0, 0, 16, 67.6, 16),
|
|
|
|
Block.createCuboidShape(0, 0, 0, 16, 44.8, 16),
|
|
|
|
Block.createCuboidShape(0, 0, 0, 16, 48, 16)
|
2018-09-25 23:30:21 +02:00
|
|
|
};
|
|
|
|
|
2020-04-15 12:37:14 +02:00
|
|
|
public TallCropBlock(Settings settings) {
|
|
|
|
super(settings);
|
2020-01-16 12:35:46 +01:00
|
|
|
setDefaultState(getDefaultState().with(HALF, Half.BOTTOM));
|
2018-09-25 23:30:21 +02:00
|
|
|
}
|
|
|
|
|
2020-04-22 16:28:20 +02:00
|
|
|
@Override
|
|
|
|
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
|
|
|
builder.add(AGE, HALF);
|
|
|
|
}
|
|
|
|
|
2018-09-25 23:30:21 +02:00
|
|
|
@Override
|
2020-01-27 17:37:22 +01:00
|
|
|
public OffsetType getOffsetType() {
|
|
|
|
return OffsetType.XZ;
|
2018-09-25 23:30:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2020-01-16 12:35:46 +01:00
|
|
|
public IntProperty getAgeProperty() {
|
2018-09-25 23:30:21 +02:00
|
|
|
return AGE;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public int getMaxAge() {
|
2019-01-09 14:27:50 +01:00
|
|
|
return 4;
|
2018-09-25 23:30:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2020-01-16 12:35:46 +01:00
|
|
|
protected Item getSeedsItem() {
|
2018-09-25 23:30:21 +02:00
|
|
|
return UItems.alfalfa_seeds;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2020-04-22 16:28:20 +02:00
|
|
|
public void scheduledTick(BlockState state, ServerWorld world, BlockPos pos, Random rand) {
|
|
|
|
if (rand.nextInt(10) != 0 && world.isChunkLoaded(pos) && world.getLightLevel(pos.up()) >= 9) {
|
2020-04-15 12:37:14 +02:00
|
|
|
if (canGrow(world, rand, pos, state)) {
|
|
|
|
growUpwards(world, pos, state, 1);
|
2018-09-25 23:30:21 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-26 00:13:02 +02:00
|
|
|
@Override
|
2020-04-15 12:37:14 +02:00
|
|
|
protected boolean canPlantOnTop(BlockState state, BlockView view, BlockPos pos) {
|
|
|
|
return state.getBlock() == this || super.canPlantOnTop(state, view, pos);
|
2018-09-26 00:13:02 +02:00
|
|
|
}
|
|
|
|
|
2020-01-16 12:35:46 +01:00
|
|
|
protected void growUpwards(World world, BlockPos pos, BlockState state, int increase) {
|
2018-09-25 23:30:21 +02:00
|
|
|
boolean hasDown = world.getBlockState(pos.down()).getBlock() == this;
|
|
|
|
boolean hasTrunk = world.getBlockState(pos.down(2)).getBlock() == this;
|
|
|
|
boolean hasRoot = world.getBlockState(pos.down(3)).getBlock() == this;
|
|
|
|
|
2019-02-05 10:01:26 +01:00
|
|
|
if (state.getBlock() != this) {
|
2020-01-16 12:35:46 +01:00
|
|
|
if (state.isAir()) {
|
2019-02-05 10:01:26 +01:00
|
|
|
if (!(hasDown && hasTrunk && hasRoot)) {
|
2020-01-16 12:35:46 +01:00
|
|
|
world.setBlockState(pos, withAge(increase).with(HALF, Half.TOP));
|
2019-02-05 10:01:26 +01:00
|
|
|
}
|
2018-09-25 23:30:21 +02:00
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
int age = getAge(state) + increase;
|
|
|
|
int max = getMaxAge();
|
|
|
|
|
|
|
|
if (age > max) {
|
2019-01-06 22:31:34 +01:00
|
|
|
if (!(hasDown && hasTrunk)) {
|
|
|
|
growUpwards(world, pos.up(), world.getBlockState(pos.up()), age - max);
|
|
|
|
}
|
2018-09-25 23:30:21 +02:00
|
|
|
age = max;
|
|
|
|
}
|
|
|
|
|
|
|
|
boolean hasUp = world.getBlockState(pos.up()).getBlock() == this;
|
|
|
|
|
|
|
|
if (hasDown && hasUp) {
|
2020-01-16 12:35:46 +01:00
|
|
|
world.setBlockState(pos, withAge(age).with(HALF, Half.MIDDLE));
|
2018-09-25 23:30:21 +02:00
|
|
|
} else if (hasUp) {
|
2020-01-16 12:35:46 +01:00
|
|
|
world.setBlockState(pos, withAge(age).with(HALF, Half.BOTTOM));
|
2018-09-25 23:30:21 +02:00
|
|
|
} else {
|
2020-01-16 12:35:46 +01:00
|
|
|
world.setBlockState(pos, withAge(age).with(HALF, Half.TOP));
|
2018-09-25 23:30:21 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2020-04-22 16:28:20 +02:00
|
|
|
public boolean canPlaceAt(BlockState state, WorldView world, BlockPos pos) {
|
2020-04-15 12:37:14 +02:00
|
|
|
return getHalf(state) != Half.BOTTOM || super.canPlaceAt(state, world, pos);
|
2018-09-25 23:30:21 +02:00
|
|
|
}
|
|
|
|
|
2020-01-16 12:35:46 +01:00
|
|
|
public void onPlayerDestroy(World worldIn, BlockPos pos, BlockState state) {
|
2019-02-06 11:40:23 +01:00
|
|
|
breakConnectedBlocks(worldIn, pos, null);
|
|
|
|
}
|
|
|
|
|
2018-09-25 23:30:21 +02:00
|
|
|
@Override
|
2020-04-15 12:37:14 +02:00
|
|
|
public void onBreak(World worldIn, BlockPos pos, BlockState state, PlayerEntity player) {
|
2018-09-25 23:30:21 +02:00
|
|
|
breakConnectedBlocks(worldIn, pos, player);
|
|
|
|
}
|
|
|
|
|
2020-01-16 12:35:46 +01:00
|
|
|
protected void breakConnectedBlocks(World worldIn, BlockPos pos, @Nullable PlayerEntity player) {
|
|
|
|
BlockState state = worldIn.getBlockState(pos);
|
2018-09-25 23:30:21 +02:00
|
|
|
|
|
|
|
if (state.getBlock() != this) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-01-16 12:35:46 +01:00
|
|
|
worldIn.breakBlock(pos, true);
|
2018-09-25 23:30:21 +02:00
|
|
|
|
|
|
|
Half half = getHalf(state);
|
|
|
|
|
|
|
|
if (half.checkDown()) {
|
|
|
|
breakConnectedBlocks(worldIn, pos.down(), player);
|
|
|
|
}
|
|
|
|
if (half.checkUp()) {
|
|
|
|
breakConnectedBlocks(worldIn, pos.up(), player);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2020-04-15 12:37:14 +02:00
|
|
|
protected int getGrowthAmount(World world) {
|
|
|
|
return super.getGrowthAmount(world) / 2;
|
2018-09-25 23:30:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2020-04-15 12:37:14 +02:00
|
|
|
public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, EntityContext context) {
|
|
|
|
if (getHalf(state) != Half.MIDDLE) {
|
|
|
|
return VoxelShapes.empty();
|
|
|
|
}
|
|
|
|
return super.getCollisionShape(state, view, pos, context);
|
2018-09-25 23:30:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2020-04-15 12:37:14 +02:00
|
|
|
public VoxelShape getOutlineShape(BlockState state, BlockView view, BlockPos pos, EntityContext ePos) {
|
|
|
|
Vec3d offset = getOffsetPos(state, view, pos);
|
|
|
|
return SHAPES[Math.min(SHAPES.length - 1, getFullAge(view, pos))].offset(offset.x, offset.y, offset.z);
|
2018-09-25 23:30:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2020-01-16 12:35:46 +01:00
|
|
|
public boolean canGrow(World world, Random random, BlockPos pos, BlockState state) {
|
2018-09-25 23:30:21 +02:00
|
|
|
Half half = getHalf(state);
|
|
|
|
|
|
|
|
if (half == Half.MIDDLE || (half == Half.TOP && world.getBlockState(pos.down()).getBlock() == this)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-01-16 12:35:46 +01:00
|
|
|
BlockState above = world.getBlockState(pos.up(1));
|
|
|
|
BlockState higher = world.getBlockState(pos.up(2));
|
2018-09-25 23:30:21 +02:00
|
|
|
|
2020-01-27 17:37:22 +01:00
|
|
|
boolean iCanGrow = !isMature(state);
|
|
|
|
boolean aboveCanGrow = above.getBlock() != this || !isMature(above);
|
|
|
|
boolean higherCanGrow = higher.getBlock() != this || !isMature(higher);
|
2018-09-25 23:30:21 +02:00
|
|
|
|
|
|
|
return iCanGrow || aboveCanGrow || higherCanGrow;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2020-01-16 12:35:46 +01:00
|
|
|
public void applyGrowth(World world, BlockPos pos, BlockState state) {
|
2020-04-15 12:37:14 +02:00
|
|
|
growUpwards(world, pos, state, getGrowthAmount(world));
|
2018-09-25 23:30:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
protected BlockPos getTip(World world, BlockPos pos) {
|
|
|
|
BlockPos above = pos.up();
|
2020-01-16 12:35:46 +01:00
|
|
|
BlockState state = world.getBlockState(above);
|
2018-09-25 23:30:21 +02:00
|
|
|
|
|
|
|
if (state.getBlock() == this) {
|
|
|
|
return getTip(world, above);
|
|
|
|
}
|
|
|
|
|
|
|
|
return pos;
|
|
|
|
}
|
|
|
|
|
2020-01-16 12:35:46 +01:00
|
|
|
protected int getFullAge(BlockView world, BlockPos pos) {
|
|
|
|
BlockState state = world.getBlockState(pos);
|
2018-09-25 23:30:21 +02:00
|
|
|
|
|
|
|
int age = 0;
|
|
|
|
|
|
|
|
if (state.getBlock() == this) {
|
2020-01-16 12:35:46 +01:00
|
|
|
age += state.get(getAgeProperty());
|
2018-09-25 23:30:21 +02:00
|
|
|
age += getFullAge(world, pos.up());
|
|
|
|
}
|
|
|
|
|
|
|
|
return age;
|
|
|
|
}
|
|
|
|
|
2020-01-16 12:35:46 +01:00
|
|
|
protected Half getHalf(BlockState state) {
|
|
|
|
return state.get(HALF);
|
2019-01-06 22:31:34 +01:00
|
|
|
}
|
|
|
|
|
2020-01-16 12:35:46 +01:00
|
|
|
public enum Half implements StringIdentifiable {
|
2018-09-25 23:30:21 +02:00
|
|
|
TOP,
|
|
|
|
MIDDLE,
|
|
|
|
BOTTOM;
|
|
|
|
|
|
|
|
boolean checkUp() {
|
|
|
|
return this != TOP;
|
|
|
|
}
|
|
|
|
|
|
|
|
boolean checkDown() {
|
|
|
|
return this != BOTTOM;
|
|
|
|
}
|
|
|
|
|
2020-01-16 12:35:46 +01:00
|
|
|
@Override
|
2018-09-25 23:30:21 +02:00
|
|
|
public String toString() {
|
2020-04-15 12:37:14 +02:00
|
|
|
return super.toString().toLowerCase();
|
2018-09-25 23:30:21 +02:00
|
|
|
}
|
|
|
|
|
2020-01-16 12:35:46 +01:00
|
|
|
@Override
|
|
|
|
public String asString() {
|
|
|
|
return toString();
|
2018-09-25 23:30:21 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|