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

342 lines
10 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;
2018-09-25 23:30:21 +02:00
import com.minelittlepony.unicopia.UItems;
import net.minecraft.block.BlockCrops;
import net.minecraft.block.properties.PropertyEnum;
import net.minecraft.block.properties.PropertyInteger;
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
2018-09-26 20:53:35 +02:00
import net.minecraft.item.ItemStack;
2018-09-25 23:30:21 +02:00
import net.minecraft.util.IStringSerializable;
2018-09-26 20:53:35 +02:00
import net.minecraft.util.NonNullList;
2018-09-25 23:30:21 +02:00
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.common.EnumPlantType;
2018-09-25 23:30:21 +02:00
import net.minecraftforge.common.ForgeHooks;
public class BlockAlfalfa extends BlockCrops {
2019-01-09 14:27:50 +01:00
public static final PropertyInteger AGE = PropertyInteger.create("age", 0, 4);
2018-09-25 23:30:21 +02:00
public static final PropertyEnum<Half> HALF = PropertyEnum.create("half", Half.class);
private static final AxisAlignedBB[] BOUNDS = new AxisAlignedBB[] {
new AxisAlignedBB(0, 0, 0, 1, 0.1, 1),
new AxisAlignedBB(0, 0, 0, 1, 0.2, 1),
new AxisAlignedBB(0, 0, 0, 1, 0.4, 1),
new AxisAlignedBB(0, 0, 0, 1, 0.6, 1),
new AxisAlignedBB(0, 0, 0, 1, 0.8, 1),
new AxisAlignedBB(0, 0, 0, 1, 1, 1),
new AxisAlignedBB(0, 0, 0, 1, 1.2, 1),
new AxisAlignedBB(0, 0, 0, 1, 1.4, 1),
new AxisAlignedBB(0, 0, 0, 1, 1.6, 1),
new AxisAlignedBB(0, 0, 0, 1, 1.8, 1),
new AxisAlignedBB(0, 0, 0, 1, 2, 1),
new AxisAlignedBB(0, 0, 0, 1, 2.2, 1),
new AxisAlignedBB(0, 0, 0, 1, 2.4, 1),
new AxisAlignedBB(0, 0, 0, 1, 2.6, 1),
new AxisAlignedBB(0, 0, 0, 1, 2.8, 1),
new AxisAlignedBB(0, 0, 0, 1, 3, 1)
};
public BlockAlfalfa(String domain, String name) {
setRegistryName(domain, name);
setTranslationKey(name);
setDefaultState(getDefaultState().withProperty(HALF, Half.BOTTOM));
}
@Override
public EnumOffsetType getOffsetType() {
return EnumOffsetType.XZ;
}
@Override
protected PropertyInteger getAgeProperty() {
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
protected Item getSeed() {
return UItems.alfalfa_seeds;
}
@Override
protected Item getCrop() {
return UItems.alfalfa_seeds;
}
@Override
public void updateTick(World world, BlockPos pos, IBlockState state, Random rand) {
checkAndDropBlock(world, pos, state);
if (rand.nextInt(10) != 0) {
if (world.isAreaLoaded(pos, 1) && world.getLightFromNeighbors(pos.up()) >= 9) {
if (canGrow(world, pos, state, false)) {
float f = getGrowthChance(this, world, pos);
if(ForgeHooks.onCropsGrowPre(world, pos, state, rand.nextInt((int)(25 / f) + 1) == 0)) {
growUpwards(world, pos, state, 1);
ForgeHooks.onCropsGrowPost(world, pos, state, world.getBlockState(pos));
}
}
}
}
}
@Override
protected boolean canSustainBush(IBlockState state) {
return super.canSustainBush(state) || state.getBlock() == this;
}
2018-09-25 23:30:21 +02:00
protected void growUpwards(World world, BlockPos pos, IBlockState state, int increase) {
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) {
if (state.getBlock().isAir(state, world, pos)) {
if (!(hasDown && hasTrunk && hasRoot)) {
world.setBlockState(pos, withAge(increase).withProperty(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) {
world.setBlockState(pos, withAge(age).withProperty(HALF, Half.MIDDLE));
2018-09-25 23:30:21 +02:00
} else if (hasUp) {
world.setBlockState(pos, withAge(age).withProperty(HALF, Half.BOTTOM));
2018-09-25 23:30:21 +02:00
} else {
world.setBlockState(pos, withAge(age).withProperty(HALF, Half.TOP));
2018-09-25 23:30:21 +02:00
}
}
@Override
public Item getItemDropped(IBlockState state, Random rand, int fortune) {
if (state.getValue(HALF) != Half.BOTTOM) {
return Items.AIR;
}
return super.getItemDropped(state, rand, fortune);
}
2018-09-26 20:53:35 +02:00
@Override
public void getDrops(NonNullList<ItemStack> drops, IBlockAccess world, BlockPos pos, IBlockState state, int fortune) {
Random rand = world instanceof World ? ((World)world).rand : RANDOM;
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
public int quantityDropped(IBlockState state, int fortune, Random random) {
return 1;
}
2018-09-25 23:30:21 +02:00
@Override
public boolean canBlockStay(World world, BlockPos pos, IBlockState state) {
return getHalf(state) != Half.BOTTOM || super.canBlockStay(world, pos, state);
}
public void onPlayerDestroy(World worldIn, BlockPos pos, IBlockState state) {
breakConnectedBlocks(worldIn, pos, null);
}
2018-09-25 23:30:21 +02:00
@Override
public void onBlockHarvested(World worldIn, BlockPos pos, IBlockState state, EntityPlayer player) {
breakConnectedBlocks(worldIn, pos, player);
}
protected void breakConnectedBlocks(World worldIn, BlockPos pos, @Nullable EntityPlayer player) {
2018-09-25 23:30:21 +02:00
IBlockState state = worldIn.getBlockState(pos);
if (state.getBlock() != this) {
return;
}
if (player != null && player.capabilities.isCreativeMode) {
2018-09-25 23:30:21 +02:00
worldIn.setBlockToAir(pos);
} else {
if (worldIn.isRemote) {
worldIn.setBlockToAir(pos);
} else {
worldIn.destroyBlock(pos, true);
}
}
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
public boolean canCollideCheck(IBlockState state, boolean hitIfLiquid) {
return getHalf(state) != Half.MIDDLE;
}
@Deprecated
2018-09-25 23:30:21 +02:00
@Override
public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess 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
public boolean canGrow(World world, BlockPos pos, IBlockState state, boolean isClient) {
Half half = getHalf(state);
if (half == Half.MIDDLE || (half == Half.TOP && world.getBlockState(pos.down()).getBlock() == this)) {
return false;
}
IBlockState above = world.getBlockState(pos.up(1));
IBlockState higher = world.getBlockState(pos.up(2));
boolean iCanGrow = !isMaxAge(state);
boolean aboveCanGrow = above.getBlock() != this || !isMaxAge(above);
boolean higherCanGrow = higher.getBlock() != this || !isMaxAge(higher);
return iCanGrow || aboveCanGrow || higherCanGrow;
}
@Override
public void grow(World world, BlockPos pos, IBlockState state) {
growUpwards(world, pos, state, getBonemealAgeIncrease(world));
}
protected BlockPos getTip(World world, BlockPos pos) {
BlockPos above = pos.up();
IBlockState state = world.getBlockState(above);
if (state.getBlock() == this) {
return getTip(world, above);
}
return pos;
}
protected int getFullAge(IBlockAccess world, BlockPos pos) {
IBlockState state = world.getBlockState(pos);
int age = 0;
if (state.getBlock() == this) {
age += state.getValue(getAgeProperty());
age += getFullAge(world, pos.up());
}
return age;
}
protected Half getHalf(IBlockState state) {
return (Half)state.getValue(HALF);
}
@Override
public EnumPlantType getPlantType(IBlockAccess world, BlockPos pos) {
return EnumPlantType.Crop;
}
2019-01-09 14:27:50 +01:00
@Override
public IBlockState getStateFromMeta(int meta) {
int age = meta % (getMaxAge() + 1);
int half = (int)Math.floor(meta / (getMaxAge() + 1)) % Half.values().length;
return withAge(age).withProperty(HALF, Half.values()[half]);
}
// 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
public int getMetaFromState(IBlockState state) {
int age = getAge(state);
int half = getHalf(state).ordinal();
return (half * (getMaxAge() + 1)) + age;
}
2018-09-25 23:30:21 +02:00
public static enum Half implements IStringSerializable {
TOP,
MIDDLE,
BOTTOM;
boolean checkUp() {
return this != TOP;
}
boolean checkDown() {
return this != BOTTOM;
}
public String toString() {
return getName();
}
public String getName() {
return this == TOP ? "top" : this == MIDDLE ? "middle" : "bottom";
}
}
}