blob: b6768e8f81f2c6d418d8bb2b2e840f71bbeb91bb [file] [log] [blame] [raw]
package mekanism.common.block;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import javax.annotation.Nullable;
import mekanism.common.Mekanism;
import mekanism.common.MekanismBlocks;
import mekanism.common.Tier.BaseTier;
import mekanism.common.base.ITierItem;
import mekanism.common.block.property.PropertyConnection;
import mekanism.common.block.states.BlockStateTransmitter;
import mekanism.common.block.states.BlockStateTransmitter.TransmitterType;
import mekanism.common.block.states.BlockStateTransmitter.TransmitterType.Size;
import mekanism.common.tile.transmitter.TileEntityDiversionTransporter;
import mekanism.common.tile.transmitter.TileEntityLogisticalTransporter;
import mekanism.common.tile.transmitter.TileEntityMechanicalPipe;
import mekanism.common.tile.transmitter.TileEntityPressurizedTube;
import mekanism.common.tile.transmitter.TileEntityRestrictiveTransporter;
import mekanism.common.tile.transmitter.TileEntitySidedPipe;
import mekanism.common.tile.transmitter.TileEntitySidedPipe.ConnectionType;
import mekanism.common.tile.transmitter.TileEntityThermodynamicConductor;
import mekanism.common.tile.transmitter.TileEntityUniversalCable;
import mekanism.common.util.MekanismUtils;
import mekanism.common.util.MultipartUtils;
import mekanism.common.util.MultipartUtils.AdvancedRayTraceResult;
import net.minecraft.block.Block;
import net.minecraft.block.ITileEntityProvider;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.block.state.IBlockState;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.EnumBlockRenderType;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.NonNullList;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.ChunkCache;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
import net.minecraftforge.client.model.obj.OBJModel.OBJProperty;
import net.minecraftforge.client.model.obj.OBJModel.OBJState;
import net.minecraftforge.common.property.IExtendedBlockState;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class BlockTransmitter extends Block implements ITileEntityProvider
{
public static AxisAlignedBB[] smallSides = new AxisAlignedBB[7];
public static AxisAlignedBB[] largeSides = new AxisAlignedBB[7];
public static AxisAlignedBB smallDefault = smallSides[6];
public static AxisAlignedBB largeDefault = largeSides[6];
static
{
smallSides[0] = new AxisAlignedBB(0.3, 0.0, 0.3, 0.7, 0.3, 0.7);
smallSides[1] = new AxisAlignedBB(0.3, 0.7, 0.3, 0.7, 1.0, 0.7);
smallSides[2] = new AxisAlignedBB(0.3, 0.3, 0.0, 0.7, 0.7, 0.3);
smallSides[3] = new AxisAlignedBB(0.3, 0.3, 0.7, 0.7, 0.7, 1.0);
smallSides[4] = new AxisAlignedBB(0.0, 0.3, 0.3, 0.3, 0.7, 0.7);
smallSides[5] = new AxisAlignedBB(0.7, 0.3, 0.3, 1.0, 0.7, 0.7);
smallSides[6] = new AxisAlignedBB(0.3, 0.3, 0.3, 0.7, 0.7, 0.7);
largeSides[0] = new AxisAlignedBB(0.25, 0.0, 0.25, 0.75, 0.25, 0.75);
largeSides[1] = new AxisAlignedBB(0.25, 0.75, 0.25, 0.75, 1.0, 0.75);
largeSides[2] = new AxisAlignedBB(0.25, 0.25, 0.0, 0.75, 0.75, 0.25);
largeSides[3] = new AxisAlignedBB(0.25, 0.25, 0.75, 0.75, 0.75, 1.0);
largeSides[4] = new AxisAlignedBB(0.0, 0.25, 0.25, 0.25, 0.75, 0.75);
largeSides[5] = new AxisAlignedBB(0.75, 0.25, 0.25, 1.0, 0.75, 0.75);
largeSides[6] = new AxisAlignedBB(0.25, 0.25, 0.25, 0.75, 0.75, 0.75);
}
public BlockTransmitter()
{
super(Material.PISTON);
setCreativeTab(Mekanism.tabMekanism);
setHardness(1F);
setResistance(10F);
}
@Override
public IBlockState getActualState(IBlockState state, IBlockAccess worldIn, BlockPos pos)
{
TileEntity tile = worldIn instanceof ChunkCache ? ((ChunkCache)worldIn).getTileEntity(pos, Chunk.EnumCreateEntityType.CHECK) : worldIn.getTileEntity(pos);
if(tile instanceof TileEntitySidedPipe)
{
state = state.withProperty(BlockStateTransmitter.tierProperty, ((TileEntitySidedPipe)tile).getBaseTier());
}
return state;
}
@Override
public IBlockState getStateFromMeta(int meta)
{
TransmitterType type = TransmitterType.get(meta);
return getDefaultState().withProperty(BlockStateTransmitter.typeProperty, type);
}
@Override
public int getMetaFromState(IBlockState state)
{
TransmitterType type = state.getValue(BlockStateTransmitter.typeProperty);
return type.ordinal();
}
@Override
public BlockStateContainer createBlockState()
{
return new BlockStateTransmitter(this);
}
@SideOnly(Side.CLIENT)
@Override
public IBlockState getExtendedState(IBlockState state, IBlockAccess w, BlockPos pos)
{
TileEntitySidedPipe tile = w instanceof ChunkCache ? (TileEntitySidedPipe)((ChunkCache)w).getTileEntity(pos, Chunk.EnumCreateEntityType.CHECK) : (TileEntitySidedPipe)w.getTileEntity(pos);
if(tile != null)
{
return tile.getExtendedState(state);
}
else {
ConnectionType[] typeArray = new ConnectionType[] {ConnectionType.NORMAL, ConnectionType.NORMAL, ConnectionType.NORMAL,
ConnectionType.NORMAL, ConnectionType.NORMAL, ConnectionType.NORMAL};
PropertyConnection connectionProp = new PropertyConnection((byte)0, (byte)0, typeArray, true);
return ((IExtendedBlockState)state).withProperty(OBJProperty.INSTANCE, new OBJState(Arrays.asList(), true)).withProperty(PropertyConnection.INSTANCE, connectionProp);
}
}
@Override
public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess world, BlockPos pos)
{
TileEntity tile = world instanceof ChunkCache ? ((ChunkCache)world).getTileEntity(pos, Chunk.EnumCreateEntityType.CHECK) : world.getTileEntity(pos);
if(tile instanceof TileEntitySidedPipe && ((TileEntitySidedPipe)tile).getTransmitterType().getSize() == Size.SMALL)
{
return smallSides[6];
}
return largeSides[6];
}
@Override
public void addCollisionBoxToList(IBlockState state, World world, BlockPos pos, AxisAlignedBB entityBox, List<AxisAlignedBB> collidingBoxes, @Nullable Entity entityIn, boolean b)
{
TileEntitySidedPipe tile = (TileEntitySidedPipe)world.getTileEntity(pos);
if(tile != null)
{
List<AxisAlignedBB> boxes = tile.getCollisionBoxes(entityBox.offset(-pos.getX(), -pos.getY(), -pos.getZ()));
for(AxisAlignedBB box : boxes)
{
collidingBoxes.add(box.offset(pos));
}
}
}
@Override
public AxisAlignedBB getSelectedBoundingBox(IBlockState state, World world, BlockPos pos)
{
return getDefaultForTile((TileEntitySidedPipe)world.getTileEntity(pos)).offset(pos);
}
@Override
public RayTraceResult collisionRayTrace(IBlockState blockState, World world, BlockPos pos, Vec3d start, Vec3d end)
{
TileEntitySidedPipe tile = (TileEntitySidedPipe)world.getTileEntity(pos);
if(tile == null)
{
return null;
}
List<AxisAlignedBB> boxes = tile.getCollisionBoxes();
AdvancedRayTraceResult result = MultipartUtils.collisionRayTrace(pos, start, end, boxes);
if(result != null && result.valid())
{
setDefaultForTile(tile, result.bounds);
}
return result != null ? result.hit : null;
}
@Override
public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ)
{
ItemStack stack = player.getHeldItem(hand);
if(stack.isEmpty())
{
return false;
}
if(MekanismUtils.hasUsableWrench(player, pos) && player.isSneaking())
{
if(!world.isRemote)
{
dismantleBlock(state, world, pos, false);
}
return true;
}
return false;
}
@Override
public ItemStack getPickBlock(IBlockState state, RayTraceResult target, World world, BlockPos pos, EntityPlayer player)
{
TileEntitySidedPipe tileEntity = (TileEntitySidedPipe)world.getTileEntity(pos);
ItemStack itemStack = new ItemStack(MekanismBlocks.Transmitter, 1, tileEntity.getTransmitterType().ordinal());
if(!itemStack.hasTagCompound())
{
itemStack.setTagCompound(new NBTTagCompound());
}
ITierItem tierItem = (ITierItem)itemStack.getItem();
tierItem.setBaseTier(itemStack, tileEntity.getBaseTier());
return itemStack;
}
public ItemStack dismantleBlock(IBlockState state, World world, BlockPos pos, boolean returnBlock)
{
ItemStack itemStack = getPickBlock(state, null, world, pos, null);
world.setBlockToAir(pos);
if(!returnBlock)
{
float motion = 0.7F;
double motionX = (world.rand.nextFloat() * motion) + (1.0F - motion) * 0.5D;
double motionY = (world.rand.nextFloat() * motion) + (1.0F - motion) * 0.5D;
double motionZ = (world.rand.nextFloat() * motion) + (1.0F - motion) * 0.5D;
EntityItem entityItem = new EntityItem(world, pos.getX() + motionX, pos.getY() + motionY, pos.getZ() + motionZ, itemStack);
world.spawnEntity(entityItem);
}
return itemStack;
}
@Override
@SideOnly(Side.CLIENT)
public void getSubBlocks(Item item, CreativeTabs creativetabs, NonNullList<ItemStack> list)
{
for(TransmitterType type : TransmitterType.values())
{
if(type.hasTiers())
{
for(BaseTier tier : BaseTier.values())
{
if(tier.isObtainable())
{
list.add(MekanismUtils.getTransmitter(type, tier, 1));
}
}
}
else {
list.add(MekanismUtils.getTransmitter(type, BaseTier.BASIC, 1));
}
}
}
@Override
public void onBlockPlacedBy(World world, BlockPos pos, IBlockState state, EntityLivingBase placer, ItemStack stack)
{
TileEntitySidedPipe tile = (TileEntitySidedPipe)world.getTileEntity(pos);
tile.onAdded();
}
@Override
public void neighborChanged(IBlockState state, World world, BlockPos pos, Block block, BlockPos neighbor)
{
TileEntitySidedPipe tile = (TileEntitySidedPipe)world.getTileEntity(pos);
EnumFacing side = EnumFacing.getFacingFromVector(neighbor.getX() - pos.getX(), neighbor.getY() - pos.getY(), neighbor.getZ() - pos.getZ());
tile.onNeighborBlockChange(side);
}
@Override
public void onNeighborChange(IBlockAccess world, BlockPos pos, BlockPos neighbor)
{
TileEntitySidedPipe tile = world instanceof ChunkCache ? (TileEntitySidedPipe)((ChunkCache)world).getTileEntity(pos, Chunk.EnumCreateEntityType.CHECK) : (TileEntitySidedPipe)world.getTileEntity(pos);
EnumFacing side = EnumFacing.getFacingFromVector(neighbor.getX() - pos.getX(), neighbor.getY() - pos.getY(), neighbor.getZ() - pos.getZ());
tile.onNeighborTileChange(side);
}
@Override
public boolean canRenderInLayer(IBlockState state, BlockRenderLayer layer)
{
TransmitterType type = state.getValue(BlockStateTransmitter.typeProperty);
if(layer == BlockRenderLayer.TRANSLUCENT && (type == TransmitterType.LOGISTICAL_TRANSPORTER || type == TransmitterType.DIVERSION_TRANSPORTER))
{
return true;
}
return layer == BlockRenderLayer.CUTOUT;
}
@Override
public EnumBlockRenderType getRenderType(IBlockState state)
{
return EnumBlockRenderType.MODEL;
}
@Override
public boolean isBlockNormalCube(IBlockState state)
{
return false;
}
@Override
public boolean isOpaqueCube(IBlockState state)
{
return false;
}
@Override
public boolean isFullCube(IBlockState state)
{
return false;
}
@Override
public boolean isFullBlock(IBlockState state)
{
return false;
}
@Override
public int quantityDropped(Random random)
{
return 0;
}
@Override
public boolean removedByPlayer(IBlockState state, World world, BlockPos pos, EntityPlayer player, boolean willHarvest)
{
if(!player.capabilities.isCreativeMode && !world.isRemote && willHarvest)
{
float motion = 0.7F;
double motionX = (world.rand.nextFloat() * motion) + (1.0F - motion) * 0.5D;
double motionY = (world.rand.nextFloat() * motion) + (1.0F - motion) * 0.5D;
double motionZ = (world.rand.nextFloat() * motion) + (1.0F - motion) * 0.5D;
EntityItem entityItem = new EntityItem(world, pos.getX() + motionX, pos.getY() + motionY, pos.getZ() + motionZ, getPickBlock(state, null, world, pos, player));
world.spawnEntity(entityItem);
}
return super.removedByPlayer(state, world, pos, player, willHarvest);
}
private static AxisAlignedBB getDefaultForTile(TileEntitySidedPipe tile)
{
if(tile == null || tile.getTransmitterType().getSize() == Size.SMALL)
{
return smallDefault;
}
return largeDefault;
}
private static void setDefaultForTile(TileEntitySidedPipe tile, AxisAlignedBB box)
{
if(tile == null)
{
return;
}
if(tile.getTransmitterType().getSize() == Size.SMALL)
{
smallDefault = box;
return;
}
largeDefault = box;
}
@Override
public TileEntity createNewTileEntity(World worldIn, int meta)
{
TransmitterType type = TransmitterType.get(meta);
switch(type)
{
case UNIVERSAL_CABLE:
return new TileEntityUniversalCable();
case MECHANICAL_PIPE:
return new TileEntityMechanicalPipe();
case PRESSURIZED_TUBE:
return new TileEntityPressurizedTube();
case LOGISTICAL_TRANSPORTER:
return new TileEntityLogisticalTransporter();
case DIVERSION_TRANSPORTER:
return new TileEntityDiversionTransporter();
case RESTRICTIVE_TRANSPORTER:
return new TileEntityRestrictiveTransporter();
case THERMODYNAMIC_CONDUCTOR:
return new TileEntityThermodynamicConductor();
}
return null;
}
}