package mekanism.common.block;
import java.util.List;
import java.util.Random;
import mekanism.api.Coord4D;
import mekanism.api.MekanismConfig.client;
import mekanism.api.MekanismConfig.general;
import mekanism.api.energy.IEnergizedItem;
import mekanism.api.energy.IStrictEnergyStorage;
import mekanism.api.util.StackUtils;
import mekanism.client.render.ctm.CTMBlockRenderContext;
import mekanism.client.render.ctm.CTMData;
import mekanism.client.render.ctm.ICTMBlock;
import mekanism.common.Mekanism;
import mekanism.common.Tier.BaseTier;
import mekanism.common.Tier.FluidTankTier;
import mekanism.common.base.IActiveState;
import mekanism.common.base.IBoundingBlock;
import mekanism.common.base.IFactory;
import mekanism.common.base.IFactory.RecipeType;
import mekanism.common.base.IRedstoneControl;
import mekanism.common.base.ISideConfiguration;
import mekanism.common.base.ISustainedData;
import mekanism.common.base.ISustainedInventory;
import mekanism.common.base.ISustainedTank;
import mekanism.common.base.ITierItem;
import mekanism.common.base.IUpgradeTile;
import mekanism.common.block.states.BlockStateBasic;
import mekanism.common.block.states.BlockStateBasic.BasicBlockType;
import mekanism.common.block.states.BlockStateFacing;
import mekanism.common.block.states.BlockStateMachine;
import mekanism.common.block.states.BlockStateMachine.MachineBlock;
import mekanism.common.block.states.BlockStateMachine.MachineType;
import mekanism.common.item.ItemBlockMachine;
import mekanism.common.network.PacketLogisticalSorterGui.LogisticalSorterGuiMessage;
import mekanism.common.network.PacketLogisticalSorterGui.SorterGuiPacket;
import mekanism.common.security.ISecurityItem;
import mekanism.common.security.ISecurityTile;
import mekanism.common.tile.TileEntityBasicBlock;
import mekanism.common.tile.TileEntityChargepad;
import mekanism.common.tile.TileEntityContainerBlock;
import mekanism.common.tile.TileEntityFactory;
import mekanism.common.tile.TileEntityFluidTank;
import mekanism.common.tile.TileEntityLaserAmplifier;
import mekanism.common.tile.TileEntityLogisticalSorter;
import mekanism.common.tile.TileEntityMetallurgicInfuser;
import mekanism.common.tile.TileEntityPersonalChest;
import mekanism.common.util.FluidContainerUtils;
import mekanism.common.util.ItemDataUtils;
import mekanism.common.util.MekanismUtils;
import mekanism.common.util.PipeUtils;
import mekanism.common.util.SecurityUtils;
import net.minecraft.block.Block;
import net.minecraft.block.BlockContainer;
import net.minecraft.block.material.Material;
import net.minecraft.block.properties.PropertyEnum;
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.entity.player.EntityPlayerMP;
import net.minecraft.inventory.IInventory;
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.EnumParticleTypes;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.world.Explosion;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.common.property.IExtendedBlockState;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidRegistry;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidUtil;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import buildcraft.api.tools.IToolWrench;
/**
* Block class for handling multiple machine block IDs.
* 0:0: Enrichment Chamber
* 0:1: Osmium Compressor
* 0:2: Combiner
* 0:3: Crusher
* 0:4: Digital Miner
* 0:5: Basic Factory
* 0:6: Advanced Factory
* 0:7: Elite Factory
* 0:8: Metallurgic Infuser
* 0:9: Purification Chamber
* 0:10: Energized Smelter
* 0:11: Teleporter
* 0:12: Electric Pump
* 0:13: Electric Chest
* 0:14: Chargepad
* 0:15: Logistical Sorter
* 1:0: Rotary Condensentrator
* 1:1: Chemical Oxidizer
* 1:2: Chemical Infuser
* 1:3: Chemical Injection Chamber
* 1:4: Electrolytic Separator
* 1:5: Precision Sawmill
* 1:6: Chemical Dissolution Chamber
* 1:7: Chemical Washer
* 1:8: Chemical Crystallizer
* 1:9: Seismic Vibrator
* 1:10: Pressurized Reaction Chamber
* 1:11: Fluid Tank
* 1:12: Fluidic Plenisher
* 1:13: Laser
* 1:14: Laser Amplifier
* 1:15: Laser Tractor Beam
* 2:0: Quantum Entangloporter
* 2:1: Solar Neutron Activator
* 2:2: Ambient Accumulator
* 2:3: Oredictionificator
* 2:4: Resistive Heater
* 2:5: Formulaic Assemblicator
* 2:6: Fuelwood Heater
*
* @author AidanBrady
*
*/
public abstract class BlockMachine extends BlockContainer implements ICTMBlock
{
public CTMData[] ctmData = new CTMData[16];
private static final AxisAlignedBB CHARGEPAD_BOUNDS = new AxisAlignedBB(0.0F, 0.0F, 0.0F, 1.0F, 0.06F, 1.0F);
private static final AxisAlignedBB TANK_BOUNDS = new AxisAlignedBB(0.125F, 0.0F, 0.125F, 0.875F, 1.0F, 0.875F);
public BlockMachine()
{
super(Material.IRON);
setHardness(3.5F);
setResistance(16F);
setCreativeTab(Mekanism.tabMekanism);
initCTMs();
}
public static BlockMachine getBlockMachine(MachineBlock block)
{
return new BlockMachine()
{
@Override
public MachineBlock getMachineBlock()
{
return block;
}
};
}
public abstract MachineBlock getMachineBlock();
@SideOnly(Side.CLIENT)
@Override
public IBlockState getExtendedState(IBlockState stateIn, IBlockAccess w, BlockPos pos)
{
if(stateIn.getBlock() == null || stateIn.getMaterial() == Material.AIR)
{
return stateIn;
}
IExtendedBlockState state = (IExtendedBlockState)stateIn;
CTMBlockRenderContext ctx = new CTMBlockRenderContext(w, pos);
return state.withProperty(BlockStateBasic.ctmProperty, ctx);
}
@Override
public BlockStateContainer createBlockState()
{
return new BlockStateMachine(this, getTypeProperty());
}
@Override
public IBlockState getStateFromMeta(int meta)
{
MachineType type = MachineType.get(getMachineBlock(), meta & 0xF);
return getDefaultState().withProperty(getTypeProperty(), type);
}
@Override
public int getMetaFromState(IBlockState state)
{
MachineType type = state.getValue(getTypeProperty());
return type.meta;
}
@Override
public IBlockState getActualState(IBlockState state, IBlockAccess worldIn, BlockPos pos)
{
TileEntity tile = worldIn.getTileEntity(pos);
if(tile instanceof TileEntityBasicBlock && ((TileEntityBasicBlock)tile).facing != null)
{
state = state.withProperty(BlockStateFacing.facingProperty, ((TileEntityBasicBlock)tile).facing);
}
if(tile instanceof IActiveState)
{
state = state.withProperty(BlockStateMachine.activeProperty, ((IActiveState)tile).getActive());
}
if(tile instanceof TileEntityFluidTank)
{
state = state.withProperty(BlockStateMachine.tierProperty, ((TileEntityFluidTank)tile).tier.getBaseTier());
}
if(tile instanceof TileEntityFactory)
{
state = state.withProperty(BlockStateMachine.recipeProperty, ((TileEntityFactory)tile).recipeType);
}
return state;
}
public void initCTMs()
{
switch(getMachineBlock())
{
case MACHINE_BLOCK_1:
ctmData[11] = new CTMData(BasicBlockType.TELEPORTER_FRAME, MachineType.TELEPORTER);
break;
default:
}
}
@Override
public void onBlockPlacedBy(World world, BlockPos pos, IBlockState state, EntityLivingBase placer, ItemStack stack)
{
TileEntityBasicBlock tileEntity = (TileEntityBasicBlock)world.getTileEntity(pos);
int side = MathHelper.floor_double((placer.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3;
int height = Math.round(placer.rotationPitch);
int change = 3;
if(tileEntity == null)
{
return;
}
if(tileEntity.canSetFacing(0) && tileEntity.canSetFacing(1))
{
if(height >= 65)
{
change = 1;
} else if(height <= -65)
{
change = 0;
}
}
if(change != 0 && change != 1)
{
switch(side)
{
case 0:
change = 2;
break;
case 1:
change = 5;
break;
case 2:
change = 3;
break;
case 3:
change = 4;
break;
}
}
tileEntity.setFacing((short)change);
tileEntity.redstone = world.isBlockIndirectlyGettingPowered(pos) > 0;
if(tileEntity instanceof TileEntityLogisticalSorter)
{
TileEntityLogisticalSorter transporter = (TileEntityLogisticalSorter)tileEntity;
if(!transporter.hasInventory())
{
for(EnumFacing dir : EnumFacing.VALUES)
{
TileEntity tile = Coord4D.get(transporter).offset(dir).getTileEntity(world);
if(tile instanceof IInventory)
{
tileEntity.setFacing((short)dir.getOpposite().ordinal());
break;
}
}
}
}
if(tileEntity instanceof IBoundingBlock)
{
((IBoundingBlock)tileEntity).onPlace();
}
}
@Override
public void breakBlock(World world, BlockPos pos, IBlockState state)
{
TileEntityBasicBlock tileEntity = (TileEntityBasicBlock)world.getTileEntity(pos);
if(tileEntity instanceof IBoundingBlock)
{
((IBoundingBlock)tileEntity).onBreak();
}
super.breakBlock(world, pos, state);
}
@Override
@SideOnly(Side.CLIENT)
public void randomDisplayTick(IBlockState state, World world, BlockPos pos, Random random)
{
TileEntityBasicBlock tileEntity = (TileEntityBasicBlock)world.getTileEntity(pos);
if(tileEntity instanceof TileEntityFluidTank)
{
return;
}
if(MekanismUtils.isActive(world, pos) && ((IActiveState)tileEntity).renderUpdate() && client.machineEffects)
{
float xRandom = (float)pos.getX() + 0.5F;
float yRandom = (float)pos.getY() + 0.0F + random.nextFloat() * 6.0F / 16.0F;
float zRandom = (float)pos.getZ() + 0.5F;
float iRandom = 0.52F;
float jRandom = random.nextFloat() * 0.6F - 0.3F;
EnumFacing side = tileEntity.facing;
if(tileEntity instanceof TileEntityMetallurgicInfuser)
{
side = side.getOpposite();
}
switch(side)
{
case WEST:
world.spawnParticle(EnumParticleTypes.SMOKE_NORMAL, (xRandom - iRandom), yRandom, (zRandom + jRandom), 0.0D, 0.0D, 0.0D);
world.spawnParticle(EnumParticleTypes.REDSTONE, (xRandom - iRandom), yRandom, (zRandom + jRandom), 0.0D, 0.0D, 0.0D);
break;
case EAST:
world.spawnParticle(EnumParticleTypes.SMOKE_NORMAL, (xRandom + iRandom), yRandom, (zRandom + jRandom), 0.0D, 0.0D, 0.0D);
world.spawnParticle(EnumParticleTypes.REDSTONE, (xRandom + iRandom), yRandom, (zRandom + jRandom), 0.0D, 0.0D, 0.0D);
break;
case NORTH:
world.spawnParticle(EnumParticleTypes.SMOKE_NORMAL, (xRandom + jRandom), yRandom, (zRandom - iRandom), 0.0D, 0.0D, 0.0D);
world.spawnParticle(EnumParticleTypes.REDSTONE, (xRandom + jRandom), yRandom, (zRandom - iRandom), 0.0D, 0.0D, 0.0D);
break;
case SOUTH:
world.spawnParticle(EnumParticleTypes.SMOKE_NORMAL, (xRandom + jRandom), yRandom, (zRandom + iRandom), 0.0D, 0.0D, 0.0D);
world.spawnParticle(EnumParticleTypes.REDSTONE, (xRandom + jRandom), yRandom, (zRandom + iRandom), 0.0D, 0.0D, 0.0D);
break;
default:
break;
}
}
}
@Override
public int getLightValue(IBlockState state, IBlockAccess world, BlockPos pos)
{
if(client.enableAmbientLighting)
{
TileEntity tileEntity = world.getTileEntity(pos);
if(tileEntity instanceof IActiveState)
{
if(((IActiveState)tileEntity).getActive() && ((IActiveState)tileEntity).lightUpdate())
{
return client.ambientLightingLevel;
}
}
}
return 0;
}
@Override
public int damageDropped(IBlockState state)
{
return state.getBlock().getMetaFromState(state);
}
@Override
@SideOnly(Side.CLIENT)
public void getSubBlocks(Item item, CreativeTabs creativetabs, List<ItemStack> list)
{
for(MachineType type : MachineType.getValidMachines())
{
if(type.typeBlock == getMachineBlock() && type.isEnabled())
{
switch(type)
{
case BASIC_FACTORY:
case ADVANCED_FACTORY:
case ELITE_FACTORY:
for(RecipeType recipe : RecipeType.values())
{
ItemStack stack = new ItemStack(item, 1, type.meta);
((IFactory)stack.getItem()).setRecipeType(recipe.ordinal(), stack);
list.add(stack);
}
break;
case FLUID_TANK:
ItemBlockMachine itemMachine = (ItemBlockMachine)item;
for(FluidTankTier tier : FluidTankTier.values())
{
ItemStack stack = new ItemStack(item, 1, type.meta);
itemMachine.setBaseTier(stack, tier.getBaseTier());
list.add(stack);
}
break;
default:
list.add(new ItemStack(item, 1, type.meta));
}
}
}
}
@Override
public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer entityplayer, EnumHand hand, ItemStack stack, EnumFacing side, float hitX, float hitY, float hitZ)
{
if(world.isRemote)
{
return true;
}
TileEntityBasicBlock tileEntity = (TileEntityBasicBlock)world.getTileEntity(pos);
int metadata = state.getBlock().getMetaFromState(state);
if(stack != null)
{
Item tool = stack.getItem();
if(MekanismUtils.hasUsableWrench(entityplayer, pos))
{
if(SecurityUtils.canAccess(entityplayer, tileEntity))
{
if(entityplayer.isSneaking())
{
dismantleBlock(state, world, pos, false);
return true;
}
if(MekanismUtils.isBCWrench(tool))
{
((IToolWrench)tool).wrenchUsed(entityplayer, pos);
}
int change = tileEntity.facing.rotateY().ordinal();
if(tileEntity instanceof TileEntityLogisticalSorter)
{
if(!((TileEntityLogisticalSorter)tileEntity).hasInventory())
{
for(EnumFacing dir : EnumFacing.VALUES)
{
TileEntity tile = Coord4D.get(tileEntity).offset(dir).getTileEntity(world);
if(tile instanceof IInventory)
{
change = dir.getOpposite().ordinal();
break;
}
}
}
}
tileEntity.setFacing((short)change);
world.notifyNeighborsOfStateChange(pos, this);
}
else {
SecurityUtils.displayNoAccess(entityplayer);
}
return true;
}
}
if(tileEntity != null)
{
MachineType type = MachineType.get(getMachineBlock(), metadata);
switch(type)
{
case PERSONAL_CHEST:
if(!entityplayer.isSneaking() && !world.isSideSolid(pos.up(), EnumFacing.DOWN))
{
TileEntityPersonalChest chest = (TileEntityPersonalChest)tileEntity;
if(SecurityUtils.canAccess(entityplayer, tileEntity))
{
MekanismUtils.openPersonalChestGui((EntityPlayerMP)entityplayer, chest, null, true);
}
else {
SecurityUtils.displayNoAccess(entityplayer);
}
return true;
}
break;
case FLUID_TANK:
if(!entityplayer.isSneaking())
{
if(SecurityUtils.canAccess(entityplayer, tileEntity))
{
if(stack != null && FluidContainerUtils.isFluidContainer(stack))
{
if(manageInventory(entityplayer, (TileEntityFluidTank)tileEntity, hand, stack))
{
entityplayer.inventory.markDirty();
return true;
}
}
else {
entityplayer.openGui(Mekanism.instance, type.guiId, world, pos.getX(), pos.getY(), pos.getZ());
}
}
else {
SecurityUtils.displayNoAccess(entityplayer);
}
return true;
}
break;
case LOGISTICAL_SORTER:
if(!entityplayer.isSneaking())
{
if(SecurityUtils.canAccess(entityplayer, tileEntity))
{
LogisticalSorterGuiMessage.openServerGui(SorterGuiPacket.SERVER, 0, world, (EntityPlayerMP)entityplayer, Coord4D.get(tileEntity), -1);
}
else {
SecurityUtils.displayNoAccess(entityplayer);
}
return true;
}
break;
case TELEPORTER:
case QUANTUM_ENTANGLOPORTER:
if(!entityplayer.isSneaking())
{
String owner = ((ISecurityTile)tileEntity).getSecurity().getOwner();
if(MekanismUtils.isOp((EntityPlayerMP)entityplayer) || owner == null || entityplayer.getName().equals(owner))
{
entityplayer.openGui(Mekanism.instance, type.guiId, world, pos.getX(), pos.getY(), pos.getZ());
}
else {
SecurityUtils.displayNoAccess(entityplayer);
}
return true;
}
break;
default:
if(!entityplayer.isSneaking() && type.guiId != -1)
{
if(SecurityUtils.canAccess(entityplayer, tileEntity))
{
entityplayer.openGui(Mekanism.instance, type.guiId, world, pos.getX(), pos.getY(), pos.getZ());
}
else {
SecurityUtils.displayNoAccess(entityplayer);
}
return true;
}
break;
}
}
return false;
}
@Override
public TileEntity createTileEntity(World world, IBlockState state)
{
int metadata = state.getBlock().getMetaFromState(state);
if(MachineType.get(getMachineBlock(), metadata) == null)
{
return null;
}
return MachineType.get(getMachineBlock(), metadata).create();
}
@Override
public TileEntity createNewTileEntity(World world, int metadata)
{
return null;
}
@Override
public boolean isOpaqueCube(IBlockState state)
{
return false;
}
@Override
public Item getItemDropped(IBlockState state, Random random, int fortune)
{
return null;
}
@Override
public EnumBlockRenderType getRenderType(IBlockState state)
{
return EnumBlockRenderType.MODEL;
}
@SideOnly(Side.CLIENT)
@Override
public BlockRenderLayer getBlockLayer()
{
return BlockRenderLayer.CUTOUT;
}
@Override
public float getPlayerRelativeBlockHardness(IBlockState state, EntityPlayer player, World world, BlockPos pos)
{
TileEntity tile = world.getTileEntity(pos);
return SecurityUtils.canAccess(player, tile) ? super.getPlayerRelativeBlockHardness(state, player, world, pos) : 0.0F;
}
@Override
public float getExplosionResistance(World world, BlockPos pos, Entity exploder, Explosion explosion)
{
IBlockState state = world.getBlockState(pos);
if(MachineType.get(getMachineBlock(), state.getBlock().getMetaFromState(state)) != MachineType.PERSONAL_CHEST)
{
return blockResistance;
}
else {
return -1;
}
}
@Override
public boolean removedByPlayer(IBlockState state, World world, BlockPos pos, EntityPlayer player, boolean willHarvest)
{
if(!player.capabilities.isCreativeMode && !world.isRemote && willHarvest)
{
TileEntityBasicBlock tileEntity = (TileEntityBasicBlock)world.getTileEntity(pos);
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.spawnEntityInWorld(entityItem);
}
return world.setBlockToAir(pos);
}
@Override
public boolean hasComparatorInputOverride(IBlockState state)
{
return true;
}
@Override
public int getComparatorInputOverride(IBlockState state, World world, BlockPos pos)
{
TileEntity tileEntity = world.getTileEntity(pos);
if(tileEntity instanceof TileEntityFluidTank)
{
return ((TileEntityFluidTank)tileEntity).getRedstoneLevel();
}
if(tileEntity instanceof TileEntityLaserAmplifier)
{
TileEntityLaserAmplifier amplifier = (TileEntityLaserAmplifier)tileEntity;
if(amplifier.outputMode == TileEntityLaserAmplifier.RedstoneOutput.ENERGY_CONTENTS)
{
return amplifier.getRedstoneLevel();
}
else {
return getWeakPower(state, world, pos, null);
}
}
return 0;
}
private boolean manageInventory(EntityPlayer player, TileEntityFluidTank tileEntity, EnumHand hand, ItemStack itemStack)
{
ItemStack copyStack = StackUtils.size(itemStack.copy(), 1);
if(FluidContainerUtils.isFluidContainer(itemStack))
{
IFluidHandler handler = FluidUtil.getFluidHandler(copyStack);
if(FluidUtil.getFluidContained(copyStack) == null)
{
if(tileEntity.fluidTank.getFluid() != null)
{
int filled = handler.fill(tileEntity.fluidTank.getFluid(), !player.capabilities.isCreativeMode);
if(filled > 0)
{
if(itemStack.stackSize == 1)
{
player.setHeldItem(hand, copyStack);
}
else if(itemStack.stackSize > 1 && player.inventory.addItemStackToInventory(copyStack))
{
itemStack.stackSize--;
}
if(tileEntity.tier != FluidTankTier.CREATIVE)
{
tileEntity.fluidTank.drain(filled, true);
}
return true;
}
}
}
else {
FluidStack itemFluid = FluidUtil.getFluidContained(copyStack);
int needed = tileEntity.getCurrentNeeded();
if(tileEntity.fluidTank.getFluid() != null && !tileEntity.fluidTank.getFluid().isFluidEqual(itemFluid))
{
return false;
}
boolean filled = false;
FluidStack drained = handler.drain(needed, !player.capabilities.isCreativeMode);
if(copyStack.stackSize == 0)
{
copyStack = null;
}
if(drained != null)
{
if(player.capabilities.isCreativeMode)
{
filled = true;
}
else {
if(copyStack != null)
{
if(itemStack.stackSize == 1)
{
player.setHeldItem(hand, copyStack);
filled = true;
}
else {
if(player.inventory.addItemStackToInventory(copyStack))
{
itemStack.stackSize--;
filled = true;
}
}
}
else {
itemStack.stackSize--;
if(itemStack.stackSize == 0)
{
player.setHeldItem(hand, null);
}
filled = true;
}
}
if(filled)
{
int toFill = tileEntity.fluidTank.getCapacity()-tileEntity.fluidTank.getFluidAmount();
if(tileEntity.tier != FluidTankTier.CREATIVE)
{
toFill = Math.min(toFill, drained.amount);
}
tileEntity.fluidTank.fill(PipeUtils.copy(drained, toFill), true);
if(drained.amount-toFill > 0)
{
tileEntity.pushUp(PipeUtils.copy(itemFluid, drained.amount-toFill), true);
}
return true;
}
}
}
}
return false;
}
@Override
public void neighborChanged(IBlockState state, World world, BlockPos pos, Block neighborBlock)
{
if(!world.isRemote)
{
TileEntity tileEntity = world.getTileEntity(pos);
if(tileEntity instanceof TileEntityBasicBlock)
{
((TileEntityBasicBlock)tileEntity).onNeighborChange(neighborBlock);
}
if(tileEntity instanceof TileEntityLogisticalSorter)
{
TileEntityLogisticalSorter sorter = (TileEntityLogisticalSorter)tileEntity;
if(!sorter.hasInventory())
{
for(EnumFacing dir : EnumFacing.VALUES)
{
TileEntity tile = Coord4D.get(tileEntity).offset(dir).getTileEntity(world);
if(tile instanceof IInventory)
{
sorter.setFacing((short)dir.getOpposite().ordinal());
return;
}
}
}
}
}
}
@Override
public ItemStack getPickBlock(IBlockState state, RayTraceResult target, World world, BlockPos pos, EntityPlayer player)
{
TileEntityBasicBlock tileEntity = (TileEntityBasicBlock)world.getTileEntity(pos);
ItemStack itemStack = new ItemStack(this, 1, state.getBlock().getMetaFromState(state));
if(itemStack.getTagCompound() == null)
{
itemStack.setTagCompound(new NBTTagCompound());
}
if(tileEntity instanceof TileEntityFluidTank)
{
ITierItem tierItem = (ITierItem)itemStack.getItem();
tierItem.setBaseTier(itemStack, ((TileEntityFluidTank)tileEntity).tier.getBaseTier());
}
if(tileEntity instanceof ISecurityTile)
{
ISecurityItem securityItem = (ISecurityItem)itemStack.getItem();
if(securityItem.hasSecurity(itemStack))
{
securityItem.setOwner(itemStack, ((ISecurityTile)tileEntity).getSecurity().getOwner());
securityItem.setSecurity(itemStack, ((ISecurityTile)tileEntity).getSecurity().getMode());
}
}
if(tileEntity instanceof IUpgradeTile)
{
((IUpgradeTile)tileEntity).getComponent().write(ItemDataUtils.getDataMap(itemStack));
}
if(tileEntity instanceof ISideConfiguration)
{
ISideConfiguration config = (ISideConfiguration)tileEntity;
config.getConfig().write(ItemDataUtils.getDataMap(itemStack));
config.getEjector().write(ItemDataUtils.getDataMap(itemStack));
}
if(tileEntity instanceof ISustainedData)
{
((ISustainedData)tileEntity).writeSustainedData(itemStack);
}
if(tileEntity instanceof IRedstoneControl)
{
IRedstoneControl control = (IRedstoneControl)tileEntity;
ItemDataUtils.setInt(itemStack, "controlType", control.getControlType().ordinal());
}
if(tileEntity instanceof IStrictEnergyStorage)
{
IEnergizedItem energizedItem = (IEnergizedItem)itemStack.getItem();
energizedItem.setEnergy(itemStack, ((IStrictEnergyStorage)tileEntity).getEnergy());
}
if(tileEntity instanceof TileEntityContainerBlock && ((TileEntityContainerBlock)tileEntity).inventory.length > 0)
{
ISustainedInventory inventory = (ISustainedInventory)itemStack.getItem();
inventory.setInventory(((ISustainedInventory)tileEntity).getInventory(), itemStack);
}
if(((ISustainedTank)itemStack.getItem()).hasTank(itemStack))
{
if(tileEntity instanceof ISustainedTank)
{
if(((ISustainedTank)tileEntity).getFluidStack() != null)
{
((ISustainedTank)itemStack.getItem()).setFluidStack(((ISustainedTank)tileEntity).getFluidStack(), itemStack);
}
}
}
if(tileEntity instanceof TileEntityFactory)
{
IFactory factoryItem = (IFactory)itemStack.getItem();
factoryItem.setRecipeType(((TileEntityFactory)tileEntity).recipeType.ordinal(), itemStack);
}
return itemStack;
}
@Override
public boolean canConnectRedstone(IBlockState state, IBlockAccess world, BlockPos pos, EnumFacing side)
{
MachineType type = MachineType.get(getMachineBlock(), state.getBlock().getMetaFromState(state));
switch(type)
{
case LASER_AMPLIFIER:
return true;
default:
return false;
}
}
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.spawnEntityInWorld(entityItem);
}
return itemStack;
}
@Override
public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess world, BlockPos pos)
{
MachineType type = MachineType.get(getMachineBlock(), state.getBlock().getMetaFromState(state));
if(type == null)
{
return super.getBoundingBox(state, world, pos);
}
switch(type)
{
case CHARGEPAD:
return CHARGEPAD_BOUNDS;
case FLUID_TANK:
return TANK_BOUNDS;
default:
return super.getBoundingBox(state, world, pos);
}
}
@Override
public boolean isFullCube(IBlockState state)
{
return false;
}
@Override
public AxisAlignedBB getCollisionBoundingBox(IBlockState state, World world, BlockPos pos)
{
if(world.getTileEntity(pos) instanceof TileEntityChargepad)
{
return null;
}
return super.getCollisionBoundingBox(state, world, pos);
}
@Override
public boolean isSideSolid(IBlockState state, IBlockAccess world, BlockPos pos, EnumFacing side)
{
MachineType type = MachineType.get(getMachineBlock(), state.getBlock().getMetaFromState(state));
switch(type)
{
case CHARGEPAD:
case PERSONAL_CHEST:
return false;
case FLUID_TANK:
return side == EnumFacing.UP || side == EnumFacing.DOWN;
default:
return true;
}
}
@Override
public CTMData getCTMData(IBlockState state)
{
return ctmData[state.getBlock().getMetaFromState(state)];
}
@Override
public String getOverrideTexture(IBlockState state, EnumFacing side)
{
return null;
}
@Override
public PropertyEnum<MachineType> getTypeProperty()
{
return getMachineBlock().getProperty();
}
@Override
public EnumFacing[] getValidRotations(World world, BlockPos pos)
{
TileEntity tile = world.getTileEntity(pos);
EnumFacing[] valid = new EnumFacing[6];
if(tile instanceof TileEntityBasicBlock)
{
TileEntityBasicBlock basicTile = (TileEntityBasicBlock)tile;
for(EnumFacing dir : EnumFacing.VALUES)
{
if(basicTile.canSetFacing(dir.ordinal()))
{
valid[dir.ordinal()] = dir;
}
}
}
return valid;
}
@Override
public boolean rotateBlock(World world, BlockPos pos, EnumFacing axis)
{
TileEntity tile = world.getTileEntity(pos);
if(tile instanceof TileEntityBasicBlock)
{
TileEntityBasicBlock basicTile = (TileEntityBasicBlock)tile;
if(basicTile.canSetFacing(axis.ordinal()))
{
basicTile.setFacing((short)axis.ordinal());
return true;
}
}
return false;
}
@Override
public int getWeakPower(IBlockState state, IBlockAccess world, BlockPos pos, EnumFacing side)
{
TileEntity tile = world.getTileEntity(pos);
if(tile instanceof TileEntityLaserAmplifier)
{
return ((TileEntityLaserAmplifier)tile).emittingRedstone ? 15 : 0;
}
return 0;
}
}