Unicopia/src/main/java/com/minelittlepony/unicopia/block/UFarmland.java
2019-02-06 22:25:18 +02:00

142 lines
5 KiB
Java

package com.minelittlepony.unicopia.block;
import java.util.Random;
import com.minelittlepony.util.PosHelper;
import net.minecraft.block.Block;
import net.minecraft.block.BlockFarmland;
import net.minecraft.block.SoundType;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.init.Blocks;
import net.minecraft.item.Item;
import net.minecraft.util.EnumFacing;
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;
import net.minecraftforge.common.IPlantable;
public abstract class UFarmland extends BlockFarmland {
public UFarmland(String domain, String name) {
setTranslationKey(name);
setRegistryName(domain, name);
setHardness(0.6F);
setSoundType(SoundType.GROUND);
}
@Override
public void updateTick(World world, BlockPos pos, IBlockState state, Random rand) {
int i = state.getValue(MOISTURE);
if (!hasWater(world, pos) && !world.isRainingAt(pos.up())) {
if (i > 0) {
world.setBlockState(pos, state.withProperty(MOISTURE, i - 1), 2);
} else if (!hasCrops(world, pos)) {
turnToDirt(world, pos, state);
}
} else if (i < 7) {
world.setBlockState(pos, state.withProperty(MOISTURE, 7), 2);
}
}
@Override
public void onFallenUpon(World world, BlockPos pos, Entity entity, float fallDistance) {
if (shouldTrample(world, pos, entity, fallDistance)) {
turnToDirt(world, pos, world.getBlockState(pos));
}
entity.fall(fallDistance, 1);
}
@Override
public void neighborChanged(IBlockState state, World world, BlockPos pos, Block block, BlockPos fromPos) {
if (shouldTurnToDirt(world, pos, state)) {
turnToDirt(world, pos, state);
}
}
@Override
public void onBlockAdded(World world, BlockPos pos, IBlockState state) {
if (shouldTurnToDirt(world, pos, state)) {
turnToDirt(world, pos, state);
}
}
public boolean hasCrops(World worldIn, BlockPos pos) {
Block block = worldIn.getBlockState(pos.up()).getBlock();
return block instanceof IPlantable
&& canSustainPlant(worldIn.getBlockState(pos), worldIn, pos, EnumFacing.UP, (IPlantable)block);
}
public boolean hasWater(World world, BlockPos pos) {
return PosHelper.inRegion(pos.add(-4, 0, -4), pos.add(4, 1, 4)).anyMatch(p ->
world.getBlockState(p).getMaterial() == Material.WATER
);
}
@Override
public boolean canSustainPlant(IBlockState state, IBlockAccess world, BlockPos pos, EnumFacing direction, IPlantable plantable) {
return super.canSustainPlant(state, world, pos, direction, plantable)
|| plantable.getPlantType(world, pos.offset(direction)) == EnumPlantType.Crop;
}
@Override
public Item getItemDropped(IBlockState state, Random rand, int fortune) {
IBlockState dirtState = getDroppedState(state);
return dirtState.getBlock().getItemDropped(dirtState, rand, fortune);
}
/**
* Determines if this farmland should be trampled when an entity walks on it.
*/
public boolean shouldTrample(World world, BlockPos pos, Entity entity, float fallDistance) {
return !world.isRemote && entity.canTrample(world, this, pos, fallDistance);
}
/**
* Determines if this farmland meets all the conditions for turning into dirt.
*/
public boolean shouldTurnToDirt(World world, BlockPos pos, IBlockState state) {
return world.getBlockState(pos.up()).getMaterial().isSolid();
}
/**
* Turns this farmland into dirt or its dirt equivalent.
*/
public void turnToDirt(World world, BlockPos pos, IBlockState state) {
world.setBlockState(pos, getDirtState(world, pos, state));
AxisAlignedBB bounds = getUpdateCollissionBounds(world, pos, state);
if (bounds != null) {
// Update entity positions so they don't fall through the block
for (Entity entity : world.getEntitiesWithinAABBExcludingEntity(null, bounds)) {
double offset = Math.min(bounds.maxY - bounds.minY, bounds.maxY - entity.getEntityBoundingBox().minY);
entity.setPositionAndUpdate(entity.posX, entity.posY + offset + 0.001D, entity.posZ);
}
}
}
protected AxisAlignedBB getUpdateCollissionBounds(World world, BlockPos pos, IBlockState state) {
return field_194405_c.offset(pos);
}
protected IBlockState getDroppedState(IBlockState state) {
return Blocks.DIRT.getDefaultState();
}
/**
* Gets the state used to represent this block as a piece of dirt.
*/
protected IBlockState getDirtState(World world, BlockPos pos, IBlockState state) {
return getDroppedState(state);
}
}