mirror of
				https://github.com/SquidDev-CC/CC-Tweaked
				synced 2025-10-31 13:42:59 +00:00 
			
		
		
		
	Add basic support for fancy rendering of printouts
- When held in first-person, single pages are displayed like a map. - When placed in an item frame, the page is drawn instead of the actual item.
This commit is contained in:
		| @@ -20,10 +20,9 @@ import java.io.IOException; | ||||
|  | ||||
| public class GuiPrintout extends GuiContainer | ||||
| { | ||||
|     private static final ResourceLocation background = new ResourceLocation( "computercraft", "textures/gui/printout.png" ); | ||||
|      | ||||
|     private static final int xSize = 172; | ||||
|     private static final int ySize = 209; | ||||
|     public static final ResourceLocation BACKGROUND = new ResourceLocation( "computercraft", "textures/gui/printout.png" ); | ||||
|     public static final int X_SIZE = 172; | ||||
|     public static final int Y_SIZE = 209; | ||||
|      | ||||
|     private final boolean m_book; | ||||
|     private final int m_pages; | ||||
| @@ -142,57 +141,57 @@ public class GuiPrintout extends GuiContainer | ||||
|          | ||||
|         // Draw the printout | ||||
|         GlStateManager.color( 1.0f, 1.0f, 1.0f, 1.0f ); | ||||
|         this.mc.getTextureManager().bindTexture( background ); | ||||
|         this.mc.getTextureManager().bindTexture( BACKGROUND ); | ||||
|          | ||||
|         int startY = (height - ySize) / 2; | ||||
|         //int startX = (width - xSize) / 2 - (m_page * 8); | ||||
|         int startX = (width - (xSize + (m_pages - 1)*8)) / 2; | ||||
|         int startY = (height - Y_SIZE) / 2; | ||||
|         //int startX = (width - X_SIZE) / 2 - (m_page * 8); | ||||
|         int startX = (width - (X_SIZE + (m_pages - 1)*8)) / 2; | ||||
|          | ||||
|         if( m_book ) | ||||
|         { | ||||
|             // Border | ||||
|             drawTexturedModalRect( startX - 8, startY - 8, xSize + 48, 0, 12, ySize + 24); | ||||
|             drawTexturedModalRect( startX + xSize + (m_pages - 1)*8 - 4, startY - 8, xSize + 48 + 12, 0, 12, ySize + 24); | ||||
|             drawTexturedModalRect( startX - 8, startY - 8, X_SIZE + 48, 0, 12, Y_SIZE + 24); | ||||
|             drawTexturedModalRect( startX + X_SIZE + (m_pages - 1)*8 - 4, startY - 8, X_SIZE + 48 + 12, 0, 12, Y_SIZE + 24); | ||||
|              | ||||
|             drawTexturedModalRect( startX, startY - 8, 0, ySize, xSize, 12); | ||||
|             drawTexturedModalRect( startX, startY + ySize - 4, 0, ySize + 12, xSize, 12); | ||||
|             drawTexturedModalRect( startX, startY - 8, 0, Y_SIZE, X_SIZE, 12); | ||||
|             drawTexturedModalRect( startX, startY + Y_SIZE - 4, 0, Y_SIZE + 12, X_SIZE, 12); | ||||
|             for( int n=1; n<m_pages; ++n ) | ||||
|             { | ||||
|                 drawTexturedModalRect( startX + xSize + (n-1)*8, startY - 8, 0, ySize, 8, 12); | ||||
|                 drawTexturedModalRect( startX + xSize + (n-1)*8, startY + ySize - 4, 0, ySize + 12, 8, 12); | ||||
|                 drawTexturedModalRect( startX + X_SIZE + (n-1)*8, startY - 8, 0, Y_SIZE, 8, 12); | ||||
|                 drawTexturedModalRect( startX + X_SIZE + (n-1)*8, startY + Y_SIZE - 4, 0, Y_SIZE + 12, 8, 12); | ||||
|             } | ||||
|         } | ||||
|              | ||||
|         // Left half | ||||
|         if( m_page == 0 ) | ||||
|         {             | ||||
|             drawTexturedModalRect( startX, startY, 24, 0, xSize / 2, ySize); | ||||
|             drawTexturedModalRect( startX, startY, 0, 0, 12, ySize); | ||||
|             drawTexturedModalRect( startX, startY, 24, 0, X_SIZE / 2, Y_SIZE ); | ||||
|             drawTexturedModalRect( startX, startY, 0, 0, 12, Y_SIZE ); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             drawTexturedModalRect( startX, startY, 0, 0, 12, ySize); | ||||
|             drawTexturedModalRect( startX, startY, 0, 0, 12, Y_SIZE ); | ||||
|             for( int n=1; n<m_page; ++n ) | ||||
|             { | ||||
|                 drawTexturedModalRect( startX + n*8, startY, 12, 0, 12, ySize);                 | ||||
|                 drawTexturedModalRect( startX + n*8, startY, 12, 0, 12, Y_SIZE );                 | ||||
|             } | ||||
|             drawTexturedModalRect( startX + m_page*8, startY, 24, 0, xSize / 2, ySize); | ||||
|             drawTexturedModalRect( startX + m_page*8, startY, 24, 0, X_SIZE / 2, Y_SIZE ); | ||||
|         } | ||||
|          | ||||
|         // Right half | ||||
|         if( m_page == (m_pages - 1) ) | ||||
|         { | ||||
|             drawTexturedModalRect( startX + m_page*8 + xSize/2, startY, 24 + xSize / 2, 0, xSize / 2, ySize); | ||||
|             drawTexturedModalRect( startX + m_page*8 + (xSize - 12), startY, 24 + xSize + 12, 0, 12, ySize); | ||||
|             drawTexturedModalRect( startX + m_page*8 + X_SIZE /2, startY, 24 + X_SIZE / 2, 0, X_SIZE / 2, Y_SIZE ); | ||||
|             drawTexturedModalRect( startX + m_page*8 + (X_SIZE - 12), startY, 24 + X_SIZE + 12, 0, 12, Y_SIZE ); | ||||
|         } | ||||
|         else  | ||||
|         { | ||||
|             drawTexturedModalRect( startX + (m_pages - 1)*8 + (xSize - 12), startY, 24 + xSize + 12, 0, 12, ySize); | ||||
|             drawTexturedModalRect( startX + (m_pages - 1)*8 + (X_SIZE - 12), startY, 24 + X_SIZE + 12, 0, 12, Y_SIZE ); | ||||
|             for( int n=m_pages-2; n>=m_page; --n ) | ||||
|             { | ||||
|                 drawTexturedModalRect( startX + n*8 + (xSize - 12), startY, 24 + xSize, 0, 12, ySize); | ||||
|                 drawTexturedModalRect( startX + n*8 + (X_SIZE - 12), startY, 24 + X_SIZE, 0, 12, Y_SIZE ); | ||||
|             } | ||||
|             drawTexturedModalRect( startX + m_page*8 + xSize/2, startY, 24 + xSize / 2, 0, xSize / 2, ySize); | ||||
|             drawTexturedModalRect( startX + m_page*8 + X_SIZE /2, startY, 24 + X_SIZE / 2, 0, X_SIZE / 2, Y_SIZE ); | ||||
|         } | ||||
|  | ||||
|         // Draw the text | ||||
|   | ||||
| @@ -8,6 +8,7 @@ package dan200.computercraft.client.proxy; | ||||
|  | ||||
| import dan200.computercraft.ComputerCraft; | ||||
| import dan200.computercraft.client.gui.*; | ||||
| import dan200.computercraft.client.render.ItemPrintoutRenderer; | ||||
| import dan200.computercraft.client.render.TileEntityMonitorRenderer; | ||||
| import dan200.computercraft.shared.computer.blocks.ComputerState; | ||||
| import dan200.computercraft.shared.computer.blocks.TileComputer; | ||||
| @@ -442,6 +443,7 @@ public class ComputerCraftProxyClient extends ComputerCraftProxyCommon | ||||
|     { | ||||
|         ForgeHandlers handlers = new ForgeHandlers(); | ||||
|         MinecraftForge.EVENT_BUS.register( handlers ); | ||||
|         MinecraftForge.EVENT_BUS.register( new ItemPrintoutRenderer() ); | ||||
|     } | ||||
|  | ||||
|     public class ForgeHandlers | ||||
|   | ||||
| @@ -0,0 +1,219 @@ | ||||
| package dan200.computercraft.client.render; | ||||
|  | ||||
| import dan200.computercraft.ComputerCraft; | ||||
| import dan200.computercraft.client.gui.FixedWidthFontRenderer; | ||||
| import dan200.computercraft.client.gui.GuiPrintout; | ||||
| import dan200.computercraft.core.terminal.TextBuffer; | ||||
| import dan200.computercraft.shared.media.items.ItemPrintout; | ||||
| import dan200.computercraft.shared.util.Palette; | ||||
| import net.minecraft.client.Minecraft; | ||||
| import net.minecraft.client.renderer.BufferBuilder; | ||||
| import net.minecraft.client.renderer.GlStateManager; | ||||
| import net.minecraft.client.renderer.ItemRenderer; | ||||
| import net.minecraft.client.renderer.Tessellator; | ||||
| import net.minecraft.client.renderer.vertex.DefaultVertexFormats; | ||||
| import net.minecraft.entity.player.EntityPlayer; | ||||
| import net.minecraft.item.ItemStack; | ||||
| import net.minecraft.util.EnumHand; | ||||
| import net.minecraft.util.EnumHandSide; | ||||
| import net.minecraft.util.math.MathHelper; | ||||
| import net.minecraftforge.client.event.RenderItemInFrameEvent; | ||||
| import net.minecraftforge.client.event.RenderSpecificHandEvent; | ||||
| import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; | ||||
| import org.lwjgl.opengl.GL11; | ||||
|  | ||||
| import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_HEIGHT; | ||||
| import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_WIDTH; | ||||
| import static dan200.computercraft.shared.media.items.ItemPrintout.LINES_PER_PAGE; | ||||
| import static dan200.computercraft.shared.media.items.ItemPrintout.LINE_MAX_LENGTH; | ||||
|  | ||||
| public class ItemPrintoutRenderer | ||||
| { | ||||
|     @SubscribeEvent | ||||
|     public void onRenderInHand( RenderSpecificHandEvent event ) | ||||
|     { | ||||
|         ItemStack stack = event.getItemStack(); | ||||
|         if( stack.getItem() != ComputerCraft.Items.printout ) return; | ||||
|  | ||||
|         // We only allow single pages to be viewed in-hand for now | ||||
|         if( ItemPrintout.getType( stack ) != ItemPrintout.Type.Single ) return; | ||||
|  | ||||
|         event.setCanceled( true ); | ||||
|  | ||||
|         EntityPlayer player = Minecraft.getMinecraft().player; | ||||
|  | ||||
|         GlStateManager.pushMatrix(); | ||||
|         if( event.getHand() == EnumHand.MAIN_HAND && player.getHeldItemOffhand().isEmpty() ) | ||||
|         { | ||||
|             renderPrintoutFirstPersonCentre( | ||||
|                 event.getInterpolatedPitch(), | ||||
|                 event.getEquipProgress(), | ||||
|                 event.getSwingProgress(), | ||||
|                 stack | ||||
|             ); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             renderPrintoutFirstPersonSide( | ||||
|                 event.getHand() == EnumHand.MAIN_HAND ? player.getPrimaryHand() : player.getPrimaryHand().opposite(), | ||||
|                 event.getEquipProgress(), | ||||
|                 event.getSwingProgress(), | ||||
|                 stack | ||||
|             ); | ||||
|         } | ||||
|         GlStateManager.popMatrix(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Renders a pocket computer to one side of the player. | ||||
|      * | ||||
|      * @param side          The side to render on | ||||
|      * @param equipProgress The equip progress of this item | ||||
|      * @param swingProgress The swing progress of this item | ||||
|      * @param stack         The stack to render | ||||
|      * @see ItemRenderer#renderMapFirstPersonSide(float, EnumHandSide, float, ItemStack) | ||||
|      */ | ||||
|     private void renderPrintoutFirstPersonSide( EnumHandSide side, float equipProgress, float swingProgress, ItemStack stack ) | ||||
|     { | ||||
|         Minecraft minecraft = Minecraft.getMinecraft(); | ||||
|         float offset = side == EnumHandSide.RIGHT ? 1f : -1f; | ||||
|         GlStateManager.translate( offset * 0.125f, -0.125f, 0f ); | ||||
|  | ||||
|         // If the player is not invisible then render a single arm | ||||
|         if( !minecraft.player.isInvisible() ) | ||||
|         { | ||||
|             GlStateManager.pushMatrix(); | ||||
|             GlStateManager.rotate( offset * 10f, 0f, 0f, 1f ); | ||||
|             minecraft.getItemRenderer().renderArmFirstPerson( equipProgress, swingProgress, side ); | ||||
|             GlStateManager.popMatrix(); | ||||
|         } | ||||
|  | ||||
|         // Setup the appropriate transformations. This is just copied from the | ||||
|         // corresponding method in ItemRenderer.  | ||||
|         GlStateManager.pushMatrix(); | ||||
|         GlStateManager.translate( offset * 0.51f, -0.08f + equipProgress * -1.2f, -0.75f ); | ||||
|         float f1 = MathHelper.sqrt( swingProgress ); | ||||
|         float f2 = MathHelper.sin( f1 * (float) Math.PI ); | ||||
|         float f3 = -0.5f * f2; | ||||
|         float f4 = 0.4f * MathHelper.sin( f1 * ((float) Math.PI * 2f) ); | ||||
|         float f5 = -0.3f * MathHelper.sin( swingProgress * (float) Math.PI ); | ||||
|         GlStateManager.translate( offset * f3, f4 - 0.3f * f2, f5 ); | ||||
|         GlStateManager.rotate( f2 * -45f, 1f, 0f, 0f ); | ||||
|         GlStateManager.rotate( offset * f2 * -30f, 0f, 1f, 0f ); | ||||
|  | ||||
|         renderPrintoutFirstPerson( stack ); | ||||
|  | ||||
|         GlStateManager.popMatrix(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Render an item in the middle of the screen | ||||
|      * | ||||
|      * @param pitch         The pitch of the player | ||||
|      * @param equipProgress The equip progress of this item | ||||
|      * @param swingProgress The swing progress of this item | ||||
|      * @param stack         The stack to render | ||||
|      * @see ItemRenderer#renderMapFirstPerson(float, float, float) | ||||
|      */ | ||||
|     private void renderPrintoutFirstPersonCentre( float pitch, float equipProgress, float swingProgress, ItemStack stack ) | ||||
|     { | ||||
|         ItemRenderer itemRenderer = Minecraft.getMinecraft().getItemRenderer(); | ||||
|  | ||||
|         // Setup the appropriate transformations. This is just copied from the | ||||
|         // corresponding method in ItemRenderer. | ||||
|         float swingRt = MathHelper.sqrt( swingProgress ); | ||||
|         float tX = -0.2f * MathHelper.sin( swingProgress * (float) Math.PI ); | ||||
|         float tZ = -0.4f * MathHelper.sin( swingRt * (float) Math.PI ); | ||||
|         GlStateManager.translate( 0f, -tX / 2f, tZ ); | ||||
|         float pitchAngle = itemRenderer.getMapAngleFromPitch( pitch ); | ||||
|         GlStateManager.translate( 0f, 0.04f + equipProgress * -1.2f + pitchAngle * -0.5f, -0.72f ); | ||||
|         GlStateManager.rotate( pitchAngle * -85f, 1f, 0f, 0f ); | ||||
|         itemRenderer.renderArms(); | ||||
|         float rX = MathHelper.sin( swingRt * (float) Math.PI ); | ||||
|         GlStateManager.rotate( rX * 20f, 1f, 0f, 0f ); | ||||
|         GlStateManager.scale( 2f, 2f, 2f ); | ||||
|  | ||||
|         renderPrintoutFirstPerson( stack ); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     private static void renderPrintoutFirstPerson( ItemStack stack ) | ||||
|     { | ||||
|         // Setup various transformations. Note that these are partially adapated from the corresponding method | ||||
|         // in ItemRenderer.renderMapFirstPerson | ||||
|         GlStateManager.disableLighting(); | ||||
|  | ||||
|         GlStateManager.rotate( 180f, 0f, 1f, 0f ); | ||||
|         GlStateManager.rotate( 180f, 0f, 0f, 1f ); | ||||
|         GlStateManager.scale( 0.38f, 0.38f, 0.38f ); | ||||
|         GlStateManager.translate( -0.5f, -0.5f, 0.0f ); | ||||
|  | ||||
|         drawPrintout( stack ); | ||||
|  | ||||
|         GlStateManager.enableLighting(); | ||||
|     } | ||||
|  | ||||
|     @SubscribeEvent | ||||
|     public void onRenderInFrame( RenderItemInFrameEvent event ) | ||||
|     { | ||||
|         ItemStack stack = event.getItem(); | ||||
|         if( stack.getItem() != ComputerCraft.Items.printout ) return; | ||||
|  | ||||
|         // We only allow single pages to be viewed in-hand for now | ||||
|         if( ItemPrintout.getType( stack ) != ItemPrintout.Type.Single ) return; | ||||
|  | ||||
|         event.setCanceled( true ); | ||||
|  | ||||
|         GlStateManager.disableLighting(); | ||||
|  | ||||
|         // Move a little bit forward to ensure we're not clipping with the frame | ||||
|         GlStateManager.translate( 0.0f, 0.0f, -0.001f ); | ||||
|         GlStateManager.rotate( 180f, 0f, 0f, 1f ); | ||||
|         GlStateManager.translate( -0.5f, -0.5f, 0.0f ); | ||||
|  | ||||
|         drawPrintout( stack ); | ||||
|  | ||||
|         GlStateManager.enableLighting(); | ||||
|     } | ||||
|  | ||||
|     private static void drawPrintout( ItemStack stack ) | ||||
|     { | ||||
|         int xMargin = 13; | ||||
|         int yMargin = 11; | ||||
|  | ||||
|         int width = LINE_MAX_LENGTH * FONT_WIDTH + xMargin * 2; | ||||
|         int height = LINES_PER_PAGE * FONT_HEIGHT + yMargin * 2; | ||||
|         int max = Math.max( height, width ); | ||||
|  | ||||
|         // Scale the printout to fit correctly. | ||||
|         double scale = 1.0 / max; | ||||
|         GlStateManager.scale( scale, scale, scale ); | ||||
|         GlStateManager.translate( (max - width) / 2.0f, (max - height) / 2.0f, 0.0f ); | ||||
|  | ||||
|         drawBackground( 0, 0, 0.01 ); | ||||
|  | ||||
|         FixedWidthFontRenderer fontRenderer = (FixedWidthFontRenderer) ComputerCraft.getFixedWidthFontRenderer(); | ||||
|  | ||||
|         String[] text = ItemPrintout.getText( stack ); | ||||
|         String[] colours = ItemPrintout.getColours( stack ); | ||||
|         for( int line = 0; line < LINES_PER_PAGE && line < text.length; ++line ) | ||||
|         { | ||||
|             fontRenderer.drawString( new TextBuffer( text[ line ] ), xMargin, yMargin + line * FONT_HEIGHT, new TextBuffer( colours[ line ] ), null, 0, 0, false, Palette.DEFAULT ); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private static void drawBackground( double x, double y, double z ) | ||||
|     { | ||||
|         Minecraft mc = Minecraft.getMinecraft(); | ||||
|         mc.getTextureManager().bindTexture( GuiPrintout.BACKGROUND ); | ||||
|  | ||||
|         Tessellator tessellator = Tessellator.getInstance(); | ||||
|         BufferBuilder buffer = tessellator.getBuffer(); | ||||
|         buffer.begin( GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX ); | ||||
|         buffer.pos( x, y + GuiPrintout.Y_SIZE, z ).tex( 24 / 256.0, GuiPrintout.Y_SIZE / 256.0 ).endVertex(); | ||||
|         buffer.pos( x + GuiPrintout.X_SIZE, y + GuiPrintout.Y_SIZE, z ).tex( (24 + GuiPrintout.X_SIZE) / 256.0, GuiPrintout.Y_SIZE / 256.0 ).endVertex(); | ||||
|         buffer.pos( x + GuiPrintout.X_SIZE, y, z ).tex( (24 + GuiPrintout.X_SIZE) / 256.0, 0 ).endVertex(); | ||||
|         buffer.pos( x, y, z ).tex( 24 / 256.0, 0 ).endVertex(); | ||||
|         tessellator.draw(); | ||||
|     } | ||||
| } | ||||
| @@ -1,3 +1,7 @@ | ||||
| # RecordMedia (and related methods) | ||||
| public net.minecraft.item.ItemRecord field_185076_b # sound | ||||
| public net.minecraft.item.ItemRecord field_185077_c # displayName | ||||
| # ItemPocketRenderer | ||||
| public net.minecraft.client.renderer.ItemRenderer func_187466_c()V # renderArms | ||||
| public net.minecraft.client.renderer.ItemRenderer func_178100_c(F)F # getMapAngleFromPitch | ||||
| public net.minecraft.client.renderer.ItemRenderer func_187456_a(FFLnet/minecraft/util/EnumHandSide;)V # renderArmFirstPerson | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 SquidDev
					SquidDev