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

320 lines
9.2 KiB
Java
Raw Normal View History

2018-09-25 23:30:21 +02:00
package com.minelittlepony.unicopia.block;
import java.util.Random;
import javax.annotation.Nullable;
2020-01-16 12:35:46 +01:00
import com.minelittlepony.unicopia.UItems;
import net.minecraft.block.BlockState;
import net.minecraft.block.CropBlock;
import net.minecraft.entity.player.PlayerEntity;
2018-09-25 23:30:21 +02:00
import net.minecraft.item.Item;
2018-09-26 20:53:35 +02:00
import net.minecraft.item.ItemStack;
2020-01-16 12:35:46 +01:00
import net.minecraft.item.Items;
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-01-16 12:35:46 +01:00
import net.minecraft.util.math.Box;
import net.minecraft.world.BlockView;
2018-09-25 23:30:21 +02:00
import net.minecraft.world.World;
2020-01-16 12:35:46 +01:00
public class BlockAlfalfa extends CropBlock {
public static final IntProperty AGE = IntProperty.of("age", 0, 4);
public static final EnumProperty<Half> HALF = EnumProperty.of("half", Half.class);
private static final Box[] BOUNDS = new Box[] {
new Box(0, 0, 0, 1, 0.1, 1),
new Box(0, 0, 0, 1, 0.2, 1),
new Box(0, 0, 0, 1, 0.4, 1),
new Box(0, 0, 0, 1, 0.6, 1),
new Box(0, 0, 0, 1, 0.8, 1),
new Box(0, 0, 0, 1, 1, 1),
new Box(0, 0, 0, 1, 1.2, 1),
new Box(0, 0, 0, 1, 1.4, 1),
new Box(0, 0, 0, 1, 1.6, 1),
new Box(0, 0, 0, 1, 1.8, 1),
new Box(0, 0, 0, 1, 2, 1),
new Box(0, 0, 0, 1, 2.2, 1),
new Box(0, 0, 0, 1, 2.4, 1),
new Box(0, 0, 0, 1, 2.6, 1),
new Box(0, 0, 0, 1, 2.8, 1),
new Box(0, 0, 0, 1, 3, 1)
2018-09-25 23:30:21 +02:00
};
public BlockAlfalfa(String domain, String name) {
setRegistryName(domain, name);
setTranslationKey(name);
2020-01-16 12:35:46 +01:00
setDefaultState(getDefaultState().with(HALF, Half.BOTTOM));
2018-09-25 23:30:21 +02:00
}
@Override
public EnumOffsetType getOffsetType() {
return EnumOffsetType.XZ;
}
@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
protected Item getCrop() {
return UItems.alfalfa_seeds;
}
@Override
2020-01-16 12:35:46 +01:00
public void onScheduledTick(BlockState state, World world, BlockPos pos, Random rand) {
2018-09-25 23:30:21 +02:00
checkAndDropBlock(world, pos, state);
if (rand.nextInt(10) != 0) {
2020-01-16 12:35:46 +01:00
if (world.isBlockLoaded(pos) && world.getLightLevel(pos.up()) >= 9) {
if (canGrow(world, rand, pos, state)) {
growUpwards(world, pos, state, 1);
2018-09-25 23:30:21 +02:00
}
}
}
}
@Override
2020-01-16 12:35:46 +01:00
protected boolean canSustainBush(BlockState state) {
return super.canSustainBush(state) || state.getBlock() == this;
}
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-01-16 12:35:46 +01:00
public Item getItemDropped(BlockState state, Random rand, int fortune) {
if (state.get(HALF) != Half.BOTTOM) {
2018-09-25 23:30:21 +02:00
return Items.AIR;
}
return super.getItemDropped(state, rand, fortune);
}
2018-09-26 20:53:35 +02:00
@Override
2020-01-16 12:35:46 +01:00
public void getDrops(NonNullList<ItemStack> drops, BlockView world, BlockPos pos, BlockState state, int fortune) {
Random rand = world instanceof World ? ((World)world).random : RANDOM;
2018-09-26 20:53:35 +02:00
Item item = getItemDropped(state, rand, fortune);
if (item != Items.AIR) {
drops.add(new ItemStack(item, getFullAge(world, pos), damageDropped(state)));
if (isMaxAge(state)) {
drops.add(new ItemStack(UItems.alfalfa_leaves, rand.nextInt(10)));
}
}
}
@Override
2020-01-16 12:35:46 +01:00
public int quantityDropped(BlockState state, int fortune, Random random) {
2018-09-26 20:53:35 +02:00
return 1;
}
2018-09-25 23:30:21 +02:00
@Override
2020-01-16 12:35:46 +01:00
public boolean canBlockStay(World world, BlockPos pos, BlockState state) {
2018-09-25 23:30:21 +02:00
return getHalf(state) != Half.BOTTOM || super.canBlockStay(world, pos, state);
}
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-01-16 12:35:46 +01:00
public void onBlockHarvested(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
protected int getBonemealAgeIncrease(World world) {
return super.getBonemealAgeIncrease(world) / 2;
}
@Override
protected BlockStateContainer createBlockState() {
return new BlockStateContainer(this, HALF, AGE);
}
@Override
2020-01-16 12:35:46 +01:00
public boolean canCollideCheck(BlockState state, boolean hitIfLiquid) {
2018-09-25 23:30:21 +02:00
return getHalf(state) != Half.MIDDLE;
}
@Override
2020-01-16 12:35:46 +01:00
public Box getBoundingBox(BlockState state, BlockView source, BlockPos pos) {
return BOUNDS[Math.min(BOUNDS.length - 1, getFullAge(source, pos))].offset(getOffset(state, source, pos));
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 = !isMaxAge(state);
boolean aboveCanGrow = above.getBlock() != this || !isMaxAge(above);
boolean higherCanGrow = higher.getBlock() != this || !isMaxAge(higher);
return iCanGrow || aboveCanGrow || higherCanGrow;
}
@Override
2020-01-16 12:35:46 +01:00
public void applyGrowth(World world, BlockPos pos, BlockState state) {
2018-09-25 23:30:21 +02:00
growUpwards(world, pos, state, getBonemealAgeIncrease(world));
}
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-09 14:27:50 +01:00
@Override
2020-01-16 12:35:46 +01:00
public BlockState getStateFromMeta(int meta) {
2019-01-09 14:27:50 +01:00
int age = meta % (getMaxAge() + 1);
int half = (int)Math.floor(meta / (getMaxAge() + 1)) % Half.values().length;
2020-01-16 12:35:46 +01:00
return withAge(age).with(HALF, Half.values()[half]);
2019-01-09 14:27:50 +01:00
}
// 0: age:0, half:0
// 1: age:1, half:0
// 2: age:2, half:0
// 3: age:3, half:0
// 4: age:4, half:0
// 5: age:0, half:1
// 6: age:1, half:1
// 7: age:2, half:1
// 8: age:3, half:1
// 9: age:4, half:1
//10: age:0, half:2
//11: age:1, half:2
//12: age:2, half:2
//13: age:3, half:2
//14: age:4, half:2
@Override
2020-01-16 12:35:46 +01:00
public int getMetaFromState(BlockState state) {
2019-01-09 14:27:50 +01:00
int age = getAge(state);
int half = getHalf(state).ordinal();
return (half * (getMaxAge() + 1)) + age;
}
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-01-16 12:35:46 +01:00
return this == TOP ? "top" : this == MIDDLE ? "middle" : "bottom";
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
}
}
}