package com.bioxx.tfc2.blocks; import java.util.Random; import net.minecraft.block.Block; import net.minecraft.block.BlockFalling; import net.minecraft.block.material.Material; import net.minecraft.block.properties.PropertyHelper; import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; import net.minecraft.util.EnumFacing; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import com.bioxx.jmapgen.RandomCollection; import com.bioxx.tfc2.api.interfaces.IGravityBlock; import com.bioxx.tfc2.entity.EntityFallingBlockTFC; public class BlockGravity extends BlockTerra implements IGravityBlock { public BlockGravity(Material m, PropertyHelper p) { super(m, p); } @Override public void onBlockAdded(World worldIn, BlockPos pos, IBlockState state) { worldIn.scheduleUpdate(pos, this, tickRate(worldIn)); } @Override public void neighborChanged(IBlockState state, World world, BlockPos pos, Block blockIn) { world.scheduleUpdate(pos, this, tickRate(world)); } @Override public void updateTick(World worldIn, BlockPos pos, IBlockState state, Random rand) { if (!worldIn.isRemote) { checkFallable(worldIn, pos, state); } } protected void checkFallable(World worldIn, BlockPos pos, IBlockState state) { BlockPos slidePos = slideScan(worldIn, pos); if ((canFallInto(worldIn, pos.down())) && (pos.getY() >= 0)) { fall(worldIn, pos, state); } else if(slidePos != null && (slidePos.getY() >= 0)) { worldIn.setBlockToAir(pos); fall(worldIn, slidePos, state); } } protected void fall(World worldIn, BlockPos pos, IBlockState state) { int i = 32; if ((!BlockFalling.fallInstantly) && (worldIn.isAreaLoaded(pos.add(-i, -i, -i), pos.add(i, i, i)))) { if (!worldIn.isRemote) { EntityFallingBlockTFC entityfallingblock = new EntityFallingBlockTFC(worldIn, pos.getX() + 0.5D, pos.getY(), pos.getZ() + 0.5D, state); onStartFalling(entityfallingblock); worldIn.spawnEntityInWorld(entityfallingblock); } } else { worldIn.setBlockToAir(pos); BlockPos blockpos; for (blockpos = pos.down(); (canFallInto(worldIn, blockpos)) && (blockpos.getY() > 0); blockpos = blockpos.down()) {} if (blockpos.getY() > 0) { worldIn.setBlockState(blockpos.up(), getDefaultState()); } } } @Override public void onStartFalling(EntityFallingBlockTFC fallingEntity) {} @Override public int tickRate(World worldIn) { return 5; } @Override public boolean canFallInto(World worldIn, BlockPos pos) { if (worldIn.isAirBlock(pos)) return true; Block block = worldIn.getBlockState(pos).getBlock(); Material material = block.getMaterial(worldIn.getBlockState(pos)); return (block == Blocks.FIRE) || (material == Material.AIR) || (material == Material.WATER) || (material == Material.LAVA) || block.isReplaceable(worldIn, pos); } @Override public void onEndFalling(World worldIn, BlockPos pos) {} /** * @return Minimum cliffheight required for this block to slide down to lower elevation. -1 disables sliding */ @Override public int getSlideHeight() { return -1; } /** * @return Chance that a block will slide [0.0 - 1.0] */ @Override public float getSlideChance() { return 0f; } protected BlockPos slideScan(World world, BlockPos pos) { if(pos.getY() == 0) return null; if(world.rand.nextFloat() < 1 - getSlideChance()) return null; if(getSlideHeight() == -1) return null; else { RandomCollection<BlockPos> pot = new RandomCollection<BlockPos>(); if(!world.isSideSolid(pos.east(), EnumFacing.WEST) && depthScan(world, pos.east()) >= getSlideHeight()) pot.add(1.0, pos.east()); if(!world.isSideSolid(pos.west(), EnumFacing.EAST) && depthScan(world, pos.west()) >= getSlideHeight()) pot.add(1.0, pos.west()); if(!world.isSideSolid(pos.north(), EnumFacing.SOUTH) && depthScan(world, pos.north()) >= getSlideHeight()) pot.add(1.0, pos.north()); if(!world.isSideSolid(pos.south(), EnumFacing.NORTH) && depthScan(world, pos.south()) >= getSlideHeight()) pot.add(1.0, pos.south()); if(pot.size() > 0) return pot.next(); } return null; } private int depthScan(World world, BlockPos pos) { BlockPos scanPos; for(int i = 1; i < 255;i++) { scanPos = pos.down(i); if(!canFallInto(world, scanPos)) return i-1; } return 0; } }