2018-09-25 23:30:21 +02:00
|
|
|
package com.minelittlepony.unicopia.block;
|
|
|
|
|
|
|
|
import java.util.Random;
|
|
|
|
|
2019-02-06 11:40:23 +01:00
|
|
|
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
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-26 00:13:02 +02:00
|
|
|
@Override
|
2020-01-16 12:35:46 +01:00
|
|
|
protected boolean canSustainBush(BlockState state) {
|
2018-09-26 00:13:02 +02:00
|
|
|
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;
|
|
|
|
|
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-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) {
|
2019-02-06 11:40:23 +01:00
|
|
|
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) {
|
2019-01-10 09:24:19 +01:00
|
|
|
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-06 22:31:34 +01:00
|
|
|
}
|
|
|
|
|
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
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|