Unicopia/src/main/java/com/minelittlepony/unicopia/block/TallCropBlock.java

258 lines
8.1 KiB
Java
Raw Normal View History

package com.minelittlepony.unicopia.block;
2018-09-25 23:30:21 +02:00
import java.util.Random;
import javax.annotation.Nullable;
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
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() {
2020-04-24 15:23:36 +02:00
return UItems.ALFALFA_SEEDS;
2018-09-25 23:30:21 +02:00
}
@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
}
}
}
@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);
}
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;
if (state.getBlock() != this) {
2020-01-16 12:35:46 +01:00
if (state.isAir()) {
if (!(hasDown && hasTrunk && hasRoot)) {
2020-01-16 12:35:46 +01:00
world.setBlockState(pos, withAge(increase).with(HALF, Half.TOP));
}
2018-09-25 23:30:21 +02:00
}
return;
}
int age = getAge(state) + increase;
int max = getMaxAge();
if (age > max) {
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) {
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
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);
}
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
}
}
}