package blusunrize.immersiveengineering.common.blocks; import blusunrize.immersiveengineering.api.IEProperties; import blusunrize.immersiveengineering.common.IEContent; import blusunrize.immersiveengineering.common.blocks.stone.BlockTypes_StoneDecoration; import blusunrize.immersiveengineering.common.blocks.stone.BlockTypes_StoneDevices; import blusunrize.immersiveengineering.common.util.IEPotions; import net.minecraft.block.material.Material; import net.minecraft.block.properties.IProperty; import net.minecraft.block.state.BlockStateContainer; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.EntityLivingBase; import net.minecraft.potion.PotionEffect; import net.minecraft.util.EnumFacing; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraftforge.common.property.ExtendedBlockState; import net.minecraftforge.common.property.IUnlistedProperty; import net.minecraftforge.event.ForgeEventFactory; import net.minecraftforge.fluids.Fluid; import java.util.Random; /** * @author BluSunrize - 22.01.2017 */ public class BlockIEFluidConcrete extends BlockIEFluid { public BlockIEFluidConcrete(String name, Fluid fluid, Material material) { super(name, fluid, material); this.setQuantaPerBlock(16); } @Override protected BlockStateContainer createBlockState() { return new ExtendedBlockState(this, new IProperty[] { LEVEL, IEProperties.INT_16}, FLUID_RENDER_PROPS.toArray(new IUnlistedProperty<?>[0])); } @Override public void updateTick(World world, BlockPos pos, IBlockState state, Random rand) { if(!isSourceBlock(world, pos) && ForgeEventFactory.canCreateFluidSource(world, pos, state, false)) { int adjacentSourceBlocks = (isSourceBlock(world, pos.north()) ? 1 : 0) + (isSourceBlock(world, pos.south()) ? 1 : 0) + (isSourceBlock(world, pos.east()) ? 1 : 0) + (isSourceBlock(world, pos.west()) ? 1 : 0); if(adjacentSourceBlocks >= 2 && (world.getBlockState(pos.up(densityDir)).getMaterial().isSolid() || isSourceBlock(world, pos.up(densityDir)))) world.setBlockState(pos, state.withProperty(LEVEL, 0)); } int level = state.getValue(LEVEL); int timer = state.getValue(IEProperties.INT_16); int quantaRemaining = quantaPerBlock - level; int expQuanta = -101; if(timer>=Math.min(14,quantaRemaining)) { IBlockState solidState; if(level>=14) solidState = IEContent.blockStoneDevice.getStateFromMeta(BlockTypes_StoneDevices.CONCRETE_SHEET.getMeta()); else if(level>=10) solidState = IEContent.blockStoneDevice.getStateFromMeta(BlockTypes_StoneDevices.CONCRETE_QUARTER.getMeta()); else if(level>=6) solidState = IEContent.blockStoneDecorationSlabs.getStateFromMeta(BlockTypes_StoneDecoration.CONCRETE.getMeta()); else if(level>=2) solidState = IEContent.blockStoneDevice.getStateFromMeta(BlockTypes_StoneDevices.CONCRETE_THREEQUARTER.getMeta()); else solidState = IEContent.blockStoneDecoration.getStateFromMeta(BlockTypes_StoneDecoration.CONCRETE.getMeta()); world.setBlockState(pos, solidState); for(EntityLivingBase living : world.getEntitiesWithinAABB(EntityLivingBase.class, new AxisAlignedBB(pos,pos.add(1,1,1)))) living.addPotionEffect(new PotionEffect(IEPotions.concreteFeet,Integer.MAX_VALUE)); return; } else { state = state.withProperty(IEProperties.INT_16, Math.min(15, timer+1)); world.setBlockState(pos, state); } // check adjacent block levels if non-source if(quantaRemaining < quantaPerBlock) { if(world.getBlockState(pos.add( 0, -densityDir, 0)).getBlock() == this || world.getBlockState(pos.add(-1, -densityDir, 0)).getBlock() == this || world.getBlockState(pos.add( 1, -densityDir, 0)).getBlock() == this || world.getBlockState(pos.add( 0, -densityDir, -1)).getBlock() == this || world.getBlockState(pos.add( 0, -densityDir, 1)).getBlock() == this) { expQuanta = quantaPerBlock - 1; } else { int maxQuanta = -100; maxQuanta = getLargerQuanta(world, pos.add(-1, 0, 0), maxQuanta); maxQuanta = getLargerQuanta(world, pos.add( 1, 0, 0), maxQuanta); maxQuanta = getLargerQuanta(world, pos.add( 0, 0, -1), maxQuanta); maxQuanta = getLargerQuanta(world, pos.add( 0, 0, 1), maxQuanta); expQuanta = maxQuanta - 1; } int total = level; int blocks = 1; for(EnumFacing f : EnumFacing.HORIZONTALS) { IBlockState otherState = world.getBlockState(pos.offset(f)); if(otherState.getBlock()==this) { blocks++; total += otherState.getValue(LEVEL); } } int newEvenQuanta = (int)Math.ceil(total/(float)blocks); for(EnumFacing f : EnumFacing.HORIZONTALS) { IBlockState otherState = world.getBlockState(pos.offset(f)); if(otherState.getBlock()==this) world.setBlockState(pos.offset(f), otherState.withProperty(LEVEL, newEvenQuanta)); } // decay calculation if(expQuanta != quantaRemaining) { quantaRemaining = expQuanta; if(expQuanta <= 0) world.setBlockToAir(pos); else { world.setBlockState(pos, state.withProperty(LEVEL, quantaPerBlock - expQuanta), 2); world.scheduleUpdate(pos, this, tickRate); world.notifyNeighborsOfStateChange(pos, this); } } } // This is a "source" block, set meta to zero, and send a server only update else if(quantaRemaining >= quantaPerBlock) world.setBlockState(pos, this.getDefaultState(), 2); // Flow vertically if possible if(canDisplace(world, pos.up(densityDir))) { flowIntoBlockRet(world, pos.up(densityDir), 1, timer); return; } // Flow outward if possible int flowMeta = quantaPerBlock - quantaRemaining + 1; if(flowMeta >= quantaPerBlock) { world.setBlockState(pos, state.withProperty(IEProperties.INT_16, Math.min(15, timer+1))); world.scheduleUpdate(pos, this, tickRate); return; } if(isSourceBlock(world, pos) || !isFlowingVertically(world, pos)) { if(world.getBlockState(pos.down(densityDir)).getBlock() == this) flowMeta = 1; boolean flowTo[] = getOptimalFlowDirections(world, pos); boolean hasFlown = false; if(flowTo[0]) hasFlown |= flowIntoBlockRet(world, pos.add(-1, 0, 0), flowMeta, timer); if(flowTo[1]) hasFlown |= flowIntoBlockRet(world, pos.add( 1, 0, 0), flowMeta, timer); if(flowTo[2]) hasFlown |= flowIntoBlockRet(world, pos.add( 0, 0, -1), flowMeta, timer); if(flowTo[3]) hasFlown |= flowIntoBlockRet(world, pos.add( 0, 0, 1), flowMeta, timer); if(!hasFlown) { world.setBlockState(pos, state.withProperty(IEProperties.INT_16, Math.min(15, timer+1))); world.scheduleUpdate(pos, this, tickRate); } } } protected boolean flowIntoBlockRet(World world, BlockPos pos, int meta, int harden) { if(meta < 0) return false; if(displaceIfPossible(world, pos)) { world.setBlockState(pos, this.getBlockState().getBaseState().withProperty(LEVEL, meta).withProperty(IEProperties.INT_16, harden), 3); return true; } return false; } }