package mekanism.generators.common.block;
import java.util.List;
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.base.IActiveState;
import mekanism.common.block.states.BlockStateBasic;
import mekanism.common.tile.TileEntityBasicBlock;
import mekanism.common.tile.TileEntityElectricBlock;
import mekanism.common.util.MekanismUtils;
import mekanism.generators.common.GeneratorsBlocks;
import mekanism.generators.common.MekanismGenerators;
import mekanism.generators.common.block.states.BlockStateReactor;
import mekanism.generators.common.block.states.BlockStateReactor.ReactorBlock;
import mekanism.generators.common.block.states.BlockStateReactor.ReactorBlockType;
import mekanism.generators.common.tile.reactor.TileEntityReactorController;
import mekanism.generators.common.tile.reactor.TileEntityReactorLogicAdapter;
import mekanism.generators.common.tile.reactor.TileEntityReactorPort;
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.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
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.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.common.property.IExtendedBlockState;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import buildcraft.api.tools.IToolWrench;
public abstract class BlockReactor extends BlockContainer implements ICTMBlock
{
public CTMData[] ctmData = new CTMData[16];
public BlockReactor()
{
super(Material.IRON);
setHardness(3.5F);
setResistance(8F);
setCreativeTab(Mekanism.tabMekanism);
initCTMs();
}
public static BlockReactor getReactorBlock(ReactorBlock block)
{
return new BlockReactor()
{
@Override
public ReactorBlock getReactorBlock()
{
return block;
}
};
}
public abstract ReactorBlock getReactorBlock();
@Override
public IBlockState getActualState(IBlockState state, IBlockAccess worldIn, BlockPos pos)
{
TileEntity tile = worldIn.getTileEntity(pos);
if(tile instanceof TileEntityReactorController)
{
state = state.withProperty(BlockStateReactor.activeProperty, ((IActiveState)tile).getActive());
}
if(tile instanceof TileEntityReactorPort)
{
state = state.withProperty(BlockStateReactor.activeProperty, ((TileEntityReactorPort)tile).fluidEject);
}
return state;
}
public void initCTMs()
{
switch(getReactorBlock())
{
case REACTOR_BLOCK:
ctmData[0] = new CTMData(ReactorBlockType.REACTOR_CONTROLLER, ReactorBlockType.REACTOR_FRAME, ReactorBlockType.NEUTRON_CAPTURE, ReactorBlockType.REACTOR_PORT, ReactorBlockType.REACTOR_LOGIC_ADAPTER);
ctmData[1] = new CTMData(ReactorBlockType.REACTOR_CONTROLLER, ReactorBlockType.REACTOR_FRAME, ReactorBlockType.NEUTRON_CAPTURE, ReactorBlockType.REACTOR_PORT, ReactorBlockType.REACTOR_LOGIC_ADAPTER);
ctmData[2] = new CTMData(ReactorBlockType.REACTOR_CONTROLLER, ReactorBlockType.REACTOR_FRAME, ReactorBlockType.NEUTRON_CAPTURE, ReactorBlockType.REACTOR_PORT, ReactorBlockType.REACTOR_LOGIC_ADAPTER);
ctmData[3] = new CTMData(ReactorBlockType.REACTOR_CONTROLLER, ReactorBlockType.REACTOR_FRAME, ReactorBlockType.NEUTRON_CAPTURE, ReactorBlockType.REACTOR_PORT, ReactorBlockType.REACTOR_LOGIC_ADAPTER);
ctmData[4] = new CTMData(ReactorBlockType.REACTOR_CONTROLLER, ReactorBlockType.REACTOR_FRAME, ReactorBlockType.NEUTRON_CAPTURE, ReactorBlockType.REACTOR_PORT, ReactorBlockType.REACTOR_LOGIC_ADAPTER);
break;
case REACTOR_GLASS:
ctmData[0] = new CTMData(ReactorBlockType.REACTOR_GLASS, ReactorBlockType.LASER_FOCUS_MATRIX);
ctmData[1] = new CTMData(ReactorBlockType.REACTOR_GLASS, ReactorBlockType.LASER_FOCUS_MATRIX);
break;
}
}
@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 BlockStateReactor(this, getTypeProperty());
}
@Override
public IBlockState getStateFromMeta(int meta)
{
ReactorBlockType type = ReactorBlockType.get(getReactorBlock(), meta & 0xF);
return getDefaultState().withProperty(getTypeProperty(), type);
}
@Override
public int getMetaFromState(IBlockState state)
{
ReactorBlockType type = state.getValue(getTypeProperty());
return type.meta;
}
@Override
public int damageDropped(IBlockState state)
{
return state.getBlock().getMetaFromState(state);
}
@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);
}
}
}
@Override
public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer entityplayer, EnumHand hand, ItemStack stack, EnumFacing facing, float playerX, float playerY, float playerZ)
{
if(world.isRemote)
{
return true;
}
TileEntityElectricBlock tileEntity = (TileEntityElectricBlock)world.getTileEntity(pos);
int metadata = state.getBlock().getMetaFromState(state);
if(stack != null)
{
if(MekanismUtils.isBCWrench(stack.getItem()) && !stack.getUnlocalizedName().contains("omniwrench"))
{
if(entityplayer.isSneaking())
{
dismantleBlock(world, pos, false);
return true;
}
((IToolWrench)stack.getItem()).wrenchUsed(entityplayer, pos);
return true;
}
}
if(tileEntity instanceof TileEntityReactorController)
{
if(!entityplayer.isSneaking())
{
entityplayer.openGui(MekanismGenerators.instance, ReactorBlockType.get(this, metadata).guiId, world, pos.getX(), pos.getY(), pos.getZ());
return true;
}
}
if(tileEntity instanceof TileEntityReactorLogicAdapter)
{
if(!entityplayer.isSneaking())
{
entityplayer.openGui(MekanismGenerators.instance, BlockStateReactor.ReactorBlockType.get(this, metadata).guiId, world, pos.getX(), pos.getY(), pos.getZ());
return true;
}
}
return false;
}
@Override
@SideOnly(Side.CLIENT)
public void getSubBlocks(Item item, CreativeTabs creativetabs, List list)
{
for(BlockStateReactor.ReactorBlockType type : BlockStateReactor.ReactorBlockType.values())
{
if(type.blockType == getReactorBlock() && type.isValidReactorBlock())
{
list.add(new ItemStack(item, 1, type.meta));
}
}
}
@Override
public TileEntity createTileEntity(World world, IBlockState state)
{
int metadata = state.getBlock().getMetaFromState(state);
if(ReactorBlockType.get(getReactorBlock(), metadata) == null)
{
return null;
}
return ReactorBlockType.get(getReactorBlock(), metadata).create();
}
@Override
public BlockRenderLayer getBlockLayer()
{
return this == GeneratorsBlocks.Reactor ? BlockRenderLayer.CUTOUT : BlockRenderLayer.TRANSLUCENT;
}
@Override
public EnumBlockRenderType getRenderType(IBlockState state)
{
return EnumBlockRenderType.MODEL;
}
@Override
public boolean isOpaqueCube(IBlockState state)
{
return false;
}
@Override
public boolean isFullCube(IBlockState state)
{
return false;
}
/*This method is not used, metadata manipulation is required to create a Tile Entity.*/
@Override
public TileEntity createNewTileEntity(World world, int meta)
{
return null;
}
@Override
@SideOnly(Side.CLIENT)
public boolean shouldSideBeRendered(IBlockState state, IBlockAccess world, BlockPos pos, EnumFacing side)
{
int meta = state.getBlock().getMetaFromState(state);
ReactorBlockType type = ReactorBlockType.get(getReactorBlock(), meta);
if(type == ReactorBlockType.REACTOR_GLASS || type == ReactorBlockType.LASER_FOCUS_MATRIX)
{
if(!ctmData[meta].shouldRenderSide(world, pos.offset(side), side))
{
return false;
}
}
return super.shouldSideBeRendered(state, world, pos, side);
}
@Override
public int getWeakPower(IBlockState state, IBlockAccess world, BlockPos pos, EnumFacing side)
{
TileEntity tile = world.getTileEntity(pos);
if(tile instanceof TileEntityReactorLogicAdapter)
{
return ((TileEntityReactorLogicAdapter)tile).checkMode() ? 15 : 0;
}
return 0;
}
@Override
public boolean isSideSolid(IBlockState state, IBlockAccess world, BlockPos pos, EnumFacing side)
{
ReactorBlockType type = ReactorBlockType.get(getReactorBlock(), state.getBlock().getMetaFromState(state));
switch(type)
{
case REACTOR_FRAME:
case REACTOR_PORT:
case REACTOR_LOGIC_ADAPTER:
return true;
default:
return false;
}
}
@Override
public boolean canConnectRedstone(IBlockState state, IBlockAccess world, BlockPos pos, EnumFacing side)
{
ReactorBlockType type = BlockStateReactor.ReactorBlockType.get(this, state.getBlock().getMetaFromState(state));
switch(type)
{
case REACTOR_LOGIC_ADAPTER:
return true;
default:
return false;
}
}
public ItemStack dismantleBlock(World world, BlockPos pos, boolean returnBlock)
{
IBlockState state = world.getBlockState(pos);
ItemStack itemStack = new ItemStack(this, 1, state.getBlock().getMetaFromState(state));
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 CTMData getCTMData(IBlockState state)
{
return ctmData[state.getBlock().getMetaFromState(state)];
}
@Override
public String getOverrideTexture(IBlockState state, EnumFacing side)
{
ReactorBlockType type = state.getValue(getTypeProperty());
if(type == ReactorBlockType.REACTOR_CONTROLLER)
{
if(side == EnumFacing.UP)
{
return type.getName() + (state.getValue(BlockStateReactor.activeProperty) ? "_on" : "");
}
else {
return "reactor_frame";
}
}
else if(type == ReactorBlockType.REACTOR_PORT)
{
return type.getName() + (state.getValue(BlockStateReactor.activeProperty) ? "_output" : "");
}
return null;
}
@Override
public PropertyEnum<ReactorBlockType> getTypeProperty()
{
return getReactorBlock().getProperty();
}
}