package slimeknights.tconstruct.smeltery.block; import com.google.common.collect.Lists; import net.minecraft.block.properties.PropertyBool; import net.minecraft.block.properties.PropertyEnum; import net.minecraft.block.state.BlockStateContainer; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.BlockRenderLayer; import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; import net.minecraft.util.IStringSerializable; import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; import net.minecraftforge.fluids.FluidUtil; import net.minecraftforge.fluids.capability.CapabilityFluidHandler; import net.minecraftforge.fluids.capability.IFluidHandler; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import java.util.List; import java.util.Locale; import java.util.Random; import javax.annotation.Nonnull; import slimeknights.mantle.block.EnumBlock; import slimeknights.tconstruct.smeltery.tileentity.TileTank; public class BlockTank extends BlockEnumSmeltery<BlockTank.TankType> { public static final PropertyEnum<TankType> TYPE = PropertyEnum.create("type", TankType.class); public static final PropertyBool KNOB = PropertyBool.create("has_knob"); public BlockTank() { super(TYPE, TankType.class); setDefaultState(this.blockState.getBaseState().withProperty(KNOB, false)); } @Nonnull @Override public TileEntity createNewTileEntity(@Nonnull World worldIn, int meta) { return new TileTank(); } @Nonnull @Override protected BlockStateContainer createBlockState() { return new BlockStateContainer(this, TYPE, KNOB); } @Nonnull @Override public IBlockState getActualState(@Nonnull IBlockState state, IBlockAccess worldIn, BlockPos pos) { boolean hasKnob = (state.getValue(TYPE)) == TankType.TANK && worldIn.isAirBlock(pos.up()); return super.getActualState(state, worldIn, pos).withProperty(KNOB, hasKnob); } @Nonnull @Override public IBlockState getStateFromMeta(int meta) { IBlockState state = super.getStateFromMeta(meta); if(meta == TankType.TANK.getMeta()) { state = state.withProperty(KNOB, true); } return state; } @Override public boolean onBlockActivated(World worldIn, BlockPos pos, IBlockState state, EntityPlayer playerIn, EnumHand hand, ItemStack heldItem, EnumFacing side, float hitX, float hitY, float hitZ) { TileEntity te = worldIn.getTileEntity(pos); if(te == null || !te.hasCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, side)) { return false; } IFluidHandler fluidHandler = te.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, side); FluidUtil.interactWithFluidHandler(heldItem, fluidHandler, playerIn); // prevent interaction so stuff like buckets and other things don't place the liquid block return heldItem != null && !(heldItem.getItem() instanceof ItemBlock); } /* Block breaking retains the liquid */ @Override public void onBlockPlacedBy(World world, BlockPos pos, IBlockState state, EntityLivingBase placer, ItemStack stack) { TileEntity te = world.getTileEntity(pos); if(te instanceof TileTank && stack != null && stack.hasTagCompound()) { ((TileTank) te).readTankFromNBT(stack.getTagCompound()); } } @Nonnull @Override public List<ItemStack> getDrops(IBlockAccess world, BlockPos pos, @Nonnull IBlockState state, int fortune) { // standard drop logic List<ItemStack> ret = Lists.newArrayList(); Random rand = world instanceof World ? ((World) world).rand : RANDOM; Item item = this.getItemDropped(state, rand, fortune); ItemStack stack = null; if(item != null) { stack = new ItemStack(item, 1, this.damageDropped(state)); ret.add(stack); } // save liquid data on the stack TileEntity te = world.getTileEntity(pos); if(te instanceof TileTank && stack != null) { if(((TileTank) te).containsFluid()) { NBTTagCompound tag = new NBTTagCompound(); ((TileTank) te).writeTankToNBT(tag); stack.setTagCompound(tag); } } return ret; } // fix blockbreak logic order. Needed to have the tile entity when getting the drops @Override public boolean removedByPlayer(@Nonnull IBlockState state, World world, @Nonnull BlockPos pos, @Nonnull EntityPlayer player, boolean willHarvest) { // we pull up a few calls to this point in time because we still have the TE here // the execution otherwise is equivalent to vanilla order this.onBlockDestroyedByPlayer(world, pos, state); if(willHarvest) { this.harvestBlock(world, player, pos, state, world.getTileEntity(pos), player.getHeldItemMainhand()); } world.setBlockToAir(pos); // return false to prevent the above called functions to be called again // side effect of this is that no xp will be dropped. but it shoudln't anyway return false; } /* Rendering stuff etc */ @Override public int getLightValue(@Nonnull IBlockState state, IBlockAccess world, @Nonnull BlockPos pos) { TileEntity te = world.getTileEntity(pos); if(!(te instanceof TileTank)) { return 0; } TileTank tank = (TileTank) te; return tank.getBrightness(); } @Nonnull @Override @SideOnly(Side.CLIENT) public BlockRenderLayer getBlockLayer() { return BlockRenderLayer.CUTOUT; } @Override public boolean isFullCube(IBlockState state) { return false; } @Override public boolean isOpaqueCube(IBlockState state) { return false; } @Override public boolean hasComparatorInputOverride(IBlockState state) { return true; } @Override public int getComparatorInputOverride(IBlockState blockState, World world, BlockPos pos) { TileEntity te = world.getTileEntity(pos); if(!(te instanceof TileTank)) { return 0; } return ((TileTank) te).comparatorStrength(); } public enum TankType implements IStringSerializable, EnumBlock.IEnumMeta { TANK, GAUGE, WINDOW; public final int meta; TankType() { meta = ordinal(); } @Override public String getName() { return this.toString().toLowerCase(Locale.US); } @Override public int getMeta() { return meta; } } }