package mcjty.rftools.blocks.screens; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import mcjty.lib.varia.BlockTools; import mcjty.rftools.Achievements; import mcjty.rftools.RFTools; import mcjty.rftools.blocks.GenericRFToolsBlock; import mcp.mobius.waila.api.IWailaConfigHandler; import mcp.mobius.waila.api.IWailaDataAccessor; import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Items; import net.minecraft.inventory.Container; import net.minecraft.item.ItemDye; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.EnumChatFormatting; import net.minecraft.util.MovingObjectPosition; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; import net.minecraftforge.common.util.Constants; import net.minecraftforge.common.util.ForgeDirection; import org.lwjgl.input.Keyboard; import java.util.List; public class ScreenBlock extends GenericRFToolsBlock { public ScreenBlock(String blockName, Class<? extends ScreenTileEntity> clazz) { super(Material.iron, clazz, true); float width = 0.5F; float height = 1.0F; this.setBlockBounds(0.5F - width, 0.0F, 0.5F - width, 0.5F + width, height, 0.5F + width); setBlockName(blockName); setCreativeTab(RFTools.tabRfTools); } @SideOnly(Side.CLIENT) @Override public List<String> getWailaBody(ItemStack itemStack, List<String> currenttip, IWailaDataAccessor accessor, IWailaConfigHandler config) { super.getWailaBody(itemStack, currenttip, accessor, config); NBTTagCompound tagCompound = accessor.getNBTData(); if (tagCompound != null) { boolean connected = tagCompound.getBoolean("connected"); if (connected) { currenttip.add(EnumChatFormatting.YELLOW + "[CONNECTED]"); } boolean power = tagCompound.getBoolean("powerOn"); if (power) { currenttip.add(EnumChatFormatting.YELLOW + "[POWER]"); } int rfPerTick = ((ScreenTileEntity) accessor.getTileEntity()).getTotalRfPerTick(); currenttip.add(EnumChatFormatting.GREEN + (power ? "Consuming " : "Needs ") + rfPerTick + " RF/tick"); } return currenttip; } @Override public void onBlockClicked(World world, int x, int y, int z, EntityPlayer player) { if (world.isRemote) { MovingObjectPosition mouseOver = Minecraft.getMinecraft().objectMouseOver; ScreenTileEntity screenTileEntity = (ScreenTileEntity) world.getTileEntity(x, y, z); screenTileEntity.hitScreenClient(mouseOver.hitVec.xCoord - x, mouseOver.hitVec.yCoord - y, mouseOver.hitVec.zCoord - z, mouseOver.sideHit); } } private void setInvisibleBlockSafe(World world, int x, int y, int z, int dx, int dy, int dz, int meta) { int yy = y + dy; if (yy < 0 || yy >= world.getHeight()) { return; } int xx = x + dx; int zz = z + dz; if (world.isAirBlock(xx, yy, zz)) { world.setBlock(xx, yy, zz, ScreenSetup.screenHitBlock, meta, 3); ScreenHitTileEntity screenHitTileEntity = (ScreenHitTileEntity) world.getTileEntity(xx, yy, zz); screenHitTileEntity.setRelativeLocation(-dx, -dy, -dz); } } private void setInvisibleBlocks(World world, int x, int y, int z, int size) { int meta = world.getBlockMetadata(x, y, z); if (meta == 2) { for (int i = 0 ; i <= size ; i++) { for (int j = 0 ; j <= size ; j++) { if (i != 0 || j != 0) { setInvisibleBlockSafe(world, x, y, z, -i, -j, 0, meta); } } } } if (meta == 3) { for (int i = 0 ; i <= size ; i++) { for (int j = 0 ; j <= size ; j++) { if (i != 0 || j != 0) { setInvisibleBlockSafe(world, x, y, z, i, -j, 0, meta); } } } } if (meta == 4) { for (int i = 0 ; i <= size ; i++) { for (int j = 0 ; j <= size ; j++) { if (i != 0 || j != 0) { setInvisibleBlockSafe(world, x, y, z, 0, -i, j, meta); } } } } if (meta == 5) { for (int i = 0 ; i <= size ; i++) { for (int j = 0 ; j <= size ; j++) { if (i != 0 || j != 0) { setInvisibleBlockSafe(world, x, y, z, 0, -i, -j, meta); } } } } } private void clearInvisibleBlockSafe(World world, int x, int y, int z) { if (y < 0 || y >= world.getHeight()) { return; } if (world.getBlock(x, y, z) == ScreenSetup.screenHitBlock) { world.setBlockToAir(x, y, z); } } private void clearInvisibleBlocks(World world, int x, int y, int z, int meta, int size) { if (meta == 2) { for (int i = 0 ; i <= size ; i++) { for (int j = 0 ; j <= size ; j++) { if (i != 0 || j != 0) { clearInvisibleBlockSafe(world, x - i, y - j, z); } } } } if (meta == 3) { for (int i = 0 ; i <= size ; i++) { for (int j = 0 ; j <= size ; j++) { if (i != 0 || j != 0) { clearInvisibleBlockSafe(world, x + i, y - j, z); } } } } if (meta == 4) { for (int i = 0 ; i <= size ; i++) { for (int j = 0 ; j <= size ; j++) { if (i != 0 || j != 0) { clearInvisibleBlockSafe(world, x, y - i, z + j); } } } } if (meta == 5) { for (int i = 0 ; i <= size ; i++) { for (int j = 0 ; j <= size ; j++) { if (i != 0 || j != 0) { clearInvisibleBlockSafe(world, x, y - i, z - j); } } } } } private static class Setup { private final boolean transparent; private final int size; public Setup(int size, boolean transparent) { this.size = size; this.transparent = transparent; } public int getSize() { return size; } public boolean isTransparent() { return transparent; } } private static Setup transitions[] = new Setup[] { new Setup(ScreenTileEntity.SIZE_NORMAL, false), new Setup(ScreenTileEntity.SIZE_NORMAL, true), new Setup(ScreenTileEntity.SIZE_LARGE, false), new Setup(ScreenTileEntity.SIZE_LARGE, true), new Setup(ScreenTileEntity.SIZE_HUGE, false), new Setup(ScreenTileEntity.SIZE_HUGE, true), }; @Override protected boolean wrenchUse(World world, int x, int y, int z, EntityPlayer player) { ScreenTileEntity screenTileEntity = (ScreenTileEntity) world.getTileEntity(x, y, z); int meta = world.getBlockMetadata(x, y, z); clearInvisibleBlocks(world, x, y, z, meta, screenTileEntity.getSize()); for (int i = 0 ; i < transitions.length ; i++) { Setup setup = transitions[i]; if (setup.isTransparent() == screenTileEntity.isTransparent() && setup.getSize() == screenTileEntity.getSize()) { Setup next = transitions[(i+1) % transitions.length]; screenTileEntity.setTransparent(next.isTransparent()); screenTileEntity.setSize(next.getSize()); setInvisibleBlocks(world, x, y, z, screenTileEntity.getSize()); break; } } return true; } @Override protected boolean openGui(World world, int x, int y, int z, EntityPlayer player) { ItemStack itemStack = player.getHeldItem(); if (itemStack != null && itemStack.getItem() == Items.dye) { int damage = itemStack.getItemDamage(); if (damage < 0) { damage = 0; } else if (damage > 15) { damage = 15; } int color = ItemDye.field_150922_c[damage]; ScreenTileEntity screenTileEntity = (ScreenTileEntity) world.getTileEntity(x, y, z); screenTileEntity.setColor(color); return true; } else { return super.openGui(world, x, y, z, player); } } @Override public void registerBlockIcons(IIconRegister iconRegister) { iconSide = iconRegister.registerIcon(RFTools.MODID + ":" + getSideIconName()); } @Override public String getSideIconName() { return "screenFrame_icon"; } /** * Updates the blocks bounds based on its current state. Args: world, x, y, z */ @Override public void setBlockBoundsBasedOnState(IBlockAccess world, int x, int y, int z) { int meta = world.getBlockMetadata(x, y, z); this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); if (meta == ForgeDirection.NORTH.ordinal()) { this.setBlockBounds(0.0F, 0.0F, 1.0F - 0.125F, 1.0F, 1.0F, 1.0F); } if (meta == ForgeDirection.SOUTH.ordinal()) { this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 0.125F); } if (meta == ForgeDirection.WEST.ordinal()) { this.setBlockBounds(1.0F - 0.125F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); } if (meta == ForgeDirection.EAST.ordinal()) { this.setBlockBounds(0.0F, 0.0F, 0.0F, 0.125F, 1.0F, 1.0F); } } /** * Returns the bounding box of the wired rectangular prism to render. */ @Override @SideOnly(Side.CLIENT) public AxisAlignedBB getSelectedBoundingBoxFromPool(World world, int x, int y, int z) { this.setBlockBoundsBasedOnState(world, x, y, z); return super.getSelectedBoundingBoxFromPool(world, x, y, z); } /** * The type of render function that is called for this block */ @Override public int getRenderType() { return -1; } /** * If this block doesn't render as an ordinary block it will return False (examples: signs, buttons, stairs, etc) */ @Override public boolean renderAsNormalBlock() { return false; } @Override public boolean getBlocksMovement(IBlockAccess world, int x, int y, int z) { return true; } /** * Is this block (a) opaque and (b) a full 1m cube? This determines whether or not to render the shared face of two * adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block. */ @Override public boolean isOpaqueCube() { return false; } @Override public int getGuiID() { return RFTools.GUI_SCREEN; } @SideOnly(Side.CLIENT) @Override public void addInformation(ItemStack itemStack, EntityPlayer player, List list, boolean whatIsThis) { super.addInformation(itemStack, player, list, whatIsThis); NBTTagCompound tagCompound = itemStack.getTagCompound(); if (tagCompound != null) { int size; if (tagCompound.hasKey("large")) { size = tagCompound.getBoolean("large") ? ScreenTileEntity.SIZE_LARGE : ScreenTileEntity.SIZE_NORMAL; } else { size = tagCompound.getInteger("size"); } boolean transparent = tagCompound.getBoolean("transparent"); if (size == ScreenTileEntity.SIZE_HUGE) { list.add(EnumChatFormatting.BLUE + "Huge screen."); } else if (size == ScreenTileEntity.SIZE_LARGE) { list.add(EnumChatFormatting.BLUE + "Large screen."); } if (transparent) { list.add(EnumChatFormatting.BLUE + "Transparent screen."); } int rc = 0; NBTTagList bufferTagList = tagCompound.getTagList("Items", Constants.NBT.TAG_COMPOUND); for (int i = 0 ; i < bufferTagList.tagCount() ; i++) { NBTTagCompound tag = bufferTagList.getCompoundTagAt(i); if (tag != null) { ItemStack stack = ItemStack.loadItemStackFromNBT(tag); if (stack != null) { rc++; } } } list.add(EnumChatFormatting.BLUE + String.valueOf(rc) + " modules"); } if (Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown(Keyboard.KEY_RSHIFT)) { list.add(EnumChatFormatting.WHITE + "This is a modular screen. As such it doesn't show anything."); list.add(EnumChatFormatting.WHITE + "You must insert modules to control what you can see."); list.add(EnumChatFormatting.WHITE + "This screen cannot be directly powered. It has to be remotely"); list.add(EnumChatFormatting.WHITE + "powered by a nearby Screen Controller."); } else { list.add(EnumChatFormatting.WHITE + RFTools.SHIFT_MESSAGE); } } @Override protected ForgeDirection getOrientation(int x, int y, int z, EntityLivingBase entityLivingBase) { return BlockTools.determineOrientationHoriz(entityLivingBase); } @Override public void onBlockPlacedBy(World world, int x, int y, int z, EntityLivingBase entityLivingBase, ItemStack itemStack) { super.onBlockPlacedBy(world, x, y, z, entityLivingBase, itemStack); if (entityLivingBase instanceof EntityPlayer) { Achievements.trigger((EntityPlayer) entityLivingBase, Achievements.clearVision); } TileEntity tileEntity = world.getTileEntity(x, y, z); if (tileEntity instanceof ScreenTileEntity) { ScreenTileEntity screenTileEntity = (ScreenTileEntity) tileEntity; if (screenTileEntity.getSize() > ScreenTileEntity.SIZE_NORMAL) { setInvisibleBlocks(world, x, y, z, screenTileEntity.getSize()); } } } @Override public void breakBlock(World world, int x, int y, int z, Block block, int meta) { TileEntity te = world.getTileEntity(x, y, z); if (te instanceof ScreenTileEntity) { ScreenTileEntity screenTileEntity = (ScreenTileEntity) te; if (screenTileEntity.getSize() > ScreenTileEntity.SIZE_NORMAL) { clearInvisibleBlocks(world, x, y, z, meta, screenTileEntity.getSize()); } } super.breakBlock(world, x, y, z, block, meta); } @Override @SideOnly(Side.CLIENT) public GuiContainer createClientGui(EntityPlayer entityPlayer, TileEntity tileEntity) { ScreenTileEntity screenTileEntity = (ScreenTileEntity) tileEntity; ScreenContainer screenContainer = new ScreenContainer(entityPlayer, screenTileEntity); return new GuiScreen(screenTileEntity, screenContainer); } @Override public Container createServerContainer(EntityPlayer entityPlayer, TileEntity tileEntity) { return new ScreenContainer(entityPlayer, (ScreenTileEntity) tileEntity); } }