mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-11-21 15:54:47 +00:00
ComputerCraft 1.79 initial upload
Added the complete source code to ComputerCraft 1.79 for Minecraft 1.8.9, plus newly written README and LICENSE files for the open source release.
This commit is contained in:
@@ -0,0 +1,151 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.client.gui;
|
||||
|
||||
import dan200.computercraft.core.terminal.TextBuffer;
|
||||
import dan200.computercraft.shared.util.Colour;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.client.renderer.WorldRenderer;
|
||||
import net.minecraft.client.renderer.texture.TextureManager;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
public class FixedWidthFontRenderer
|
||||
{
|
||||
public static ResourceLocation font = new ResourceLocation( "computercraft", "textures/gui/termFont.png" );
|
||||
public static ResourceLocation background = new ResourceLocation( "computercraft", "textures/gui/termBackground.png" );
|
||||
|
||||
public static int FONT_HEIGHT = 9;
|
||||
public static int FONT_WIDTH = 6;
|
||||
|
||||
private TextureManager m_textureManager;
|
||||
|
||||
public FixedWidthFontRenderer( TextureManager textureManager )
|
||||
{
|
||||
m_textureManager = textureManager;
|
||||
}
|
||||
|
||||
private void drawChar( WorldRenderer renderer, double x, double y, int index, int color )
|
||||
{
|
||||
int column = index % 16;
|
||||
int row = index / 16;
|
||||
Colour colour = Colour.values()[ 15 - color ];
|
||||
renderer.pos( x, y + FONT_HEIGHT, 0.0 ).tex( (double) (column * FONT_WIDTH) / 256.0, (double) ((row + 1) * FONT_HEIGHT) / 256.0 ).color( colour.getR(), colour.getG(), colour.getB(), 1.0f ).endVertex();
|
||||
renderer.pos( x + FONT_WIDTH, y + FONT_HEIGHT, 0.0 ).tex( (double) ((column + 1) * FONT_WIDTH) / 256.0, (double) ((row + 1) * FONT_HEIGHT) / 256.0 ).color( colour.getR(), colour.getG(), colour.getB(), 1.0f ).endVertex();
|
||||
renderer.pos( x + FONT_WIDTH, y, 0.0 ).tex( (double) ((column + 1) * FONT_WIDTH) / 256.0, (double) (row * FONT_HEIGHT) / 256.0 ).color( colour.getR(), colour.getG(), colour.getB(), 1.0f ).endVertex();
|
||||
renderer.pos( x, y, 0.0 ).tex( (double) (column * FONT_WIDTH) / 256.0, (double) (row * FONT_HEIGHT ) / 256.0 ).color( colour.getR(), colour.getG(), colour.getB(), 1.0f ).endVertex();
|
||||
}
|
||||
|
||||
private void drawQuad( WorldRenderer renderer, double x, double y, int color, double width )
|
||||
{
|
||||
Colour colour = Colour.values()[ 15 - color ];
|
||||
renderer.pos( x, y + FONT_HEIGHT, 0.0 ).tex( 0.0, 1.0 ).color( colour.getR(), colour.getG(), colour.getB(), 1.0f ).endVertex();
|
||||
renderer.pos( x + width, y + FONT_HEIGHT, 0.0 ).tex( 1.0, 1.0 ).color( colour.getR(), colour.getG(), colour.getB(), 1.0f ).endVertex();
|
||||
renderer.pos( x + width, y, 0.0 ).tex( 1.0, 0.0 ).color( colour.getR(), colour.getG(), colour.getB(), 1.0f ).endVertex();
|
||||
renderer.pos( x, y, 0.0 ).tex( 0.0, 0.0 ).color( colour.getR(), colour.getG(), colour.getB(), 1.0f ).endVertex();
|
||||
}
|
||||
|
||||
private boolean isGreyScale( int colour )
|
||||
{
|
||||
return (colour == 0 || colour == 15 || colour == 7 || colour == 8);
|
||||
}
|
||||
|
||||
public void drawStringBackgroundPart( int x, int y, TextBuffer backgroundColour, double leftMarginSize, double rightMarginSize, boolean greyScale )
|
||||
{
|
||||
// Draw the quads
|
||||
Tessellator tessellator = Tessellator.getInstance();
|
||||
WorldRenderer renderer = tessellator.getWorldRenderer();
|
||||
renderer.begin( GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR );
|
||||
if( leftMarginSize > 0.0 )
|
||||
{
|
||||
int colour1 = "0123456789abcdef".indexOf( backgroundColour.charAt( 0 ) );
|
||||
if( colour1 < 0 || (greyScale && !isGreyScale(colour1)) )
|
||||
{
|
||||
colour1 = 15;
|
||||
}
|
||||
drawQuad( renderer, x - leftMarginSize, y, colour1, leftMarginSize );
|
||||
}
|
||||
if( rightMarginSize > 0.0 )
|
||||
{
|
||||
int colour2 = "0123456789abcdef".indexOf( backgroundColour.charAt( backgroundColour.length() - 1 ) );
|
||||
if( colour2 < 0 || (greyScale && !isGreyScale(colour2)) )
|
||||
{
|
||||
colour2 = 15;
|
||||
}
|
||||
drawQuad( renderer, x + backgroundColour.length() * FONT_WIDTH, y, colour2, rightMarginSize );
|
||||
}
|
||||
for( int i = 0; i < backgroundColour.length(); i++ )
|
||||
{
|
||||
int colour = "0123456789abcdef".indexOf( backgroundColour.charAt( i ) );
|
||||
if( colour < 0 || ( greyScale && !isGreyScale( colour ) ) )
|
||||
{
|
||||
colour = 15;
|
||||
}
|
||||
drawQuad( renderer, x + i * FONT_WIDTH, y, colour, FONT_WIDTH );
|
||||
}
|
||||
tessellator.draw();
|
||||
}
|
||||
|
||||
public void drawStringTextPart( int x, int y, TextBuffer s, TextBuffer textColour, boolean greyScale )
|
||||
{
|
||||
// Draw the quads
|
||||
Tessellator tessellator = Tessellator.getInstance();
|
||||
WorldRenderer renderer = tessellator.getWorldRenderer();
|
||||
renderer.begin( GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR );
|
||||
for( int i = 0; i < s.length(); i++ )
|
||||
{
|
||||
// Switch colour
|
||||
int colour = "0123456789abcdef".indexOf( textColour.charAt( i ) );
|
||||
if( colour < 0 || ( greyScale && !isGreyScale( colour ) ) )
|
||||
{
|
||||
colour = 0;
|
||||
}
|
||||
|
||||
// Draw char
|
||||
int index = (int)s.charAt( i );
|
||||
if( index < 0 || index > 255 )
|
||||
{
|
||||
index = (int)'?';
|
||||
}
|
||||
drawChar( renderer, x + i * FONT_WIDTH, y, index, colour );
|
||||
}
|
||||
tessellator.draw();
|
||||
}
|
||||
|
||||
public void drawString( TextBuffer s, int x, int y, TextBuffer textColour, TextBuffer backgroundColour, double leftMarginSize, double rightMarginSize, boolean greyScale )
|
||||
{
|
||||
// Draw background
|
||||
if( backgroundColour != null )
|
||||
{
|
||||
// Bind the background texture
|
||||
m_textureManager.bindTexture( background );
|
||||
|
||||
// Draw the quads
|
||||
drawStringBackgroundPart( x, y, backgroundColour, leftMarginSize, rightMarginSize, greyScale );
|
||||
}
|
||||
|
||||
// Draw text
|
||||
if( s != null && textColour != null )
|
||||
{
|
||||
// Bind the font texture
|
||||
m_textureManager.bindTexture( font );
|
||||
|
||||
// Draw the quads
|
||||
drawStringTextPart( x, y, s, textColour, greyScale );
|
||||
}
|
||||
}
|
||||
|
||||
public int getStringWidth(String s)
|
||||
{
|
||||
if(s == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return s.length() * FONT_WIDTH;
|
||||
}
|
||||
}
|
||||
195
src/main/java/dan200/computercraft/client/gui/GuiComputer.java
Normal file
195
src/main/java/dan200/computercraft/client/gui/GuiComputer.java
Normal file
@@ -0,0 +1,195 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.client.gui;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.client.gui.widgets.WidgetTerminal;
|
||||
import dan200.computercraft.shared.computer.blocks.TileComputer;
|
||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||
import dan200.computercraft.shared.computer.core.IComputer;
|
||||
import dan200.computercraft.shared.computer.core.IComputerContainer;
|
||||
import dan200.computercraft.shared.computer.inventory.ContainerComputer;
|
||||
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.inventory.Container;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import org.lwjgl.input.Keyboard;
|
||||
import org.lwjgl.input.Mouse;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class GuiComputer extends GuiContainer
|
||||
{
|
||||
private static final ResourceLocation background = new ResourceLocation( "computercraft", "textures/gui/corners.png" );
|
||||
private static final ResourceLocation backgroundAdvanced = new ResourceLocation( "computercraft", "textures/gui/corners2.png" );
|
||||
private static final ResourceLocation backgroundCommand = new ResourceLocation( "computercraft", "textures/gui/cornersCommand.png" );
|
||||
|
||||
private final ComputerFamily m_family;
|
||||
private final IComputer m_computer;
|
||||
private final int m_termWidth;
|
||||
private final int m_termHeight;
|
||||
private WidgetTerminal m_terminal;
|
||||
|
||||
protected GuiComputer( Container container, ComputerFamily family, IComputer computer, int termWidth, int termHeight )
|
||||
{
|
||||
super( container );
|
||||
m_family = family;
|
||||
m_computer = computer;
|
||||
m_termWidth = termWidth;
|
||||
m_termHeight = termHeight;
|
||||
m_terminal = null;
|
||||
}
|
||||
|
||||
public GuiComputer( TileComputer computer )
|
||||
{
|
||||
this(
|
||||
new ContainerComputer( computer ),
|
||||
computer.getFamily(),
|
||||
computer.createComputer(),
|
||||
ComputerCraft.terminalWidth_computer,
|
||||
ComputerCraft.terminalHeight_computer
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initGui()
|
||||
{
|
||||
super.initGui();
|
||||
Keyboard.enableRepeatEvents( true );
|
||||
|
||||
m_terminal = new WidgetTerminal( 0, 0, m_termWidth, m_termHeight, new IComputerContainer()
|
||||
{
|
||||
@Override
|
||||
public IComputer getComputer()
|
||||
{
|
||||
return m_computer;
|
||||
}
|
||||
}, 2, 2, 2, 2 );
|
||||
m_terminal.setAllowFocusLoss( false );
|
||||
xSize = m_terminal.getWidth() + 24;
|
||||
ySize = m_terminal.getHeight() + 24;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGuiClosed()
|
||||
{
|
||||
super.onGuiClosed();
|
||||
Keyboard.enableRepeatEvents( false );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doesGuiPauseGame()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateScreen()
|
||||
{
|
||||
super.updateScreen();
|
||||
m_terminal.update();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void keyTyped(char c, int k) throws IOException
|
||||
{
|
||||
if( k == 1 )
|
||||
{
|
||||
super.keyTyped( c, k );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_terminal.keyTyped( c, k );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void mouseClicked( int x, int y, int button )
|
||||
{
|
||||
int startX = (width - m_terminal.getWidth()) / 2;
|
||||
int startY = (height - m_terminal.getHeight()) / 2;
|
||||
m_terminal.mouseClicked( x - startX, y - startY, button );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMouseInput() throws IOException
|
||||
{
|
||||
super.handleMouseInput();
|
||||
|
||||
int x = Mouse.getEventX() * width / mc.displayWidth;
|
||||
int y = height - Mouse.getEventY() * height / mc.displayHeight - 1;
|
||||
int startX = (width - m_terminal.getWidth()) / 2;
|
||||
int startY = (height - m_terminal.getHeight()) / 2;
|
||||
m_terminal.handleMouseInput( x - startX, y - startY );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleKeyboardInput() throws IOException
|
||||
{
|
||||
super.handleKeyboardInput();
|
||||
m_terminal.handleKeyboardInput();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void drawGuiContainerForegroundLayer(int par1, int par2)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void drawGuiContainerBackgroundLayer( float var1, int var2, int var3 )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawScreen( int mouseX, int mouseY, float f )
|
||||
{
|
||||
// Work out where to draw
|
||||
int startX = (width - m_terminal.getWidth()) / 2;
|
||||
int startY = (height - m_terminal.getHeight()) / 2;
|
||||
int endX = startX + m_terminal.getWidth();
|
||||
int endY = startY + m_terminal.getHeight();
|
||||
|
||||
// Draw background
|
||||
drawDefaultBackground();
|
||||
|
||||
// Draw terminal
|
||||
m_terminal.draw( this.mc, startX, startY, mouseX, mouseY );
|
||||
|
||||
// Draw a border around the terminal
|
||||
GlStateManager.color( 1.0f, 1.0f, 1.0f, 1.0f );
|
||||
switch( m_family )
|
||||
{
|
||||
case Normal:
|
||||
default:
|
||||
{
|
||||
this.mc.getTextureManager().bindTexture( background );
|
||||
break;
|
||||
}
|
||||
case Advanced:
|
||||
{
|
||||
this.mc.getTextureManager().bindTexture( backgroundAdvanced );
|
||||
break;
|
||||
}
|
||||
case Command:
|
||||
{
|
||||
this.mc.getTextureManager().bindTexture( backgroundCommand );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
drawTexturedModalRect(startX - 12, startY - 12, 12, 28, 12, 12);
|
||||
drawTexturedModalRect(startX - 12, endY, 12, 40, 12, 16);
|
||||
drawTexturedModalRect(endX, startY - 12, 24, 28, 12, 12);
|
||||
drawTexturedModalRect(endX, endY, 24, 40, 12, 16);
|
||||
|
||||
drawTexturedModalRect(startX, startY-12, 0, 0, endX - startX, 12);
|
||||
drawTexturedModalRect(startX, endY, 0, 12, endX - startX, 16);
|
||||
|
||||
drawTexturedModalRect(startX-12, startY, 0, 28, 12, endY - startY);
|
||||
drawTexturedModalRect(endX, startY, 36, 28, 12, endY - startY);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.client.gui;
|
||||
|
||||
import dan200.computercraft.shared.peripheral.diskdrive.ContainerDiskDrive;
|
||||
import dan200.computercraft.shared.peripheral.diskdrive.TileDiskDrive;
|
||||
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.client.resources.I18n;
|
||||
import net.minecraft.entity.player.InventoryPlayer;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
public class GuiDiskDrive extends GuiContainer
|
||||
{
|
||||
private static final ResourceLocation background = new ResourceLocation( "computercraft", "textures/gui/diskdrive.png" );
|
||||
|
||||
private TileDiskDrive m_diskDrive;
|
||||
|
||||
public GuiDiskDrive( InventoryPlayer inventoryplayer, TileDiskDrive diskDrive )
|
||||
{
|
||||
super( new ContainerDiskDrive(inventoryplayer, diskDrive) );
|
||||
m_diskDrive = diskDrive;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void drawGuiContainerForegroundLayer(int par1, int par2)
|
||||
{
|
||||
String title = m_diskDrive.getDisplayName().getUnformattedText();
|
||||
fontRendererObj.drawString( title, (xSize - fontRendererObj.getStringWidth(title)) / 2, 6, 0x404040 );
|
||||
fontRendererObj.drawString( I18n.format("container.inventory"), 8, (ySize - 96) + 2, 0x404040 );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void drawGuiContainerBackgroundLayer(float f, int i, int j)
|
||||
{
|
||||
GlStateManager.color( 1.0F, 1.0F, 1.0F, 1.0F );
|
||||
this.mc.getTextureManager().bindTexture( background );
|
||||
int l = (width - xSize) / 2;
|
||||
int i1 = (height - ySize) / 2;
|
||||
drawTexturedModalRect(l, i1, 0, 0, xSize, ySize);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.client.gui;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.shared.media.inventory.ContainerHeldItem;
|
||||
|
||||
public class GuiPocketComputer extends GuiComputer
|
||||
{
|
||||
public GuiPocketComputer( ContainerHeldItem container )
|
||||
{
|
||||
super(
|
||||
container,
|
||||
ComputerCraft.Items.pocketComputer.getFamily( container.getStack() ),
|
||||
ComputerCraft.Items.pocketComputer.createClientComputer( container.getStack() ),
|
||||
ComputerCraft.terminalWidth_pocketComputer,
|
||||
ComputerCraft.terminalHeight_pocketComputer
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.client.gui;
|
||||
|
||||
import dan200.computercraft.shared.peripheral.printer.ContainerPrinter;
|
||||
import dan200.computercraft.shared.peripheral.printer.TilePrinter;
|
||||
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.client.resources.I18n;
|
||||
import net.minecraft.entity.player.InventoryPlayer;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
public class GuiPrinter extends GuiContainer
|
||||
{
|
||||
private static final ResourceLocation background = new ResourceLocation( "computercraft", "textures/gui/printer.png" );
|
||||
|
||||
private TilePrinter m_printer;
|
||||
private ContainerPrinter m_container;
|
||||
|
||||
public GuiPrinter(InventoryPlayer inventoryplayer, TilePrinter printer)
|
||||
{
|
||||
super(new ContainerPrinter(inventoryplayer, printer));
|
||||
m_printer = printer;
|
||||
m_container = (ContainerPrinter)inventorySlots;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void drawGuiContainerForegroundLayer(int par1, int par2)
|
||||
{
|
||||
String title = m_printer.getDisplayName().getUnformattedText();
|
||||
fontRendererObj.drawString( title, (xSize - fontRendererObj.getStringWidth(title)) / 2, 6, 0x404040 );
|
||||
fontRendererObj.drawString( I18n.format("container.inventory"), 8, (ySize - 96) + 2, 0x404040 );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void drawGuiContainerBackgroundLayer(float f, int i, int j)
|
||||
{
|
||||
GlStateManager.color( 1.0F, 1.0F, 1.0F, 1.0F );
|
||||
this.mc.getTextureManager().bindTexture( background );
|
||||
int startX = (width - xSize) / 2;
|
||||
int startY = (height - ySize) / 2;
|
||||
drawTexturedModalRect(startX, startY, 0, 0, xSize, ySize);
|
||||
|
||||
boolean printing = m_container.isPrinting();
|
||||
if( printing )
|
||||
{
|
||||
drawTexturedModalRect(startX + 34, startY + 21, 176, 0, 25, 45);
|
||||
}
|
||||
}
|
||||
}
|
||||
212
src/main/java/dan200/computercraft/client/gui/GuiPrintout.java
Normal file
212
src/main/java/dan200/computercraft/client/gui/GuiPrintout.java
Normal file
@@ -0,0 +1,212 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.client.gui;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.core.terminal.TextBuffer;
|
||||
import dan200.computercraft.shared.media.inventory.ContainerHeldItem;
|
||||
import dan200.computercraft.shared.media.items.ItemPrintout;
|
||||
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import org.lwjgl.input.Mouse;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
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;
|
||||
|
||||
private final boolean m_book;
|
||||
private final int m_pages;
|
||||
private final TextBuffer[] m_text;
|
||||
private final TextBuffer[] m_colours;
|
||||
private int m_page;
|
||||
|
||||
public GuiPrintout( ContainerHeldItem container )
|
||||
{
|
||||
super( container );
|
||||
m_book = (ItemPrintout.getType( container.getStack() ) == ItemPrintout.Type.Book);
|
||||
|
||||
String[] text = ItemPrintout.getText( container.getStack() );
|
||||
m_text = new TextBuffer[ text.length ];
|
||||
for( int i=0; i<m_text.length; ++i )
|
||||
{
|
||||
m_text[i] = new TextBuffer( text[i] );
|
||||
}
|
||||
String[] colours = ItemPrintout.getColours( container.getStack() );
|
||||
m_colours = new TextBuffer[ colours.length ];
|
||||
for( int i=0; i<m_colours.length; ++i )
|
||||
{
|
||||
m_colours[i] = new TextBuffer( colours[i] );
|
||||
}
|
||||
|
||||
m_pages = Math.max( m_text.length / ItemPrintout.LINES_PER_PAGE, 1 );
|
||||
m_page = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initGui()
|
||||
{
|
||||
super.initGui();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGuiClosed()
|
||||
{
|
||||
super.onGuiClosed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doesGuiPauseGame()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateScreen()
|
||||
{
|
||||
super.updateScreen();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void keyTyped(char c, int k) throws IOException
|
||||
{
|
||||
super.keyTyped( c, k );
|
||||
|
||||
if( k == 205 )
|
||||
{
|
||||
// Right
|
||||
if( m_page < m_pages - 1 )
|
||||
{
|
||||
m_page = m_page + 1;
|
||||
}
|
||||
}
|
||||
else if( k == 203 )
|
||||
{
|
||||
// Left
|
||||
if( m_page > 0 )
|
||||
{
|
||||
m_page = m_page - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMouseInput() throws IOException
|
||||
{
|
||||
super.handleMouseInput();
|
||||
|
||||
int mouseWheelChange = Mouse.getEventDWheel();
|
||||
if (mouseWheelChange < 0)
|
||||
{
|
||||
// Up
|
||||
if( m_page < m_pages - 1 )
|
||||
{
|
||||
m_page = m_page + 1;
|
||||
}
|
||||
}
|
||||
else if (mouseWheelChange > 0)
|
||||
{
|
||||
// Down
|
||||
if( m_page > 0 )
|
||||
{
|
||||
m_page = m_page - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void drawGuiContainerForegroundLayer( int par1, int par2 )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void drawGuiContainerBackgroundLayer( float var1, int var2, int var3 )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawScreen(int mouseX, int mouseY, float f)
|
||||
{
|
||||
// Draw background
|
||||
drawDefaultBackground();
|
||||
|
||||
// Draw the printout
|
||||
GlStateManager.color( 1.0f, 1.0f, 1.0f, 1.0f );
|
||||
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;
|
||||
|
||||
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, startY - 8, 0, ySize, xSize, 12);
|
||||
drawTexturedModalRect( startX, startY + ySize - 4, 0, ySize + 12, xSize, 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);
|
||||
}
|
||||
}
|
||||
|
||||
// Left half
|
||||
if( m_page == 0 )
|
||||
{
|
||||
drawTexturedModalRect( startX, startY, 24, 0, xSize / 2, ySize);
|
||||
drawTexturedModalRect( startX, startY, 0, 0, 12, ySize);
|
||||
}
|
||||
else
|
||||
{
|
||||
drawTexturedModalRect( startX, startY, 0, 0, 12, ySize);
|
||||
for( int n=1; n<m_page; ++n )
|
||||
{
|
||||
drawTexturedModalRect( startX + n*8, startY, 12, 0, 12, ySize);
|
||||
}
|
||||
drawTexturedModalRect( startX + m_page*8, startY, 24, 0, xSize / 2, ySize);
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
else
|
||||
{
|
||||
drawTexturedModalRect( startX + (m_pages - 1)*8 + (xSize - 12), startY, 24 + xSize + 12, 0, 12, ySize);
|
||||
for( int n=m_pages-2; n>=m_page; --n )
|
||||
{
|
||||
drawTexturedModalRect( startX + n*8 + (xSize - 12), startY, 24 + xSize, 0, 12, ySize);
|
||||
}
|
||||
drawTexturedModalRect( startX + m_page*8 + xSize/2, startY, 24 + xSize / 2, 0, xSize / 2, ySize);
|
||||
}
|
||||
|
||||
// Draw the text
|
||||
FixedWidthFontRenderer fontRenderer = (FixedWidthFontRenderer)ComputerCraft.getFixedWidthFontRenderer();
|
||||
int x = startX + m_page * 8 + 13;
|
||||
int y = startY + 11;
|
||||
for( int line=0; line<ItemPrintout.LINES_PER_PAGE; ++line )
|
||||
{
|
||||
int lineIdx = ItemPrintout.LINES_PER_PAGE * m_page + line;
|
||||
if( lineIdx >= 0 && lineIdx < m_text.length )
|
||||
{
|
||||
fontRenderer.drawString( m_text[lineIdx], x, y, m_colours[lineIdx], null, 0, 0, false );
|
||||
}
|
||||
y = y + FixedWidthFontRenderer.FONT_HEIGHT;
|
||||
}
|
||||
}
|
||||
}
|
||||
166
src/main/java/dan200/computercraft/client/gui/GuiTurtle.java
Normal file
166
src/main/java/dan200/computercraft/client/gui/GuiTurtle.java
Normal file
@@ -0,0 +1,166 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.client.gui;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.api.turtle.ITurtleAccess;
|
||||
import dan200.computercraft.client.gui.widgets.WidgetTerminal;
|
||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||
import dan200.computercraft.shared.computer.core.IComputer;
|
||||
import dan200.computercraft.shared.computer.core.IComputerContainer;
|
||||
import dan200.computercraft.shared.turtle.blocks.TileTurtle;
|
||||
import dan200.computercraft.shared.turtle.inventory.ContainerTurtle;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.entity.player.InventoryPlayer;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.world.World;
|
||||
import org.lwjgl.input.Keyboard;
|
||||
import org.lwjgl.input.Mouse;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class GuiTurtle extends GuiContainer
|
||||
{
|
||||
private static final ResourceLocation background = new ResourceLocation( "computercraft", "textures/gui/turtle.png" );
|
||||
private static final ResourceLocation backgroundAdvanced = new ResourceLocation( "computercraft", "textures/gui/turtle2.png" );
|
||||
|
||||
protected World m_world;
|
||||
protected ContainerTurtle m_container;
|
||||
|
||||
protected final ComputerFamily m_family;
|
||||
protected final ITurtleAccess m_turtle;
|
||||
protected final IComputer m_computer;
|
||||
protected WidgetTerminal m_terminalGui;
|
||||
|
||||
public GuiTurtle( World world, InventoryPlayer inventoryplayer, TileTurtle turtle )
|
||||
{
|
||||
this( world, turtle, new ContainerTurtle( inventoryplayer, turtle.getAccess() ) );
|
||||
}
|
||||
|
||||
protected GuiTurtle( World world, TileTurtle turtle, ContainerTurtle container )
|
||||
{
|
||||
super( container );
|
||||
|
||||
m_world = world;
|
||||
m_container = container;
|
||||
m_family = turtle.getFamily();
|
||||
m_turtle = turtle.getAccess();
|
||||
m_computer = turtle.createComputer();
|
||||
|
||||
xSize = 254;
|
||||
ySize = 217;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initGui()
|
||||
{
|
||||
super.initGui();
|
||||
Keyboard.enableRepeatEvents(true);
|
||||
m_terminalGui = new WidgetTerminal(
|
||||
( width - xSize ) / 2 + 8,
|
||||
( height - ySize ) / 2 + 8,
|
||||
ComputerCraft.terminalWidth_turtle,
|
||||
ComputerCraft.terminalHeight_turtle,
|
||||
new IComputerContainer()
|
||||
{
|
||||
@Override
|
||||
public IComputer getComputer()
|
||||
{
|
||||
return m_computer;
|
||||
}
|
||||
},
|
||||
2, 2, 2, 2
|
||||
);
|
||||
m_terminalGui.setAllowFocusLoss( false );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGuiClosed()
|
||||
{
|
||||
super.onGuiClosed();
|
||||
Keyboard.enableRepeatEvents(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateScreen()
|
||||
{
|
||||
super.updateScreen();
|
||||
m_terminalGui.update();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void keyTyped(char c, int k) throws IOException
|
||||
{
|
||||
if( k == 1 )
|
||||
{
|
||||
super.keyTyped( c, k );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_terminalGui.keyTyped( c, k );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void mouseClicked(int x, int y, int button) throws IOException
|
||||
{
|
||||
super.mouseClicked( x, y, button );
|
||||
m_terminalGui.mouseClicked( x, y, button );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMouseInput() throws IOException
|
||||
{
|
||||
super.handleMouseInput();
|
||||
int x = Mouse.getEventX() * this.width / mc.displayWidth;
|
||||
int y = this.height - Mouse.getEventY() * this.height / mc.displayHeight - 1;
|
||||
m_terminalGui.handleMouseInput( x, y );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleKeyboardInput() throws IOException
|
||||
{
|
||||
super.handleKeyboardInput();
|
||||
m_terminalGui.handleKeyboardInput();
|
||||
}
|
||||
|
||||
protected void drawSelectionSlot( boolean advanced )
|
||||
{
|
||||
int x = (width - xSize) / 2;
|
||||
int y = (height - ySize) / 2;
|
||||
|
||||
// Draw selection slot
|
||||
int slot = m_container.getSelectedSlot();
|
||||
if( slot >= 0 )
|
||||
{
|
||||
GlStateManager.color( 1.0F, 1.0F, 1.0F, 1.0F );
|
||||
int slotX = (slot%4);
|
||||
int slotY = (slot/4);
|
||||
this.mc.getTextureManager().bindTexture( advanced ? backgroundAdvanced : background );
|
||||
drawTexturedModalRect(x + m_container.m_turtleInvStartX - 2 + slotX * 18, y + m_container.m_playerInvStartY - 2 + slotY * 18, 0, 217, 24, 24);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void drawGuiContainerBackgroundLayer( float f, int mouseX, int mouseY )
|
||||
{
|
||||
// Draw term
|
||||
boolean advanced = (m_family == ComputerFamily.Advanced);
|
||||
m_terminalGui.draw( Minecraft.getMinecraft(), 0, 0, mouseX, mouseY );
|
||||
|
||||
// Draw border/inventory
|
||||
GlStateManager.color( 1.0F, 1.0F, 1.0F, 1.0F );
|
||||
this.mc.getTextureManager().bindTexture( advanced ? backgroundAdvanced : background );
|
||||
int x = (width - xSize) / 2;
|
||||
int y = (height - ySize) / 2;
|
||||
drawTexturedModalRect(x, y, 0, 0, xSize, ySize);
|
||||
|
||||
drawSelectionSlot( advanced );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.client.gui.widgets;
|
||||
|
||||
public class MousePos
|
||||
{
|
||||
public int x;
|
||||
public int y;
|
||||
|
||||
public MousePos( int x, int y )
|
||||
{
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,386 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.client.gui.widgets;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.audio.PositionedSoundRecord;
|
||||
import net.minecraft.client.gui.FontRenderer;
|
||||
import net.minecraft.client.gui.Gui;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.client.renderer.OpenGlHelper;
|
||||
import net.minecraft.client.renderer.RenderHelper;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.client.renderer.entity.RenderItem;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL12;
|
||||
|
||||
public abstract class Widget extends Gui
|
||||
{
|
||||
private WidgetContainer m_parent;
|
||||
private boolean m_visible;
|
||||
private int m_xPosition;
|
||||
private int m_yPosition;
|
||||
private int m_width;
|
||||
private int m_height;
|
||||
|
||||
protected Widget( int x, int y, int width, int height )
|
||||
{
|
||||
m_parent = null;
|
||||
m_visible = true;
|
||||
m_xPosition = x;
|
||||
m_yPosition = y;
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
}
|
||||
|
||||
public WidgetContainer getRoot()
|
||||
{
|
||||
if( m_parent != null )
|
||||
{
|
||||
return m_parent.getRoot();
|
||||
}
|
||||
else if( this instanceof WidgetContainer )
|
||||
{
|
||||
return (WidgetContainer)this;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public WidgetContainer getParent()
|
||||
{
|
||||
return m_parent;
|
||||
}
|
||||
|
||||
public void setParent( WidgetContainer parent )
|
||||
{
|
||||
m_parent = parent;
|
||||
}
|
||||
|
||||
public boolean isObscured()
|
||||
{
|
||||
if( m_parent != null )
|
||||
{
|
||||
Widget parentModalWidget = m_parent.getModalWidget();
|
||||
if( parentModalWidget == null )
|
||||
{
|
||||
return m_parent.isObscured();
|
||||
}
|
||||
else
|
||||
{
|
||||
return (parentModalWidget != this);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isVisible()
|
||||
{
|
||||
return m_visible && (m_parent == null || m_parent.isVisible());
|
||||
}
|
||||
|
||||
public void setVisible( boolean visible )
|
||||
{
|
||||
m_visible = visible;
|
||||
}
|
||||
|
||||
public int getXPosition()
|
||||
{
|
||||
return m_xPosition;
|
||||
}
|
||||
|
||||
public int getYPosition()
|
||||
{
|
||||
return m_yPosition;
|
||||
}
|
||||
|
||||
public int getAbsoluteXPosition()
|
||||
{
|
||||
return m_xPosition + (m_parent != null ? m_parent.getAbsoluteXPosition() : 0);
|
||||
}
|
||||
|
||||
public int getAbsoluteYPosition()
|
||||
{
|
||||
return m_yPosition + (m_parent != null ? m_parent.getAbsoluteYPosition() : 0);
|
||||
}
|
||||
|
||||
public int getWidth()
|
||||
{
|
||||
return m_width;
|
||||
}
|
||||
|
||||
public int getHeight()
|
||||
{
|
||||
return m_height;
|
||||
}
|
||||
|
||||
public void setPosition( int x, int y )
|
||||
{
|
||||
m_xPosition = x;
|
||||
m_yPosition = y;
|
||||
}
|
||||
|
||||
public void resize( int width, int height )
|
||||
{
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
}
|
||||
|
||||
public void update()
|
||||
{
|
||||
}
|
||||
|
||||
public void draw( Minecraft mc, int xOrigin, int yOrigin, int mouseX, int mouseY )
|
||||
{
|
||||
}
|
||||
|
||||
public void drawForeground( Minecraft mc, int xOrigin, int yOrigin, int mouseX, int mouseY )
|
||||
{
|
||||
}
|
||||
|
||||
public void modifyMousePosition( MousePos pos )
|
||||
{
|
||||
}
|
||||
|
||||
public void handleMouseInput( int mouseX, int mouseY )
|
||||
{
|
||||
}
|
||||
|
||||
public void handleKeyboardInput()
|
||||
{
|
||||
}
|
||||
|
||||
public void mouseClicked( int mouseX, int mouseY, int mouseButton )
|
||||
{
|
||||
}
|
||||
|
||||
public void keyTyped( char c, int k )
|
||||
{
|
||||
}
|
||||
|
||||
public boolean suppressItemTooltips( Minecraft mc, int xOrigin, int yOrigin, int mouseX, int mouseY )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean suppressKeyPress( char c, int k )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void drawFullImage( int x, int y, int w, int h )
|
||||
{
|
||||
Tessellator tessellator = Tessellator.getInstance();
|
||||
tessellator.getWorldRenderer().begin( GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX );
|
||||
tessellator.getWorldRenderer().pos( (double) ( x + 0 ), (double) ( y + h ), (double) this.zLevel ).tex( 0.0, 1.0 ).endVertex();
|
||||
tessellator.getWorldRenderer().pos( (double) ( x + w ), (double) ( y + h ), (double) this.zLevel ).tex( 1.0, 1.0 ).endVertex();
|
||||
tessellator.getWorldRenderer().pos( (double) ( x + w ), (double) ( y + 0 ), (double) this.zLevel ).tex( 1.0, 0.0 ).endVertex();
|
||||
tessellator.getWorldRenderer().pos( (double) ( x + 0 ), (double) ( y + 0 ), (double) this.zLevel ).tex( 0.0, 0.0 ).endVertex();
|
||||
tessellator.draw();
|
||||
}
|
||||
|
||||
protected void drawT3( int x, int y, int w, int h, int u, int v, int uw, int vh )
|
||||
{
|
||||
int partW = uw / 3;
|
||||
|
||||
// Draw first bit
|
||||
super.drawTexturedModalRect( x, y, u, v, partW, vh );
|
||||
|
||||
// Draw middle bits
|
||||
int middleBits = Math.max( (w - 2 * partW) / partW, 0 );
|
||||
for( int j=0; j<middleBits; ++j )
|
||||
{
|
||||
super.drawTexturedModalRect( x + (j + 1) * partW, y, u + partW, v, partW, vh );
|
||||
}
|
||||
|
||||
// Draw end bit
|
||||
int endW = w - (middleBits + 1) * partW;
|
||||
super.drawTexturedModalRect( x + w - endW, y, u + uw - endW, v, endW, vh );
|
||||
}
|
||||
|
||||
protected void drawT9( int x, int y, int w, int h, int u, int v, int uw, int vh )
|
||||
{
|
||||
int partH = vh / 3;
|
||||
|
||||
// Draw first row
|
||||
drawT3( x, y, w, partH, u, v, uw, partH );
|
||||
|
||||
// Draw middle rows
|
||||
int middleBits = Math.max( (h - 2 * partH) / partH, 0 );
|
||||
for( int j=0; j<middleBits; ++j )
|
||||
{
|
||||
drawT3( x, y + ( j + 1 ) * partH, w, partH, u, v + partH, uw, partH );
|
||||
}
|
||||
|
||||
// Draw end row
|
||||
int endH = h - (middleBits + 1) * partH;
|
||||
drawT3( x, y + h - endH, w, endH, u, v + vh - endH, uw, endH );
|
||||
}
|
||||
|
||||
protected void drawInsetBorder( int x, int y, int w, int h )
|
||||
{
|
||||
// Draw border
|
||||
try
|
||||
{
|
||||
drawVerticalLine( x, y - 1, y + h - 1, 0xff363636 );
|
||||
drawVerticalLine( x + w - 1, y, y + h, 0xffffffff );
|
||||
drawHorizontalLine( x, x + w - 2, y, 0xff363636 );
|
||||
drawHorizontalLine( x + 1, x + w - 1, y + h - 1, 0xffffffff );
|
||||
drawHorizontalLine( x, x, y + h - 1, 0xff8a8a8a );
|
||||
drawHorizontalLine( x + w - 1, x + w - 1, y, 0xff8a8a8a );
|
||||
}
|
||||
finally
|
||||
{
|
||||
GlStateManager.color( 1.0f, 1.0f, 1.0f, 1.0f );
|
||||
}
|
||||
}
|
||||
|
||||
protected void drawFlatBorder( int x, int y, int w, int h, int colour )
|
||||
{
|
||||
// Draw border
|
||||
colour = colour | 0xff000000;
|
||||
try
|
||||
{
|
||||
drawVerticalLine( x, y - 1, y + h - 1, colour );
|
||||
drawVerticalLine( x + w - 1, y, y + h, colour );
|
||||
drawHorizontalLine( x, x + w - 2, y, colour );
|
||||
drawHorizontalLine( x + 1, x + w - 1, y + h - 1, colour );
|
||||
drawHorizontalLine( x, x, y + h - 1, colour );
|
||||
drawHorizontalLine( x + w - 1, x + w - 1, y, colour );
|
||||
}
|
||||
finally
|
||||
{
|
||||
GlStateManager.color( 1.0f, 1.0f, 1.0f, 1.0f );
|
||||
}
|
||||
}
|
||||
|
||||
protected void drawTooltip( String line, int x, int y )
|
||||
{
|
||||
drawTooltip( new String[] { line }, x, y );
|
||||
}
|
||||
|
||||
protected void drawTooltip( String[] lines, int x, int y )
|
||||
{
|
||||
Minecraft mc = Minecraft.getMinecraft();
|
||||
FontRenderer fontRenderer = mc.fontRendererObj;
|
||||
|
||||
int width = 0;
|
||||
for( int i=0; i<lines.length; ++i )
|
||||
{
|
||||
String line = lines[i];
|
||||
width = Math.max( fontRenderer.getStringWidth( line ), width );
|
||||
}
|
||||
int startX = x + 12;
|
||||
int startY = y - 12;
|
||||
if( startX + width + 4 > mc.currentScreen.width )
|
||||
{
|
||||
startX -= width + 24;
|
||||
if( startX < 24 )
|
||||
{
|
||||
startX = 24;
|
||||
}
|
||||
}
|
||||
|
||||
float oldZLevel = this.zLevel;
|
||||
try
|
||||
{
|
||||
this.zLevel = 300.0F;
|
||||
|
||||
int height = 10 * lines.length - 2;
|
||||
int j1 = -267386864;
|
||||
this.drawGradientRect( startX - 3, startY - 4, startX + width + 3, startY - 3, j1, j1 );
|
||||
this.drawGradientRect( startX - 3, startY + height + 3, startX + width + 3, startY + height + 4, j1, j1 );
|
||||
this.drawGradientRect( startX - 3, startY - 3, startX + width + 3, startY + height + 3, j1, j1 );
|
||||
this.drawGradientRect( startX - 4, startY - 3, startX - 3, startY + height + 3, j1, j1 );
|
||||
|
||||
this.drawGradientRect( startX + width + 3, startY - 3, startX + width + 4, startY + height + 3, j1, j1 );
|
||||
int k1 = 1347420415;
|
||||
int l1 = ( k1 & 16711422 ) >> 1 | k1 & -16777216;
|
||||
this.drawGradientRect( startX - 3, startY - 3 + 1, startX - 3 + 1, startY + height + 3 - 1, k1, l1 );
|
||||
this.drawGradientRect( startX + width + 2, startY - 3 + 1, startX + width + 3, startY + height + 3 - 1, k1, l1 );
|
||||
this.drawGradientRect( startX - 3, startY - 3, startX + width + 3, startY - 3 + 1, k1, k1 );
|
||||
this.drawGradientRect( startX - 3, startY + height + 2, startX + width + 3, startY + height + 3, l1, l1 );
|
||||
|
||||
GlStateManager.disableDepth();
|
||||
try
|
||||
{
|
||||
for( int i = 0; i < lines.length; ++i )
|
||||
{
|
||||
String line = lines[ i ];
|
||||
fontRenderer.drawStringWithShadow( line, startX, startY + i * 10, 0xffffffff );
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
GlStateManager.color( 1.0f, 1.0f, 1.0f, 1.0f );
|
||||
GlStateManager.enableDepth();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
this.zLevel = oldZLevel;
|
||||
}
|
||||
}
|
||||
|
||||
protected void drawItemStack( int x, int y, ItemStack stack )
|
||||
{
|
||||
if( stack != null )
|
||||
{
|
||||
GlStateManager.color( 1.0f, 1.0f, 1.0f, 1.0f );
|
||||
GlStateManager.enableLighting();
|
||||
GlStateManager.enableRescaleNormal();
|
||||
RenderHelper.enableGUIStandardItemLighting();
|
||||
OpenGlHelper.setLightmapTextureCoords( OpenGlHelper.lightmapTexUnit, 240.0f, 240.0f );
|
||||
try
|
||||
{
|
||||
Minecraft mc = Minecraft.getMinecraft();
|
||||
RenderItem renderItem = mc.getRenderItem();
|
||||
if( renderItem != null )
|
||||
{
|
||||
renderItem.renderItemAndEffectIntoGUI( stack, x, y );
|
||||
renderItem.renderItemOverlayIntoGUI( mc.fontRendererObj, stack, x, y, null );
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
RenderHelper.disableStandardItemLighting();
|
||||
GlStateManager.disableRescaleNormal();
|
||||
GlStateManager.disableLighting();
|
||||
GlStateManager.enableBlend();
|
||||
GlStateManager.blendFunc( GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA );
|
||||
GlStateManager.color( 1.0f, 1.0f, 1.0f, 1.0f );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void drawString( String s, int x, int y, int color )
|
||||
{
|
||||
Minecraft mc = Minecraft.getMinecraft();
|
||||
try
|
||||
{
|
||||
mc.fontRendererObj.drawString( s, x, y, color );
|
||||
}
|
||||
finally
|
||||
{
|
||||
GlStateManager.color( 1.0f, 1.0f, 1.0f, 1.0f );
|
||||
}
|
||||
}
|
||||
|
||||
protected int getStringWidth( String s )
|
||||
{
|
||||
Minecraft mc = Minecraft.getMinecraft();
|
||||
return mc.fontRendererObj.getStringWidth( s );
|
||||
}
|
||||
|
||||
protected void playClickSound()
|
||||
{
|
||||
Minecraft mc = Minecraft.getMinecraft();
|
||||
mc.getSoundHandler().playSound( PositionedSoundRecord.create( new ResourceLocation( "gui.button.press" ), 1.0F ) );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,344 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
|
||||
package dan200.computercraft.client.gui.widgets;
|
||||
|
||||
import dan200.computercraft.client.gui.widgets.Widget;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class WidgetContainer extends Widget
|
||||
{
|
||||
private ArrayList<Widget> m_widgets;
|
||||
private Widget m_modalWidget;
|
||||
|
||||
public WidgetContainer( int x, int y, int w, int h )
|
||||
{
|
||||
super( x, y, w, h );
|
||||
m_widgets = new ArrayList<Widget>();
|
||||
m_modalWidget = null;
|
||||
}
|
||||
|
||||
public void addWidget( Widget widget )
|
||||
{
|
||||
m_widgets.add( widget );
|
||||
widget.setParent( this );
|
||||
}
|
||||
|
||||
public void setModalWidget( Widget widget )
|
||||
{
|
||||
m_modalWidget = widget;
|
||||
if( widget != null )
|
||||
{
|
||||
widget.setParent( this );
|
||||
}
|
||||
}
|
||||
|
||||
public Widget getModalWidget()
|
||||
{
|
||||
return m_modalWidget;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update()
|
||||
{
|
||||
for( int i=0; i<m_widgets.size(); ++i )
|
||||
{
|
||||
m_widgets.get( i ).update();
|
||||
}
|
||||
if( m_modalWidget != null )
|
||||
{
|
||||
m_modalWidget.update();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw( Minecraft mc, int xOrigin, int yOrigin, int mouseX, int mouseY )
|
||||
{
|
||||
for( int i=0; i<m_widgets.size(); ++i )
|
||||
{
|
||||
Widget widget = m_widgets.get( i );
|
||||
if( widget.isVisible() )
|
||||
{
|
||||
widget.draw(
|
||||
mc,
|
||||
xOrigin + getXPosition(),
|
||||
yOrigin + getYPosition(),
|
||||
(m_modalWidget == null) ? (mouseX - getXPosition()) : -99,
|
||||
(m_modalWidget == null) ? (mouseY - getYPosition()) : -99
|
||||
);
|
||||
}
|
||||
}
|
||||
if( m_modalWidget != null )
|
||||
{
|
||||
if( m_modalWidget.isVisible() )
|
||||
{
|
||||
GlStateManager.pushMatrix();
|
||||
try
|
||||
{
|
||||
GlStateManager.translate( 0.0f, 0.0f, 200.0f );
|
||||
m_modalWidget.draw(
|
||||
mc,
|
||||
xOrigin + getXPosition(),
|
||||
yOrigin + getYPosition(),
|
||||
mouseX - getXPosition(),
|
||||
mouseY - getYPosition()
|
||||
);
|
||||
}
|
||||
finally
|
||||
{
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawForeground( Minecraft mc, int xOrigin, int yOrigin, int mouseX, int mouseY )
|
||||
{
|
||||
for( int i=0; i<m_widgets.size(); ++i )
|
||||
{
|
||||
Widget widget = m_widgets.get( i );
|
||||
if( widget.isVisible() )
|
||||
{
|
||||
widget.drawForeground(
|
||||
mc,
|
||||
xOrigin + getXPosition(),
|
||||
yOrigin + getYPosition(),
|
||||
(m_modalWidget == null) ? (mouseX - getXPosition()) : -99,
|
||||
(m_modalWidget == null) ? (mouseY - getYPosition()) : -99
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if( m_modalWidget != null )
|
||||
{
|
||||
if( m_modalWidget.isVisible() )
|
||||
{
|
||||
GlStateManager.pushMatrix();
|
||||
try
|
||||
{
|
||||
GlStateManager.translate( 0.0f, 0.0f, 200.0f );
|
||||
m_modalWidget.drawForeground(
|
||||
mc,
|
||||
xOrigin + getXPosition(),
|
||||
yOrigin + getYPosition(),
|
||||
mouseX - getXPosition(),
|
||||
mouseY - getYPosition()
|
||||
);
|
||||
}
|
||||
finally
|
||||
{
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void modifyMousePosition( MousePos pos )
|
||||
{
|
||||
pos.x -= getXPosition();
|
||||
pos.y -= getYPosition();
|
||||
if( m_modalWidget == null )
|
||||
{
|
||||
for( int i = 0; i < m_widgets.size(); ++i )
|
||||
{
|
||||
Widget widget = m_widgets.get( i );
|
||||
if( widget.isVisible() )
|
||||
{
|
||||
widget.modifyMousePosition( pos );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( m_modalWidget.isVisible() )
|
||||
{
|
||||
m_modalWidget.modifyMousePosition( pos );
|
||||
}
|
||||
}
|
||||
pos.x += getXPosition();
|
||||
pos.y += getYPosition();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean suppressItemTooltips( Minecraft mc, int xOrigin, int yOrigin, int mouseX, int mouseY )
|
||||
{
|
||||
if( m_modalWidget == null )
|
||||
{
|
||||
for( int i = 0; i < m_widgets.size(); ++i )
|
||||
{
|
||||
Widget widget = m_widgets.get( i );
|
||||
if( widget.isVisible() )
|
||||
{
|
||||
if( widget.suppressItemTooltips(
|
||||
mc,
|
||||
xOrigin + getXPosition(),
|
||||
yOrigin + getYPosition(),
|
||||
mouseX - getXPosition(),
|
||||
mouseY - getYPosition()
|
||||
) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( m_modalWidget.isVisible() && m_modalWidget.suppressItemTooltips(
|
||||
mc,
|
||||
xOrigin + getXPosition(),
|
||||
yOrigin + getYPosition(),
|
||||
mouseX - getXPosition(),
|
||||
mouseY - getYPosition()
|
||||
) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean suppressKeyPress( char c, int k )
|
||||
{
|
||||
if( m_modalWidget == null )
|
||||
{
|
||||
for( int i = 0; i < m_widgets.size(); ++i )
|
||||
{
|
||||
Widget widget = m_widgets.get( i );
|
||||
if( widget.isVisible() )
|
||||
{
|
||||
if( widget.suppressKeyPress( c, k ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( m_modalWidget.isVisible() )
|
||||
{
|
||||
if( m_modalWidget.suppressKeyPress( c, k ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMouseInput( int mouseX, int mouseY )
|
||||
{
|
||||
if( m_modalWidget == null )
|
||||
{
|
||||
for( int i = 0; i < m_widgets.size(); ++i )
|
||||
{
|
||||
Widget widget = m_widgets.get( i );
|
||||
if( widget.isVisible() )
|
||||
{
|
||||
widget.handleMouseInput(
|
||||
mouseX - getXPosition(),
|
||||
mouseY - getYPosition()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( m_modalWidget.isVisible() )
|
||||
{
|
||||
m_modalWidget.handleMouseInput(
|
||||
mouseX - getXPosition(),
|
||||
mouseY - getYPosition()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleKeyboardInput()
|
||||
{
|
||||
if( m_modalWidget == null )
|
||||
{
|
||||
for( int i = 0; i < m_widgets.size(); ++i )
|
||||
{
|
||||
Widget widget = m_widgets.get( i );
|
||||
if( widget.isVisible() )
|
||||
{
|
||||
widget.handleKeyboardInput();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( m_modalWidget.isVisible() )
|
||||
{
|
||||
m_modalWidget.handleKeyboardInput();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseClicked( int mouseX, int mouseY, int mouseButton )
|
||||
{
|
||||
if( m_modalWidget == null )
|
||||
{
|
||||
for( int i = 0; i < m_widgets.size(); ++i )
|
||||
{
|
||||
Widget widget = m_widgets.get( i );
|
||||
if( widget.isVisible() )
|
||||
{
|
||||
widget.mouseClicked(
|
||||
mouseX - getXPosition(),
|
||||
mouseY - getYPosition(),
|
||||
mouseButton
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( m_modalWidget.isVisible() )
|
||||
{
|
||||
m_modalWidget.mouseClicked(
|
||||
mouseX - getXPosition(),
|
||||
mouseY - getYPosition(),
|
||||
mouseButton
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped( char c, int k )
|
||||
{
|
||||
if( m_modalWidget == null )
|
||||
{
|
||||
for( int i = 0; i < m_widgets.size(); ++i )
|
||||
{
|
||||
Widget widget = m_widgets.get( i );
|
||||
if( widget.isVisible() )
|
||||
{
|
||||
widget.keyTyped( c, k );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( m_modalWidget.isVisible() )
|
||||
{
|
||||
m_modalWidget.keyTyped( c, k );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,477 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.client.gui.widgets;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.client.gui.FixedWidthFontRenderer;
|
||||
import dan200.computercraft.core.terminal.Terminal;
|
||||
import dan200.computercraft.core.terminal.TextBuffer;
|
||||
import dan200.computercraft.shared.computer.core.IComputer;
|
||||
import dan200.computercraft.shared.computer.core.IComputerContainer;
|
||||
import dan200.computercraft.shared.util.Colour;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.util.ChatAllowedCharacters;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import org.lwjgl.input.Keyboard;
|
||||
import org.lwjgl.input.Mouse;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class WidgetTerminal extends Widget
|
||||
{
|
||||
private static final ResourceLocation background = new ResourceLocation( "computercraft", "textures/gui/termBackground.png" );
|
||||
private static float TERMINATE_TIME = 0.5f;
|
||||
|
||||
private IComputerContainer m_computer;
|
||||
|
||||
private float m_terminateTimer;
|
||||
private float m_rebootTimer;
|
||||
private float m_shutdownTimer;
|
||||
|
||||
private int m_lastClickButton;
|
||||
private int m_lastClickX;
|
||||
private int m_lastClickY;
|
||||
|
||||
private boolean m_focus;
|
||||
private boolean m_allowFocusLoss;
|
||||
private boolean m_locked;
|
||||
|
||||
private int m_leftMargin;
|
||||
private int m_rightMargin;
|
||||
private int m_topMargin;
|
||||
private int m_bottomMargin;
|
||||
|
||||
private ArrayList<Integer> m_keysDown;
|
||||
|
||||
public WidgetTerminal( int x, int y, int termWidth, int termHeight, IComputerContainer computer, int leftMargin, int rightMargin, int topMargin, int bottomMargin )
|
||||
{
|
||||
super(
|
||||
x, y,
|
||||
leftMargin + rightMargin + termWidth * FixedWidthFontRenderer.FONT_WIDTH,
|
||||
topMargin + bottomMargin + termHeight * FixedWidthFontRenderer.FONT_HEIGHT
|
||||
);
|
||||
|
||||
m_computer = computer;
|
||||
m_terminateTimer = 0.0f;
|
||||
m_rebootTimer = 0.0f;
|
||||
m_shutdownTimer = 0.0f;
|
||||
|
||||
m_lastClickButton = -1;
|
||||
m_lastClickX = -1;
|
||||
m_lastClickY = -1;
|
||||
|
||||
m_focus = false;
|
||||
m_allowFocusLoss = true;
|
||||
m_locked = false;
|
||||
|
||||
m_leftMargin = leftMargin;
|
||||
m_rightMargin = rightMargin;
|
||||
m_topMargin = topMargin;
|
||||
m_bottomMargin = bottomMargin;
|
||||
|
||||
m_keysDown = new ArrayList<Integer>();
|
||||
}
|
||||
|
||||
public void setAllowFocusLoss( boolean allowFocusLoss )
|
||||
{
|
||||
m_allowFocusLoss = allowFocusLoss;
|
||||
m_focus = m_focus || !allowFocusLoss;
|
||||
}
|
||||
|
||||
public void setLocked( boolean locked )
|
||||
{
|
||||
m_locked = locked;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped( char ch, int key )
|
||||
{
|
||||
if( m_focus && !m_locked )
|
||||
{
|
||||
// Ctrl+V for paste
|
||||
if( ch == 22 )
|
||||
{
|
||||
String clipboard = GuiScreen.getClipboardString();
|
||||
if( clipboard != null )
|
||||
{
|
||||
// Clip to the first occurance of \r or \n
|
||||
int newLineIndex1 = clipboard.indexOf( "\r" );
|
||||
int newLineIndex2 = clipboard.indexOf( "\n" );
|
||||
if( newLineIndex1 >= 0 && newLineIndex2 >= 0 )
|
||||
{
|
||||
clipboard = clipboard.substring( 0, Math.min( newLineIndex1, newLineIndex2 ) );
|
||||
}
|
||||
else if( newLineIndex1 >= 0 )
|
||||
{
|
||||
clipboard = clipboard.substring( 0, newLineIndex1 );
|
||||
}
|
||||
else if( newLineIndex2 >= 0 )
|
||||
{
|
||||
clipboard = clipboard.substring( 0, newLineIndex2 );
|
||||
}
|
||||
|
||||
// Filter the string
|
||||
clipboard = ChatAllowedCharacters.filterAllowedCharacters( clipboard );
|
||||
|
||||
if( !clipboard.isEmpty() )
|
||||
{
|
||||
// Clip to 512 characters
|
||||
if( clipboard.length() > 512 )
|
||||
{
|
||||
clipboard = clipboard.substring( 0, 512 );
|
||||
}
|
||||
|
||||
// Queue the "paste" event
|
||||
queueEvent( "paste", new Object[]{
|
||||
clipboard
|
||||
} );
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Regular keys normally
|
||||
if( m_terminateTimer <= 0.0f && m_rebootTimer <= 0.0f && m_shutdownTimer <= 0.0f )
|
||||
{
|
||||
boolean repeat = Keyboard.isRepeatEvent();
|
||||
if( key > 0 )
|
||||
{
|
||||
if( !repeat )
|
||||
{
|
||||
m_keysDown.add( key );
|
||||
}
|
||||
|
||||
// Queue the "key" event
|
||||
queueEvent( "key", new Object[]{
|
||||
key, repeat
|
||||
} );
|
||||
}
|
||||
|
||||
if( (ch >= 32 && ch <= 126) || (ch >= 160 && ch <= 255) ) // printable chars in byte range
|
||||
{
|
||||
// Queue the "char" event
|
||||
queueEvent( "char", new Object[]{
|
||||
Character.toString( ch )
|
||||
} );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseClicked( int mouseX, int mouseY, int button )
|
||||
{
|
||||
if( mouseX >= getXPosition() && mouseX < getXPosition() + getWidth() &&
|
||||
mouseY >= getYPosition() && mouseY < getYPosition() + getHeight() )
|
||||
{
|
||||
if( !m_focus && button == 0)
|
||||
{
|
||||
m_focus = true;
|
||||
}
|
||||
|
||||
if( m_focus )
|
||||
{
|
||||
IComputer computer = m_computer.getComputer();
|
||||
if( !m_locked && computer != null && computer.isColour() && button >= 0 && button <= 2 )
|
||||
{
|
||||
Terminal term = computer.getTerminal();
|
||||
if( term != null )
|
||||
{
|
||||
int charX = ( mouseX - ( getXPosition() + m_leftMargin ) ) / FixedWidthFontRenderer.FONT_WIDTH;
|
||||
int charY = ( mouseY - ( getYPosition() + m_topMargin ) ) / FixedWidthFontRenderer.FONT_HEIGHT;
|
||||
charX = Math.min( Math.max( charX, 0 ), term.getWidth() - 1 );
|
||||
charY = Math.min( Math.max( charY, 0 ), term.getHeight() - 1 );
|
||||
|
||||
computer.queueEvent( "mouse_click", new Object[]{
|
||||
button + 1, charX + 1, charY + 1
|
||||
} );
|
||||
|
||||
m_lastClickButton = button;
|
||||
m_lastClickX = charX;
|
||||
m_lastClickY = charY;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( m_focus && button == 0 && m_allowFocusLoss )
|
||||
{
|
||||
m_focus = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleKeyboardInput()
|
||||
{
|
||||
for( int i=m_keysDown.size()-1; i>=0; --i )
|
||||
{
|
||||
int key = m_keysDown.get( i );
|
||||
if( !Keyboard.isKeyDown( key ) )
|
||||
{
|
||||
m_keysDown.remove( i );
|
||||
if( m_focus && !m_locked )
|
||||
{
|
||||
// Queue the "key_up" event
|
||||
queueEvent( "key_up", new Object[]{
|
||||
key
|
||||
} );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMouseInput( int mouseX, int mouseY )
|
||||
{
|
||||
IComputer computer = m_computer.getComputer();
|
||||
if( mouseX >= getXPosition() && mouseX < getXPosition() + getWidth() &&
|
||||
mouseY >= getYPosition() && mouseY < getYPosition() + getHeight() &&
|
||||
computer != null && computer.isColour() )
|
||||
{
|
||||
Terminal term = computer.getTerminal();
|
||||
if( term != null )
|
||||
{
|
||||
int charX = ( mouseX - (getXPosition() + m_leftMargin)) / FixedWidthFontRenderer.FONT_WIDTH;
|
||||
int charY = ( mouseY - (getYPosition() + m_topMargin)) / FixedWidthFontRenderer.FONT_HEIGHT;
|
||||
charX = Math.min( Math.max( charX, 0 ), term.getWidth() - 1 );
|
||||
charY = Math.min( Math.max( charY, 0 ), term.getHeight() - 1 );
|
||||
|
||||
if( m_lastClickButton >= 0 && !Mouse.isButtonDown( m_lastClickButton ) )
|
||||
{
|
||||
if( m_focus && !m_locked )
|
||||
{
|
||||
computer.queueEvent( "mouse_up", new Object[]{
|
||||
m_lastClickButton + 1, charX + 1, charY + 1
|
||||
} );
|
||||
}
|
||||
m_lastClickButton = -1;
|
||||
}
|
||||
|
||||
int wheelChange = Mouse.getEventDWheel();
|
||||
if( wheelChange == 0 && m_lastClickButton == -1 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if( m_focus && !m_locked )
|
||||
{
|
||||
if( wheelChange < 0 )
|
||||
{
|
||||
computer.queueEvent( "mouse_scroll", new Object[]{
|
||||
1, charX + 1, charY + 1
|
||||
} );
|
||||
}
|
||||
else if( wheelChange > 0 )
|
||||
{
|
||||
computer.queueEvent( "mouse_scroll", new Object[]{
|
||||
-1, charX + 1, charY + 1
|
||||
} );
|
||||
}
|
||||
|
||||
if( m_lastClickButton >= 0 && ( charX != m_lastClickX || charY != m_lastClickY ) )
|
||||
{
|
||||
computer.queueEvent( "mouse_drag", new Object[]{
|
||||
m_lastClickButton + 1, charX + 1, charY + 1
|
||||
} );
|
||||
m_lastClickX = charX;
|
||||
m_lastClickY = charY;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update()
|
||||
{
|
||||
// Handle special keys
|
||||
if( m_focus && !m_locked && (Keyboard.isKeyDown( 29 ) || Keyboard.isKeyDown( 157 )) )
|
||||
{
|
||||
// Ctrl+T for terminate
|
||||
if( Keyboard.isKeyDown( 20 ) )
|
||||
{
|
||||
if( m_terminateTimer < TERMINATE_TIME )
|
||||
{
|
||||
m_terminateTimer = m_terminateTimer + 0.05f;
|
||||
if( m_terminateTimer >= TERMINATE_TIME )
|
||||
{
|
||||
queueEvent( "terminate" );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_terminateTimer = 0.0f;
|
||||
}
|
||||
|
||||
// Ctrl+R for reboot
|
||||
if( Keyboard.isKeyDown(19) )
|
||||
{
|
||||
if( m_rebootTimer < TERMINATE_TIME )
|
||||
{
|
||||
m_rebootTimer = m_rebootTimer + 0.05f;
|
||||
if( m_rebootTimer >= TERMINATE_TIME )
|
||||
{
|
||||
IComputer computer = m_computer.getComputer();
|
||||
if( computer != null )
|
||||
{
|
||||
computer.reboot();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_rebootTimer = 0.0f;
|
||||
}
|
||||
|
||||
// Ctrl+S for shutdown
|
||||
if( Keyboard.isKeyDown(31) )
|
||||
{
|
||||
if( m_shutdownTimer < TERMINATE_TIME )
|
||||
{
|
||||
m_shutdownTimer = m_shutdownTimer + 0.05f;
|
||||
if( m_shutdownTimer >= TERMINATE_TIME )
|
||||
{
|
||||
IComputer computer = m_computer.getComputer();
|
||||
if( computer != null )
|
||||
{
|
||||
computer.shutdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_shutdownTimer = 0.0f;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_terminateTimer = 0.0f;
|
||||
m_rebootTimer = 0.0f;
|
||||
m_shutdownTimer = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw( Minecraft mc, int xOrigin, int yOrigin, int mouseX, int mouseY )
|
||||
{
|
||||
int startX = xOrigin + getXPosition();
|
||||
int startY = yOrigin + getYPosition();
|
||||
|
||||
// Draw the screen contents
|
||||
IComputer computer = m_computer.getComputer();
|
||||
Terminal terminal = (computer != null) ? computer.getTerminal() : null;
|
||||
if( terminal != null )
|
||||
{
|
||||
// Draw the terminal
|
||||
boolean greyscale = !computer.isColour();
|
||||
synchronized( terminal )
|
||||
{
|
||||
// Get the data from the terminal first
|
||||
// Unfortunately we have to keep the lock for the whole of drawing, so the text doesn't change under us.
|
||||
FixedWidthFontRenderer fontRenderer = (FixedWidthFontRenderer)ComputerCraft.getFixedWidthFontRenderer();
|
||||
boolean tblink = m_focus && terminal.getCursorBlink() && ComputerCraft.getGlobalCursorBlink();
|
||||
int tw = terminal.getWidth();
|
||||
int th = terminal.getHeight();
|
||||
int tx = terminal.getCursorX();
|
||||
int ty = terminal.getCursorY();
|
||||
|
||||
int x = startX + m_leftMargin;
|
||||
int y = startY + m_topMargin;
|
||||
|
||||
// Draw margins
|
||||
TextBuffer emptyLine = new TextBuffer( ' ', tw );
|
||||
if( m_topMargin > 0 )
|
||||
{
|
||||
fontRenderer.drawString( emptyLine, x, startY, terminal.getTextColourLine( 0 ), terminal.getBackgroundColourLine( 0 ), m_leftMargin, m_rightMargin, greyscale );
|
||||
}
|
||||
if( m_bottomMargin > 0 )
|
||||
{
|
||||
fontRenderer.drawString( emptyLine, x, startY + 2 * m_bottomMargin + ( th - 1 ) * FixedWidthFontRenderer.FONT_HEIGHT, terminal.getTextColourLine( th - 1 ), terminal.getBackgroundColourLine( th - 1 ), m_leftMargin, m_rightMargin, greyscale );
|
||||
}
|
||||
|
||||
// Draw lines
|
||||
for( int line=0; line<th; ++line )
|
||||
{
|
||||
TextBuffer text = terminal.getLine(line);
|
||||
TextBuffer colour = terminal.getTextColourLine( line );
|
||||
TextBuffer backgroundColour = terminal.getBackgroundColourLine( line );
|
||||
fontRenderer.drawString( text, x, y, colour, backgroundColour, m_leftMargin, m_rightMargin, greyscale );
|
||||
if( tblink && ty == line )
|
||||
{
|
||||
if( tx >= 0 && tx < tw )
|
||||
{
|
||||
TextBuffer cursor = new TextBuffer( '_', 1 );
|
||||
TextBuffer cursorColour = new TextBuffer( "0123456789abcdef".charAt( terminal.getTextColour() ), 1 );
|
||||
fontRenderer.drawString(
|
||||
cursor,
|
||||
x + FixedWidthFontRenderer.FONT_WIDTH * tx,
|
||||
y,
|
||||
cursorColour, null,
|
||||
0, 0,
|
||||
greyscale
|
||||
);
|
||||
}
|
||||
}
|
||||
y = y + FixedWidthFontRenderer.FONT_HEIGHT;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Draw a black background
|
||||
mc.getTextureManager().bindTexture( background );
|
||||
Colour black = Colour.Black;
|
||||
GlStateManager.color( black.getR(), black.getG(), black.getB(), 1.0f );
|
||||
try
|
||||
{
|
||||
drawTexturedModalRect( startX, startY, 0, 0, getWidth(), getHeight() );
|
||||
}
|
||||
finally
|
||||
{
|
||||
GlStateManager.color( 1.0f, 1.0f, 1.0f, 1.0f );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean suppressKeyPress( char c, int k )
|
||||
{
|
||||
if( m_focus )
|
||||
{
|
||||
return k != 1; // escape
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void queueEvent( String event )
|
||||
{
|
||||
IComputer computer = m_computer.getComputer();
|
||||
if( computer != null )
|
||||
{
|
||||
computer.queueEvent( event );
|
||||
}
|
||||
}
|
||||
|
||||
private void queueEvent( String event, Object[] args )
|
||||
{
|
||||
IComputer computer = m_computer.getComputer();
|
||||
if( computer != null )
|
||||
{
|
||||
computer.queueEvent( event, args );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,190 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.client.proxy;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.client.render.TileEntityTurtleRenderer;
|
||||
import dan200.computercraft.client.render.TurtleSmartItemModel;
|
||||
import dan200.computercraft.shared.proxy.CCTurtleProxyCommon;
|
||||
import dan200.computercraft.shared.turtle.blocks.TileTurtle;
|
||||
import dan200.computercraft.shared.turtle.core.TurtleBrain;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.ItemMeshDefinition;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.client.resources.IResourceManager;
|
||||
import net.minecraft.client.resources.SimpleReloadableResourceManager;
|
||||
import net.minecraft.client.resources.model.IBakedModel;
|
||||
import net.minecraft.client.resources.model.ModelBakery;
|
||||
import net.minecraft.client.resources.model.ModelResourceLocation;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.client.event.ModelBakeEvent;
|
||||
import net.minecraftforge.client.event.TextureStitchEvent;
|
||||
import net.minecraftforge.client.model.IModel;
|
||||
import net.minecraftforge.client.model.ISmartItemModel;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.fml.client.registry.ClientRegistry;
|
||||
import net.minecraftforge.fml.common.FMLCommonHandler;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.gameevent.TickEvent;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class CCTurtleProxyClient extends CCTurtleProxyCommon
|
||||
{
|
||||
public CCTurtleProxyClient()
|
||||
{
|
||||
}
|
||||
|
||||
// IComputerCraftProxy implementation
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
super.init();
|
||||
|
||||
// Register item models
|
||||
ItemMeshDefinition turtleMeshDefinition = new ItemMeshDefinition()
|
||||
{
|
||||
private ModelResourceLocation turtle_dynamic = new ModelResourceLocation( "computercraft:turtle_dynamic", "inventory" );
|
||||
|
||||
@Override
|
||||
public ModelResourceLocation getModelLocation( ItemStack stack )
|
||||
{
|
||||
return turtle_dynamic;
|
||||
}
|
||||
};
|
||||
String[] turtleModelNames = new String[] {
|
||||
"turtle_dynamic",
|
||||
"CC-Turtle", "CC-TurtleAdvanced",
|
||||
"turtle_black", "turtle_red", "turtle_green", "turtle_brown",
|
||||
"turtle_blue", "turtle_purple", "turtle_cyan", "turtle_lightGrey",
|
||||
"turtle_grey", "turtle_pink", "turtle_lime", "turtle_yellow",
|
||||
"turtle_lightBlue", "turtle_magenta", "turtle_orange", "turtle_white",
|
||||
"turtle_elf_overlay"
|
||||
};
|
||||
registerItemModel( ComputerCraft.Blocks.turtle, turtleMeshDefinition, turtleModelNames );
|
||||
registerItemModel( ComputerCraft.Blocks.turtleExpanded, turtleMeshDefinition, turtleModelNames );
|
||||
registerItemModel( ComputerCraft.Blocks.turtleAdvanced, turtleMeshDefinition, turtleModelNames );
|
||||
|
||||
// Setup renderers
|
||||
ClientRegistry.bindTileEntitySpecialRenderer( TileTurtle.class, new TileEntityTurtleRenderer() );
|
||||
|
||||
// Setup client forge handlers
|
||||
registerForgeHandlers();
|
||||
}
|
||||
|
||||
private void registerItemModel( Block block, ItemMeshDefinition definition, String[] names )
|
||||
{
|
||||
registerItemModel( Item.getItemFromBlock( block ), definition, names );
|
||||
}
|
||||
|
||||
private void registerItemModel( Item item, ItemMeshDefinition definition, String[] names )
|
||||
{
|
||||
for( int i=0; i<names.length; ++i )
|
||||
{
|
||||
ModelBakery.addVariantName( item, "computercraft:" + names[ i ] );
|
||||
}
|
||||
Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register( item, definition );
|
||||
}
|
||||
|
||||
private void registerForgeHandlers()
|
||||
{
|
||||
ForgeHandlers handlers = new ForgeHandlers();
|
||||
MinecraftForge.EVENT_BUS.register( handlers );
|
||||
}
|
||||
|
||||
public class ForgeHandlers
|
||||
{
|
||||
private TurtleSmartItemModel m_turtleSmartItemModel;
|
||||
|
||||
public ForgeHandlers()
|
||||
{
|
||||
m_turtleSmartItemModel = new TurtleSmartItemModel();
|
||||
IResourceManager resourceManager = Minecraft.getMinecraft().getResourceManager();
|
||||
if( resourceManager instanceof SimpleReloadableResourceManager )
|
||||
{
|
||||
SimpleReloadableResourceManager reloadableResourceManager = (SimpleReloadableResourceManager)resourceManager;
|
||||
reloadableResourceManager.registerReloadListener( m_turtleSmartItemModel );
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onTick( TickEvent.ClientTickEvent event )
|
||||
{
|
||||
if( event.phase == TickEvent.Phase.END )
|
||||
{
|
||||
TurtleBrain.cleanupBrains();
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onTextureStitchEvent( TextureStitchEvent.Pre event )
|
||||
{
|
||||
event.map.registerSprite( new ResourceLocation( "computercraft", "blocks/craftyUpgrade" ) );
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onModelBakeEvent( ModelBakeEvent event )
|
||||
{
|
||||
loadModel( event, "turtle_modem_off_left" );
|
||||
loadModel( event, "turtle_modem_on_left" );
|
||||
loadModel( event, "turtle_modem_off_right" );
|
||||
loadModel( event, "turtle_modem_on_right" );
|
||||
loadModel( event, "turtle_crafting_table_left" );
|
||||
loadModel( event, "turtle_crafting_table_right" );
|
||||
loadModel( event, "advanced_turtle_modem_off_left" );
|
||||
loadModel( event, "advanced_turtle_modem_on_left" );
|
||||
loadModel( event, "advanced_turtle_modem_off_right" );
|
||||
loadModel( event, "advanced_turtle_modem_on_right" );
|
||||
loadSmartModel( event, "turtle_dynamic", m_turtleSmartItemModel );
|
||||
}
|
||||
|
||||
private void loadModel( ModelBakeEvent event, String name )
|
||||
{
|
||||
try
|
||||
{
|
||||
IModel model = event.modelLoader.getModel(
|
||||
new ResourceLocation( "computercraft", "block/" + name )
|
||||
);
|
||||
IBakedModel bakedModel = model.bake(
|
||||
model.getDefaultState(),
|
||||
DefaultVertexFormats.ITEM,
|
||||
new Function<ResourceLocation, TextureAtlasSprite>()
|
||||
{
|
||||
@Override
|
||||
public TextureAtlasSprite apply( ResourceLocation location )
|
||||
{
|
||||
return Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite( location.toString() );
|
||||
}
|
||||
}
|
||||
);
|
||||
event.modelRegistry.putObject(
|
||||
new ModelResourceLocation( "computercraft:" + name, "inventory" ),
|
||||
bakedModel
|
||||
);
|
||||
}
|
||||
catch( IOException e )
|
||||
{
|
||||
System.out.println( "Could not load model: name" );
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void loadSmartModel( ModelBakeEvent event, String name, ISmartItemModel smartModel )
|
||||
{
|
||||
event.modelRegistry.putObject(
|
||||
new ModelResourceLocation( "computercraft:" + name, "inventory" ),
|
||||
smartModel
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,492 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.client.proxy;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.client.gui.*;
|
||||
import dan200.computercraft.client.render.TileEntityMonitorRenderer;
|
||||
import dan200.computercraft.shared.computer.blocks.TileComputer;
|
||||
import dan200.computercraft.shared.computer.core.ClientComputer;
|
||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||
import dan200.computercraft.shared.computer.items.ItemComputer;
|
||||
import dan200.computercraft.shared.media.inventory.ContainerHeldItem;
|
||||
import dan200.computercraft.shared.media.items.ItemPrintout;
|
||||
import dan200.computercraft.shared.network.ComputerCraftPacket;
|
||||
import dan200.computercraft.shared.peripheral.diskdrive.TileDiskDrive;
|
||||
import dan200.computercraft.shared.peripheral.monitor.TileMonitor;
|
||||
import dan200.computercraft.shared.peripheral.printer.TilePrinter;
|
||||
import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
|
||||
import dan200.computercraft.shared.proxy.ComputerCraftProxyCommon;
|
||||
import dan200.computercraft.shared.turtle.blocks.TileTurtle;
|
||||
import dan200.computercraft.shared.turtle.entity.TurtleVisionCamera;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.ItemMeshDefinition;
|
||||
import net.minecraft.client.resources.model.ModelBakery;
|
||||
import net.minecraft.client.resources.model.ModelResourceLocation;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.InventoryPlayer;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.util.BlockPos;
|
||||
import net.minecraft.util.IThreadListener;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.client.event.RenderGameOverlayEvent;
|
||||
import net.minecraftforge.client.event.RenderHandEvent;
|
||||
import net.minecraftforge.client.event.RenderPlayerEvent;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.fml.client.FMLClientHandler;
|
||||
import net.minecraftforge.fml.client.registry.ClientRegistry;
|
||||
import net.minecraftforge.fml.common.FMLCommonHandler;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.gameevent.TickEvent;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ComputerCraftProxyClient extends ComputerCraftProxyCommon
|
||||
{
|
||||
private long m_tick;
|
||||
private long m_renderFrame;
|
||||
private FixedWidthFontRenderer m_fixedWidthFontRenderer;
|
||||
|
||||
public ComputerCraftProxyClient()
|
||||
{
|
||||
}
|
||||
|
||||
// IComputerCraftProxy implementation
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
super.init();
|
||||
m_tick = 0;
|
||||
m_renderFrame = 0;
|
||||
|
||||
// Load textures
|
||||
Minecraft mc = Minecraft.getMinecraft();
|
||||
m_fixedWidthFontRenderer = new FixedWidthFontRenderer( mc.getTextureManager() );
|
||||
|
||||
// Register item models
|
||||
registerItemModel( ComputerCraft.Blocks.computer, new ItemMeshDefinition()
|
||||
{
|
||||
private ModelResourceLocation computer = new ModelResourceLocation( "computercraft:CC-Computer", "inventory" );
|
||||
private ModelResourceLocation advanced_computer = new ModelResourceLocation( "computercraft:advanced_computer", "inventory" );
|
||||
|
||||
@Override
|
||||
public ModelResourceLocation getModelLocation( ItemStack stack )
|
||||
{
|
||||
ItemComputer itemComputer = (ItemComputer) stack.getItem();
|
||||
ComputerFamily family = itemComputer.getFamily( stack.getItemDamage() );
|
||||
return ( family == ComputerFamily.Advanced ) ? advanced_computer : computer;
|
||||
}
|
||||
}, new String[]{ "CC-Computer", "advanced_computer" } );
|
||||
registerItemModel( ComputerCraft.Blocks.peripheral, 0, "CC-Peripheral" );
|
||||
registerItemModel( ComputerCraft.Blocks.peripheral, 1, "wireless_modem" );
|
||||
registerItemModel( ComputerCraft.Blocks.peripheral, 2, "monitor" );
|
||||
registerItemModel( ComputerCraft.Blocks.peripheral, 3, "printer" );
|
||||
registerItemModel( ComputerCraft.Blocks.peripheral, 4, "advanced_monitor" );
|
||||
registerItemModel( ComputerCraft.Blocks.cable, 0, "CC-Cable" );
|
||||
registerItemModel( ComputerCraft.Blocks.cable, 1, "wired_modem" );
|
||||
registerItemModel( ComputerCraft.Blocks.commandComputer, "command_computer" );
|
||||
registerItemModel( ComputerCraft.Blocks.advancedModem, "advanced_modem" );
|
||||
|
||||
registerItemModel( ComputerCraft.Items.disk, "disk" );
|
||||
registerItemModel( ComputerCraft.Items.diskExpanded, "diskExpanded" );
|
||||
registerItemModel( ComputerCraft.Items.treasureDisk, "treasureDisk" );
|
||||
registerItemModel( ComputerCraft.Items.printout, 0, "printout" );
|
||||
registerItemModel( ComputerCraft.Items.printout, 1, "pages" );
|
||||
registerItemModel( ComputerCraft.Items.printout, 2, "book" );
|
||||
registerItemModel( ComputerCraft.Items.pocketComputer, new ItemMeshDefinition()
|
||||
{
|
||||
private ModelResourceLocation pocket_computer_off = new ModelResourceLocation( "computercraft:pocketComputer", "inventory" );
|
||||
private ModelResourceLocation pocket_computer_on = new ModelResourceLocation( "computercraft:pocket_computer_on", "inventory" );
|
||||
private ModelResourceLocation pocket_computer_blinking = new ModelResourceLocation( "computercraft:pocket_computer_blinking", "inventory" );
|
||||
private ModelResourceLocation pocket_computer_on_modem_on = new ModelResourceLocation( "computercraft:pocket_computer_on_modem_on", "inventory" );
|
||||
private ModelResourceLocation pocket_computer_blinking_modem_on = new ModelResourceLocation( "computercraft:pocket_computer_blinking_modem_on", "inventory" );
|
||||
private ModelResourceLocation advanced_pocket_computer_off = new ModelResourceLocation( "computercraft:advanced_pocket_computer_off", "inventory" );
|
||||
private ModelResourceLocation advanced_pocket_computer_on = new ModelResourceLocation( "computercraft:advanced_pocket_computer_on", "inventory" );
|
||||
private ModelResourceLocation advanced_pocket_computer_blinking = new ModelResourceLocation( "computercraft:advanced_pocket_computer_blinking", "inventory" );
|
||||
private ModelResourceLocation advanced_pocket_computer_on_modem_on = new ModelResourceLocation( "computercraft:advanced_pocket_computer_on_modem_on", "inventory" );
|
||||
private ModelResourceLocation advanced_pocket_computer_blinking_modem_on = new ModelResourceLocation( "computercraft:advanced_pocket_computer_blinking_modem_on", "inventory" );
|
||||
|
||||
@Override
|
||||
public ModelResourceLocation getModelLocation( ItemStack stack )
|
||||
{
|
||||
ItemPocketComputer itemPocketComputer = (ItemPocketComputer)stack.getItem();
|
||||
boolean modemOn = itemPocketComputer.getModemState( stack );
|
||||
switch( itemPocketComputer.getFamily( stack ) )
|
||||
{
|
||||
case Advanced:
|
||||
{
|
||||
switch( itemPocketComputer.getState( stack ) )
|
||||
{
|
||||
case Off:
|
||||
default:
|
||||
{
|
||||
return advanced_pocket_computer_off;
|
||||
}
|
||||
case On:
|
||||
{
|
||||
return modemOn ? advanced_pocket_computer_on_modem_on : advanced_pocket_computer_on;
|
||||
}
|
||||
case Blinking:
|
||||
{
|
||||
return modemOn ? advanced_pocket_computer_blinking_modem_on : advanced_pocket_computer_blinking;
|
||||
}
|
||||
}
|
||||
}
|
||||
case Normal:
|
||||
default:
|
||||
{
|
||||
switch( itemPocketComputer.getState( stack ) )
|
||||
{
|
||||
case Off:
|
||||
default:
|
||||
{
|
||||
return pocket_computer_off;
|
||||
}
|
||||
case On:
|
||||
{
|
||||
return modemOn ? pocket_computer_on_modem_on : pocket_computer_on;
|
||||
}
|
||||
case Blinking:
|
||||
{
|
||||
return modemOn ? pocket_computer_blinking_modem_on : pocket_computer_blinking;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, new String[] {
|
||||
"pocketComputer", "pocket_computer_on", "pocket_computer_blinking", "pocket_computer_on_modem_on", "pocket_computer_blinking_modem_on",
|
||||
"advanced_pocket_computer_off", "advanced_pocket_computer_on", "advanced_pocket_computer_blinking", "advanced_pocket_computer_on_modem_on", "advanced_pocket_computer_blinking_modem_on",
|
||||
} );
|
||||
|
||||
// Setup renderers
|
||||
ClientRegistry.bindTileEntitySpecialRenderer( TileMonitor.class, new TileEntityMonitorRenderer() );
|
||||
|
||||
// Setup client forge handlers
|
||||
registerForgeHandlers();
|
||||
}
|
||||
|
||||
private void registerItemModel( Block block, int damage, String name )
|
||||
{
|
||||
registerItemModel( Item.getItemFromBlock( block ), damage, name );
|
||||
}
|
||||
|
||||
private void registerItemModel( Item item, int damage, String name )
|
||||
{
|
||||
name = "computercraft:" + name;
|
||||
ModelResourceLocation res = new ModelResourceLocation( name, "inventory" );
|
||||
ModelBakery.addVariantName( item, name );
|
||||
Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register( item, damage, res );
|
||||
}
|
||||
|
||||
private void registerItemModel( Block block, String name )
|
||||
{
|
||||
registerItemModel( Item.getItemFromBlock( block ), name );
|
||||
}
|
||||
|
||||
private void registerItemModel( Item item, String name )
|
||||
{
|
||||
name = "computercraft:" + name;
|
||||
final ModelResourceLocation res = new ModelResourceLocation( name, "inventory" );
|
||||
ModelBakery.addVariantName( item, name );
|
||||
Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register( item, new ItemMeshDefinition()
|
||||
{
|
||||
@Override
|
||||
public ModelResourceLocation getModelLocation( ItemStack stack )
|
||||
{
|
||||
return res;
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
private void registerItemModel( Block block, ItemMeshDefinition definition, String[] names )
|
||||
{
|
||||
registerItemModel( Item.getItemFromBlock( block ), definition, names );
|
||||
}
|
||||
|
||||
private void registerItemModel( Item item, ItemMeshDefinition definition, String[] names )
|
||||
{
|
||||
for( int i=0; i<names.length; ++i )
|
||||
{
|
||||
ModelBakery.addVariantName( item, "computercraft:" + names[i] );
|
||||
}
|
||||
Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register( item, definition );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isClient()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getGlobalCursorBlink()
|
||||
{
|
||||
return ( m_tick / 8) % 2 == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getRenderFrame()
|
||||
{
|
||||
return m_renderFrame;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteDisplayLists( int list, int range )
|
||||
{
|
||||
GL11.glDeleteLists( list, range );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getFixedWidthFontRenderer()
|
||||
{
|
||||
return m_fixedWidthFontRenderer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRecordInfo( ItemStack recordStack )
|
||||
{
|
||||
List info = new ArrayList(1);
|
||||
recordStack.getItem().addInformation( recordStack, null, info, false );
|
||||
if( info.size() > 0 ) {
|
||||
return info.get(0).toString();
|
||||
} else {
|
||||
return super.getRecordInfo( recordStack );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playRecord( String record, String recordInfo, World world, BlockPos pos )
|
||||
{
|
||||
Minecraft mc = FMLClientHandler.instance().getClient();
|
||||
world.playRecord( pos, record );
|
||||
if( record != null )
|
||||
{
|
||||
mc.ingameGUI.setRecordPlayingMessage( recordInfo );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getDiskDriveGUI( InventoryPlayer inventory, TileDiskDrive drive )
|
||||
{
|
||||
return new GuiDiskDrive( inventory, drive );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getComputerGUI( TileComputer computer )
|
||||
{
|
||||
return new GuiComputer( computer );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getPrinterGUI( InventoryPlayer inventory, TilePrinter printer )
|
||||
{
|
||||
return new GuiPrinter( inventory, printer );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getTurtleGUI( InventoryPlayer inventory, TileTurtle turtle )
|
||||
{
|
||||
return new GuiTurtle( turtle.getWorld(), inventory, turtle );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getPrintoutGUI( InventoryPlayer inventory )
|
||||
{
|
||||
ContainerHeldItem container = new ContainerHeldItem( inventory );
|
||||
if( container.getStack() != null && container.getStack().getItem() instanceof ItemPrintout )
|
||||
{
|
||||
return new GuiPrintout( container );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getPocketComputerGUI( InventoryPlayer inventory )
|
||||
{
|
||||
ContainerHeldItem container = new ContainerHeldItem( inventory );
|
||||
if( container.getStack() != null && container.getStack().getItem() instanceof ItemPocketComputer )
|
||||
{
|
||||
return new GuiPocketComputer( container );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getWorldDir( World world )
|
||||
{
|
||||
return new File( ComputerCraft.getBaseDir(), "saves/" + world.getSaveHandler().getWorldDirectoryName() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handlePacket( final ComputerCraftPacket packet, final EntityPlayer player )
|
||||
{
|
||||
switch( packet.m_packetType )
|
||||
{
|
||||
case ComputerCraftPacket.ComputerChanged:
|
||||
case ComputerCraftPacket.ComputerDeleted:
|
||||
{
|
||||
// Packet from Server to Client
|
||||
IThreadListener listener = Minecraft.getMinecraft();
|
||||
if( listener != null )
|
||||
{
|
||||
if( listener.isCallingFromMinecraftThread() )
|
||||
{
|
||||
processPacket( packet, player );
|
||||
}
|
||||
else
|
||||
{
|
||||
listener.addScheduledTask( new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
processPacket( packet, player );
|
||||
}
|
||||
} );
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
// Packet from Client to Server
|
||||
super.handlePacket( packet, player );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void processPacket( ComputerCraftPacket packet, EntityPlayer player )
|
||||
{
|
||||
switch( packet.m_packetType )
|
||||
{
|
||||
///////////////////////////////////
|
||||
// Packets from Server to Client //
|
||||
///////////////////////////////////
|
||||
case ComputerCraftPacket.ComputerChanged:
|
||||
{
|
||||
int instanceID = packet.m_dataInt[ 0 ];
|
||||
if( !ComputerCraft.clientComputerRegistry.contains( instanceID ) )
|
||||
{
|
||||
ComputerCraft.clientComputerRegistry.add( instanceID, new ClientComputer( instanceID ) );
|
||||
}
|
||||
ComputerCraft.clientComputerRegistry.get( instanceID ).handlePacket( packet, (EntityPlayer) player );
|
||||
break;
|
||||
}
|
||||
case ComputerCraftPacket.ComputerDeleted:
|
||||
{
|
||||
int instanceID = packet.m_dataInt[ 0 ];
|
||||
if( ComputerCraft.clientComputerRegistry.contains( instanceID ) )
|
||||
{
|
||||
ComputerCraft.clientComputerRegistry.remove( instanceID );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void registerForgeHandlers()
|
||||
{
|
||||
ForgeHandlers handlers = new ForgeHandlers();
|
||||
FMLCommonHandler.instance().bus().register( handlers );
|
||||
MinecraftForge.EVENT_BUS.register( handlers );
|
||||
}
|
||||
|
||||
public class ForgeHandlers
|
||||
{
|
||||
public ForgeHandlers()
|
||||
{
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onRenderHand( RenderHandEvent event )
|
||||
{
|
||||
// Don't draw the player arm when in turtle vision
|
||||
Minecraft mc = Minecraft.getMinecraft();
|
||||
if( mc.getRenderViewEntity() instanceof TurtleVisionCamera )
|
||||
{
|
||||
event.setCanceled( true );
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onRenderPlayer( RenderPlayerEvent.Pre event )
|
||||
{
|
||||
Minecraft mc = Minecraft.getMinecraft();
|
||||
if( event.entityPlayer.isUser() && mc.getRenderViewEntity() instanceof TurtleVisionCamera )
|
||||
{
|
||||
// HACK: Force the 'livingPlayer' variable to the player, this ensures the entity is drawn
|
||||
event.renderer.getRenderManager().livingPlayer = event.entityPlayer;
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onRenderPlayer( RenderPlayerEvent.Post event )
|
||||
{
|
||||
Minecraft mc = Minecraft.getMinecraft();
|
||||
if( event.entityPlayer.isUser() && mc.getRenderViewEntity() instanceof TurtleVisionCamera )
|
||||
{
|
||||
// HACK: Restore the 'livingPlayer' variable to what it was before the RenderPlayerEvent.Pre hack
|
||||
event.renderer.getRenderManager().livingPlayer = mc.getRenderViewEntity();
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onPreRenderGameOverlay( RenderGameOverlayEvent.Pre event )
|
||||
{
|
||||
Minecraft mc = Minecraft.getMinecraft();
|
||||
if( mc.getRenderViewEntity() instanceof TurtleVisionCamera )
|
||||
{
|
||||
switch( event.type )
|
||||
{
|
||||
case HELMET:
|
||||
case PORTAL:
|
||||
//case CROSSHAIRS:
|
||||
case BOSSHEALTH:
|
||||
case ARMOR:
|
||||
case HEALTH:
|
||||
case FOOD:
|
||||
case AIR:
|
||||
case HOTBAR:
|
||||
case EXPERIENCE:
|
||||
case HEALTHMOUNT:
|
||||
case JUMPBAR:
|
||||
{
|
||||
event.setCanceled( true );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onTick( TickEvent.ClientTickEvent event )
|
||||
{
|
||||
if( event.phase == TickEvent.Phase.START )
|
||||
{
|
||||
m_tick++;
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onRenderTick( TickEvent.RenderTickEvent event )
|
||||
{
|
||||
if( event.phase == TickEvent.Phase.START )
|
||||
{
|
||||
m_renderFrame++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,287 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.client.render;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.client.gui.FixedWidthFontRenderer;
|
||||
import dan200.computercraft.core.terminal.Terminal;
|
||||
import dan200.computercraft.core.terminal.TextBuffer;
|
||||
import dan200.computercraft.shared.common.ClientTerminal;
|
||||
import dan200.computercraft.shared.common.ITerminal;
|
||||
import dan200.computercraft.shared.peripheral.monitor.TileMonitor;
|
||||
import dan200.computercraft.shared.util.Colour;
|
||||
import dan200.computercraft.shared.util.DirectionUtil;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.client.renderer.WorldRenderer;
|
||||
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.BlockPos;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.client.MinecraftForgeClient;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
public class TileEntityMonitorRenderer extends TileEntitySpecialRenderer<TileMonitor>
|
||||
{
|
||||
public TileEntityMonitorRenderer()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderTileEntityAt( TileMonitor tileEntity, double posX, double posY, double posZ, float f, int i )
|
||||
{
|
||||
if( tileEntity != null )
|
||||
{
|
||||
renderMonitorAt( tileEntity, posX, posY, posZ, f, i );
|
||||
}
|
||||
}
|
||||
|
||||
private void renderMonitorAt( TileMonitor monitor, double posX, double posY, double posZ, float f, int i )
|
||||
{
|
||||
// Render from the origin monitor
|
||||
TileMonitor origin = monitor.getOrigin();
|
||||
if( origin == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Ensure each monitor is rendered only once
|
||||
long renderFrame = ComputerCraft.getRenderFrame();
|
||||
if( origin.m_lastRenderFrame == renderFrame )
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
origin.m_lastRenderFrame = renderFrame;
|
||||
}
|
||||
|
||||
boolean redraw = origin.pollChanged();
|
||||
BlockPos monitorPos = monitor.getPos();
|
||||
BlockPos originPos = origin.getPos();
|
||||
posX += originPos.getX() - monitorPos.getX();
|
||||
posY += originPos.getY() - monitorPos.getY();
|
||||
posZ += originPos.getZ() - monitorPos.getZ();
|
||||
|
||||
// Determine orientation
|
||||
EnumFacing dir = origin.getDirection();
|
||||
EnumFacing front = origin.getFront();
|
||||
float yaw = DirectionUtil.toYawAngle( dir );
|
||||
float pitch = DirectionUtil.toPitchAngle( front );
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
try
|
||||
{
|
||||
// Setup initial transform
|
||||
GlStateManager.translate( posX + 0.5, posY + 0.5, posZ + 0.5 );
|
||||
GlStateManager.rotate( -yaw, 0.0f, 1.0f, 0.0f );
|
||||
GlStateManager.rotate( pitch, 1.0f, 0.0f, 0.0f );
|
||||
GlStateManager.translate(
|
||||
-0.5 + TileMonitor.RENDER_BORDER + TileMonitor.RENDER_MARGIN,
|
||||
((double)origin.getHeight() - 0.5) - (TileMonitor.RENDER_BORDER + TileMonitor.RENDER_MARGIN),
|
||||
0.5
|
||||
);
|
||||
double xSize = (double)origin.getWidth() - 2.0 * ( TileMonitor.RENDER_MARGIN + TileMonitor.RENDER_BORDER );
|
||||
double ySize = (double)origin.getHeight() - 2.0 * ( TileMonitor.RENDER_MARGIN + TileMonitor.RENDER_BORDER );
|
||||
|
||||
// Get renderers
|
||||
Minecraft mc = Minecraft.getMinecraft();
|
||||
Tessellator tessellator = Tessellator.getInstance();
|
||||
WorldRenderer renderer = tessellator.getWorldRenderer();
|
||||
|
||||
// Get terminal
|
||||
ClientTerminal clientTerminal = (ClientTerminal)origin.getTerminal();
|
||||
Terminal terminal = (clientTerminal != null) ? clientTerminal.getTerminal() : null;
|
||||
redraw = redraw || (clientTerminal != null && clientTerminal.hasTerminalChanged());
|
||||
|
||||
// Draw the contents
|
||||
GlStateManager.depthMask( false );
|
||||
GlStateManager.disableLighting();
|
||||
try
|
||||
{
|
||||
if( terminal != null )
|
||||
{
|
||||
// Allocate display lists
|
||||
if( origin.m_renderDisplayList < 0 )
|
||||
{
|
||||
origin.m_renderDisplayList = GL11.glGenLists( 3 );
|
||||
redraw = true;
|
||||
}
|
||||
|
||||
// Draw a terminal
|
||||
boolean greyscale = !clientTerminal.isColour();
|
||||
int width = terminal.getWidth();
|
||||
int height = terminal.getHeight();
|
||||
int cursorX = terminal.getCursorX();
|
||||
int cursorY = terminal.getCursorY();
|
||||
FixedWidthFontRenderer fontRenderer = (FixedWidthFontRenderer)ComputerCraft.getFixedWidthFontRenderer();
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
try
|
||||
{
|
||||
double xScale = xSize / (double) ( width * FixedWidthFontRenderer.FONT_WIDTH );
|
||||
double yScale = ySize / (double) ( height * FixedWidthFontRenderer.FONT_HEIGHT );
|
||||
GlStateManager.scale( xScale, -yScale, 1.0 );
|
||||
|
||||
// Draw background
|
||||
mc.getTextureManager().bindTexture( FixedWidthFontRenderer.background );
|
||||
if( redraw )
|
||||
{
|
||||
// Build background display list
|
||||
GL11.glNewList( origin.m_renderDisplayList, GL11.GL_COMPILE );
|
||||
try
|
||||
{
|
||||
double marginXSize = TileMonitor.RENDER_MARGIN / xScale;
|
||||
double marginYSize = TileMonitor.RENDER_MARGIN / yScale;
|
||||
double marginSquash = marginYSize / (double) FixedWidthFontRenderer.FONT_HEIGHT;
|
||||
|
||||
// Top and bottom margins
|
||||
GL11.glPushMatrix();
|
||||
try
|
||||
{
|
||||
GL11.glScaled( 1.0, marginSquash, 1.0 );
|
||||
GL11.glTranslated( 0.0, -marginYSize / marginSquash, 0.0 );
|
||||
fontRenderer.drawStringBackgroundPart( 0, 0, terminal.getBackgroundColourLine( 0 ), marginXSize, marginXSize, greyscale );
|
||||
GL11.glTranslated( 0.0, ( marginYSize + height * FixedWidthFontRenderer.FONT_HEIGHT ) / marginSquash, 0.0 );
|
||||
fontRenderer.drawStringBackgroundPart( 0, 0, terminal.getBackgroundColourLine( height - 1 ), marginXSize, marginXSize, greyscale );
|
||||
}
|
||||
finally
|
||||
{
|
||||
GL11.glPopMatrix();
|
||||
}
|
||||
|
||||
// Backgrounds
|
||||
for( int y = 0; y < height; ++y )
|
||||
{
|
||||
fontRenderer.drawStringBackgroundPart(
|
||||
0, FixedWidthFontRenderer.FONT_HEIGHT * y,
|
||||
terminal.getBackgroundColourLine( y ),
|
||||
marginXSize, marginXSize,
|
||||
greyscale
|
||||
);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
GL11.glEndList();
|
||||
}
|
||||
}
|
||||
GlStateManager.callList( origin.m_renderDisplayList );
|
||||
|
||||
// Draw text
|
||||
mc.getTextureManager().bindTexture( FixedWidthFontRenderer.font );
|
||||
if( redraw )
|
||||
{
|
||||
// Build text display list
|
||||
GL11.glNewList( origin.m_renderDisplayList + 1, GL11.GL_COMPILE );
|
||||
try
|
||||
{
|
||||
// Lines
|
||||
for( int y = 0; y < height; ++y )
|
||||
{
|
||||
fontRenderer.drawStringTextPart(
|
||||
0, FixedWidthFontRenderer.FONT_HEIGHT * y,
|
||||
terminal.getLine( y ),
|
||||
terminal.getTextColourLine( y ),
|
||||
greyscale
|
||||
);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
GL11.glEndList();
|
||||
}
|
||||
}
|
||||
GlStateManager.callList( origin.m_renderDisplayList + 1 );
|
||||
|
||||
// Draw cursor
|
||||
mc.getTextureManager().bindTexture( FixedWidthFontRenderer.font );
|
||||
if( redraw )
|
||||
{
|
||||
// Build cursor display list
|
||||
GL11.glNewList( origin.m_renderDisplayList + 2, GL11.GL_COMPILE );
|
||||
try
|
||||
{
|
||||
// Cursor
|
||||
if( terminal.getCursorBlink() && cursorX >= 0 && cursorX < width && cursorY >= 0 && cursorY < height )
|
||||
{
|
||||
TextBuffer cursor = new TextBuffer( "_" );
|
||||
TextBuffer cursorColour = new TextBuffer( "0123456789abcdef".charAt( terminal.getTextColour() ), 1 );
|
||||
fontRenderer.drawString(
|
||||
cursor,
|
||||
FixedWidthFontRenderer.FONT_WIDTH * cursorX,
|
||||
FixedWidthFontRenderer.FONT_HEIGHT * cursorY,
|
||||
cursorColour, null,
|
||||
0, 0,
|
||||
greyscale
|
||||
);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
GL11.glEndList();
|
||||
}
|
||||
}
|
||||
if( ComputerCraft.getGlobalCursorBlink() )
|
||||
{
|
||||
GlStateManager.callList( origin.m_renderDisplayList + 2 );
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Draw a big black quad
|
||||
mc.getTextureManager().bindTexture( FixedWidthFontRenderer.background );
|
||||
renderer.begin( GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR );
|
||||
Colour colour = Colour.Black;
|
||||
renderer.pos( -TileMonitor.RENDER_MARGIN, -ySize - TileMonitor.RENDER_MARGIN, 0.0 ).tex( 0.0, 1.0 ).color( colour.getR(), colour.getG(), colour.getB(), 1.0f ).endVertex();
|
||||
renderer.pos( xSize + TileMonitor.RENDER_MARGIN, -ySize - TileMonitor.RENDER_MARGIN, 0.0 ).tex( 1.0, 1.0 ).color( colour.getR(), colour.getG(), colour.getB(), 1.0f ).endVertex();
|
||||
renderer.pos( xSize + TileMonitor.RENDER_MARGIN, TileMonitor.RENDER_MARGIN, 0.0D ).tex( 1.0, 0.0 ).color( colour.getR(), colour.getG(), colour.getB(), 1.0f ).endVertex();
|
||||
renderer.pos( -TileMonitor.RENDER_MARGIN, TileMonitor.RENDER_MARGIN, 0.0D ).tex( 0.0, 0.0 ).color( colour.getR(), colour.getG(), colour.getB(), 1.0f ).endVertex();
|
||||
renderer.pos( -TileMonitor.RENDER_MARGIN, -ySize - TileMonitor.RENDER_MARGIN, 0.0 ).tex( 0.0, 1.0 ).color( colour.getR(), colour.getG(), colour.getB(), 1.0f ).endVertex();
|
||||
tessellator.draw();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
GlStateManager.depthMask( true );
|
||||
GlStateManager.enableLighting();
|
||||
}
|
||||
|
||||
// Draw the depth blocker
|
||||
GlStateManager.colorMask( false, false, false, false );
|
||||
try
|
||||
{
|
||||
mc.getTextureManager().bindTexture( FixedWidthFontRenderer.background );
|
||||
renderer.begin( GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR );
|
||||
Colour colour = Colour.Black;
|
||||
renderer.pos( -TileMonitor.RENDER_MARGIN, -ySize - TileMonitor.RENDER_MARGIN, 0.0 ).tex( 0.0, 1.0 ).color( colour.getR(), colour.getG(), colour.getB(), 1.0f ).endVertex();
|
||||
renderer.pos( xSize + TileMonitor.RENDER_MARGIN, -ySize - TileMonitor.RENDER_MARGIN, 0.0 ).tex( 1.0, 1.0 ).color( colour.getR(), colour.getG(), colour.getB(), 1.0f ).endVertex();
|
||||
renderer.pos( xSize + TileMonitor.RENDER_MARGIN, TileMonitor.RENDER_MARGIN, 0.0D ).tex( 1.0, 0.0 ).color( colour.getR(), colour.getG(), colour.getB(), 1.0f ).endVertex();
|
||||
renderer.pos( -TileMonitor.RENDER_MARGIN, TileMonitor.RENDER_MARGIN, 0.0D ).tex( 0.0, 0.0 ).color( colour.getR(), colour.getG(), colour.getB(), 1.0f ).endVertex();
|
||||
renderer.pos( -TileMonitor.RENDER_MARGIN, -ySize - TileMonitor.RENDER_MARGIN, 0.0 ).tex( 0.0, 1.0 ).color( colour.getR(), colour.getG(), colour.getB(), 1.0f ).endVertex();
|
||||
tessellator.draw();
|
||||
}
|
||||
finally
|
||||
{
|
||||
GlStateManager.colorMask( true, true, true, true );
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
GlStateManager.color( 1.0f, 1.0f, 1.0f, 1.0f );
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,398 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.client.render;
|
||||
|
||||
import dan200.computercraft.api.turtle.ITurtleUpgrade;
|
||||
import dan200.computercraft.api.turtle.TurtleSide;
|
||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||
import dan200.computercraft.shared.computer.core.IComputer;
|
||||
import dan200.computercraft.shared.turtle.blocks.TileTurtle;
|
||||
import dan200.computercraft.shared.turtle.entity.TurtleVisionCamera;
|
||||
import dan200.computercraft.shared.util.Colour;
|
||||
import dan200.computercraft.shared.util.Holiday;
|
||||
import dan200.computercraft.shared.util.HolidayUtil;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.FontRenderer;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.client.renderer.WorldRenderer;
|
||||
import net.minecraft.client.renderer.block.model.BakedQuad;
|
||||
import net.minecraft.client.renderer.entity.RenderManager;
|
||||
import net.minecraft.client.renderer.texture.TextureMap;
|
||||
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.client.resources.model.IBakedModel;
|
||||
import net.minecraft.client.resources.model.ModelManager;
|
||||
import net.minecraft.client.resources.model.ModelResourceLocation;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.*;
|
||||
import net.minecraftforge.client.ForgeHooksClient;
|
||||
import net.minecraftforge.client.model.IFlexibleBakedModel;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import javax.vecmath.Matrix4f;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
public class TileEntityTurtleRenderer extends TileEntitySpecialRenderer<TileTurtle>
|
||||
{
|
||||
private static ModelResourceLocation NORMAL_TURTLE_MODEL = new ModelResourceLocation( "computercraft:CC-Turtle", "inventory" );
|
||||
private static ModelResourceLocation ADVANCED_TURTLE_MODEL = new ModelResourceLocation( "computercraft:CC-TurtleAdvanced", "inventory" );
|
||||
private static ModelResourceLocation[] COLOUR_TURTLE_MODELS = new ModelResourceLocation[] {
|
||||
new ModelResourceLocation( "computercraft:turtle_black", "inventory" ),
|
||||
new ModelResourceLocation( "computercraft:turtle_red", "inventory" ),
|
||||
new ModelResourceLocation( "computercraft:turtle_green", "inventory" ),
|
||||
new ModelResourceLocation( "computercraft:turtle_brown", "inventory" ),
|
||||
new ModelResourceLocation( "computercraft:turtle_blue", "inventory" ),
|
||||
new ModelResourceLocation( "computercraft:turtle_purple", "inventory" ),
|
||||
new ModelResourceLocation( "computercraft:turtle_cyan", "inventory" ),
|
||||
new ModelResourceLocation( "computercraft:turtle_lightGrey", "inventory" ),
|
||||
new ModelResourceLocation( "computercraft:turtle_grey", "inventory" ),
|
||||
new ModelResourceLocation( "computercraft:turtle_pink", "inventory" ),
|
||||
new ModelResourceLocation( "computercraft:turtle_lime", "inventory" ),
|
||||
new ModelResourceLocation( "computercraft:turtle_yellow", "inventory" ),
|
||||
new ModelResourceLocation( "computercraft:turtle_lightBlue", "inventory" ),
|
||||
new ModelResourceLocation( "computercraft:turtle_magenta", "inventory" ),
|
||||
new ModelResourceLocation( "computercraft:turtle_orange", "inventory" ),
|
||||
new ModelResourceLocation( "computercraft:turtle_white", "inventory" ),
|
||||
};
|
||||
private static ModelResourceLocation BEGINNER_TURTLE_MODEL = new ModelResourceLocation( "computercraftedu:CC-TurtleJunior", "inventory" );
|
||||
private static ModelResourceLocation[] BEGINNER_TURTLE_COLOUR_MODELS = new ModelResourceLocation[] {
|
||||
new ModelResourceLocation( "computercraftedu:turtleJunior_black", "inventory" ),
|
||||
new ModelResourceLocation( "computercraftedu:turtleJunior_red", "inventory" ),
|
||||
new ModelResourceLocation( "computercraftedu:turtleJunior_green", "inventory" ),
|
||||
new ModelResourceLocation( "computercraftedu:turtleJunior_brown", "inventory" ),
|
||||
new ModelResourceLocation( "computercraftedu:turtleJunior_blue", "inventory" ),
|
||||
new ModelResourceLocation( "computercraftedu:turtleJunior_purple", "inventory" ),
|
||||
new ModelResourceLocation( "computercraftedu:turtleJunior_cyan", "inventory" ),
|
||||
new ModelResourceLocation( "computercraftedu:turtleJunior_lightGrey", "inventory" ),
|
||||
new ModelResourceLocation( "computercraftedu:turtleJunior_grey", "inventory" ),
|
||||
new ModelResourceLocation( "computercraftedu:turtleJunior_pink", "inventory" ),
|
||||
new ModelResourceLocation( "computercraftedu:turtleJunior_lime", "inventory" ),
|
||||
new ModelResourceLocation( "computercraftedu:turtleJunior_yellow", "inventory" ),
|
||||
new ModelResourceLocation( "computercraftedu:turtleJunior_lightBlue", "inventory" ),
|
||||
new ModelResourceLocation( "computercraftedu:turtleJunior_magenta", "inventory" ),
|
||||
new ModelResourceLocation( "computercraftedu:turtleJunior_orange", "inventory" ),
|
||||
new ModelResourceLocation( "computercraftedu:turtleJunior_white", "inventory" ),
|
||||
};
|
||||
private static ModelResourceLocation ELF_OVERLAY_MODEL = new ModelResourceLocation( "computercraft:turtle_elf_overlay", "inventory" );
|
||||
|
||||
public TileEntityTurtleRenderer()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderTileEntityAt( TileTurtle tileEntity, double posX, double posY, double posZ, float f, int i )
|
||||
{
|
||||
if( tileEntity != null )
|
||||
{
|
||||
// Check the turtle isn't first person
|
||||
Entity viewEntity = Minecraft.getMinecraft().getRenderViewEntity();
|
||||
if( viewEntity != null && viewEntity instanceof TurtleVisionCamera )
|
||||
{
|
||||
TurtleVisionCamera camera = (TurtleVisionCamera)viewEntity;
|
||||
if( camera.getTurtle() == tileEntity.getAccess() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Render the turtle
|
||||
renderTurtleAt( tileEntity, posX, posY, posZ, f, i );
|
||||
}
|
||||
}
|
||||
|
||||
public static ModelResourceLocation getTurtleModel( ComputerFamily family, Colour colour )
|
||||
{
|
||||
switch( family )
|
||||
{
|
||||
case Normal:
|
||||
default:
|
||||
{
|
||||
if( colour != null )
|
||||
{
|
||||
return COLOUR_TURTLE_MODELS[ colour.ordinal() ];
|
||||
}
|
||||
else
|
||||
{
|
||||
return NORMAL_TURTLE_MODEL;
|
||||
}
|
||||
}
|
||||
case Advanced:
|
||||
{
|
||||
if( colour != null )
|
||||
{
|
||||
return COLOUR_TURTLE_MODELS[ colour.ordinal() ];
|
||||
}
|
||||
else
|
||||
{
|
||||
return ADVANCED_TURTLE_MODEL;
|
||||
}
|
||||
}
|
||||
case Beginners:
|
||||
{
|
||||
if( colour != null )
|
||||
{
|
||||
return BEGINNER_TURTLE_COLOUR_MODELS[ colour.ordinal() ];
|
||||
}
|
||||
else
|
||||
{
|
||||
return BEGINNER_TURTLE_MODEL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static ModelResourceLocation getTurtleOverlayModel( ComputerFamily family, ResourceLocation overlay, boolean christmas )
|
||||
{
|
||||
if( overlay != null )
|
||||
{
|
||||
return new ModelResourceLocation( overlay, "inventory" );
|
||||
}
|
||||
else if( christmas && family != ComputerFamily.Beginners )
|
||||
{
|
||||
return ELF_OVERLAY_MODEL;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void renderTurtleAt( TileTurtle turtle, double posX, double posY, double posZ, float f, int i )
|
||||
{
|
||||
GlStateManager.pushMatrix();
|
||||
try
|
||||
{
|
||||
// Setup the transform
|
||||
Vec3 offset;
|
||||
float yaw;
|
||||
if( turtle != null )
|
||||
{
|
||||
offset = turtle.getRenderOffset( f );
|
||||
yaw = turtle.getRenderYaw( f );
|
||||
}
|
||||
else
|
||||
{
|
||||
offset = new Vec3( 0.0, 0.0, 0.0 );
|
||||
yaw = 0.0f;
|
||||
}
|
||||
GlStateManager.translate( posX + offset.xCoord, posY + offset.yCoord, posZ + offset.zCoord );
|
||||
|
||||
// Render the label
|
||||
IComputer computer = (turtle != null) ? turtle.getComputer() : null;
|
||||
String label = (computer != null) ? computer.getLabel() : null;
|
||||
if( label != null )
|
||||
{
|
||||
renderLabel( turtle.getAccess().getPosition(), label );
|
||||
}
|
||||
|
||||
// Render the turtle
|
||||
GlStateManager.translate( 0.5f, 0.0f, 0.5f );
|
||||
GlStateManager.rotate( 180.0f - yaw, 0.0f, 1.0f, 0.0f );
|
||||
GlStateManager.translate( -0.5f, 0.0f, -0.5f );
|
||||
|
||||
// Render the turtle
|
||||
Colour colour;
|
||||
ComputerFamily family;
|
||||
ResourceLocation overlay;
|
||||
if( turtle != null )
|
||||
{
|
||||
colour = turtle.getColour();
|
||||
family = turtle.getFamily();
|
||||
overlay = turtle.getOverlay();
|
||||
}
|
||||
else
|
||||
{
|
||||
colour = null;
|
||||
family = ComputerFamily.Normal;
|
||||
overlay = null;
|
||||
}
|
||||
renderModel( getTurtleModel( family, colour ) );
|
||||
|
||||
// Render the overlay
|
||||
ModelResourceLocation overlayModel = getTurtleOverlayModel(
|
||||
family,
|
||||
overlay,
|
||||
HolidayUtil.getCurrentHoliday() == Holiday.Christmas
|
||||
);
|
||||
if( overlayModel != null )
|
||||
{
|
||||
GlStateManager.disableCull();
|
||||
GlStateManager.enableBlend();
|
||||
GlStateManager.blendFunc( GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA );
|
||||
try
|
||||
{
|
||||
renderModel( overlayModel );
|
||||
}
|
||||
finally
|
||||
{
|
||||
GlStateManager.disableBlend();
|
||||
GlStateManager.enableCull();
|
||||
}
|
||||
}
|
||||
|
||||
// Render the upgrades
|
||||
if( turtle != null )
|
||||
{
|
||||
renderUpgrade( turtle, TurtleSide.Left, f );
|
||||
renderUpgrade( turtle, TurtleSide.Right, f );
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
private void renderUpgrade( TileTurtle turtle, TurtleSide side, float f )
|
||||
{
|
||||
ITurtleUpgrade upgrade = turtle.getUpgrade( side );
|
||||
if( upgrade != null )
|
||||
{
|
||||
GlStateManager.pushMatrix();
|
||||
try
|
||||
{
|
||||
float toolAngle = turtle.getToolRenderAngle( side, f );
|
||||
GlStateManager.translate( 0.0f, 0.5f, 0.5f );
|
||||
GlStateManager.rotate( -toolAngle, 1.0f, 0.0f, 0.0f );
|
||||
GlStateManager.translate( 0.0f, -0.5f, -0.5f );
|
||||
|
||||
Pair<IBakedModel, Matrix4f> pair = upgrade.getModel( turtle.getAccess(), side );
|
||||
if( pair != null )
|
||||
{
|
||||
if( pair.getRight() != null )
|
||||
{
|
||||
ForgeHooksClient.multiplyCurrentGlMatrix( pair.getRight() );
|
||||
}
|
||||
if( pair.getLeft() != null )
|
||||
{
|
||||
renderModel( pair.getLeft() );
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void renderModel( ModelResourceLocation modelLocation )
|
||||
{
|
||||
Minecraft mc = Minecraft.getMinecraft();
|
||||
ModelManager modelManager = mc.getRenderItem().getItemModelMesher().getModelManager();
|
||||
renderModel( modelManager.getModel( modelLocation ) );
|
||||
}
|
||||
|
||||
private void renderModel( IBakedModel model )
|
||||
{
|
||||
if( model instanceof IFlexibleBakedModel )
|
||||
{
|
||||
renderModel( (IFlexibleBakedModel) model );
|
||||
}
|
||||
else
|
||||
{
|
||||
renderModel( new IFlexibleBakedModel.Wrapper( model, DefaultVertexFormats.ITEM ) );
|
||||
}
|
||||
}
|
||||
|
||||
private void renderModel( IFlexibleBakedModel model )
|
||||
{
|
||||
Minecraft mc = Minecraft.getMinecraft();
|
||||
Tessellator tessellator = Tessellator.getInstance();
|
||||
WorldRenderer renderer = tessellator.getWorldRenderer();
|
||||
mc.getTextureManager().bindTexture( TextureMap.locationBlocksTexture );
|
||||
renderer.begin( GL11.GL_QUADS, model.getFormat() );
|
||||
for( EnumFacing facing : EnumFacing.VALUES )
|
||||
{
|
||||
renderQuads( renderer, model.getFaceQuads( facing ) );
|
||||
}
|
||||
renderQuads( renderer, model.getGeneralQuads() );
|
||||
tessellator.draw();
|
||||
}
|
||||
|
||||
private void renderQuads( WorldRenderer renderer, List quads )
|
||||
{
|
||||
int color = 0xFFFFFFFF;
|
||||
Iterator it = quads.iterator();
|
||||
while( it.hasNext() )
|
||||
{
|
||||
BakedQuad quad = (BakedQuad)it.next();
|
||||
net.minecraftforge.client.model.pipeline.LightUtil.renderQuadColor( renderer, quad, color );
|
||||
}
|
||||
}
|
||||
|
||||
private void renderLabel( BlockPos position, String label )
|
||||
{
|
||||
Minecraft mc = Minecraft.getMinecraft();
|
||||
MovingObjectPosition mop = mc.objectMouseOver;
|
||||
if( mop != null && mop.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK && mop.getBlockPos().equals( position ) )
|
||||
{
|
||||
RenderManager renderManager = mc.getRenderManager();
|
||||
FontRenderer fontrenderer = renderManager.getFontRenderer();
|
||||
float scale = 0.016666668F * 1.6f;
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.disableLighting();
|
||||
GlStateManager.enableBlend();
|
||||
GlStateManager.blendFunc( GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA );
|
||||
try
|
||||
{
|
||||
GlStateManager.translate( 0.5f, 1.25f, 0.5f );
|
||||
GlStateManager.rotate( -renderManager.playerViewY, 0.0F, 1.0F, 0.0F );
|
||||
GlStateManager.rotate( renderManager.playerViewX, 1.0F, 0.0F, 0.0F );
|
||||
GlStateManager.scale( -scale, -scale, scale );
|
||||
|
||||
int yOffset = 0;
|
||||
int xOffset = fontrenderer.getStringWidth( label ) / 2;
|
||||
|
||||
// Draw background
|
||||
GlStateManager.depthMask( false );
|
||||
GlStateManager.disableDepth();
|
||||
try
|
||||
{
|
||||
// Quad
|
||||
GlStateManager.disableTexture2D();
|
||||
try
|
||||
{
|
||||
Tessellator tessellator = Tessellator.getInstance();
|
||||
WorldRenderer renderer = tessellator.getWorldRenderer();
|
||||
renderer.begin( GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR );
|
||||
renderer.pos( (double) ( -xOffset - 1 ), (double) ( -1 + yOffset ), 0.0D ).color( 0.0F, 0.0F, 0.0F, 0.25F ).endVertex();
|
||||
renderer.pos( (double) ( -xOffset - 1 ), (double) ( 8 + yOffset ), 0.0D ).color( 0.0F, 0.0F, 0.0F, 0.25F ).endVertex();
|
||||
renderer.pos( (double) ( xOffset + 1 ), (double) ( 8 + yOffset ), 0.0D ).color( 0.0F, 0.0F, 0.0F, 0.25F ).endVertex();
|
||||
renderer.pos( (double) ( xOffset + 1 ), (double) ( -1 + yOffset ), 0.0D ).color( 0.0F, 0.0F, 0.0F, 0.25F ).endVertex();
|
||||
tessellator.draw();
|
||||
}
|
||||
finally
|
||||
{
|
||||
GlStateManager.enableTexture2D();
|
||||
}
|
||||
|
||||
// Text
|
||||
fontrenderer.drawString( label, -fontrenderer.getStringWidth( label ) / 2, yOffset, 0x20ffffff );
|
||||
}
|
||||
finally
|
||||
{
|
||||
GlStateManager.enableDepth();
|
||||
GlStateManager.depthMask( true );
|
||||
}
|
||||
|
||||
// Draw foreground text
|
||||
fontrenderer.drawString( label, -fontrenderer.getStringWidth( label ) / 2, yOffset, -1 );
|
||||
}
|
||||
finally
|
||||
{
|
||||
GlStateManager.disableBlend();
|
||||
GlStateManager.enableLighting();
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,195 @@
|
||||
package dan200.computercraft.client.render;
|
||||
|
||||
import net.minecraft.client.renderer.block.model.BakedQuad;
|
||||
import net.minecraft.client.renderer.block.model.ItemCameraTransforms;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.client.renderer.vertex.VertexFormat;
|
||||
import net.minecraft.client.renderer.vertex.VertexFormatElement;
|
||||
import net.minecraft.client.resources.model.IBakedModel;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraftforge.client.model.IFlexibleBakedModel;
|
||||
|
||||
import javax.vecmath.Matrix4f;
|
||||
import javax.vecmath.Point3f;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class TurtleMultiModel implements IFlexibleBakedModel
|
||||
{
|
||||
private IFlexibleBakedModel m_baseModel;
|
||||
private IFlexibleBakedModel m_overlayModel;
|
||||
private IFlexibleBakedModel m_leftUpgradeModel;
|
||||
private IFlexibleBakedModel m_rightUpgradeModel;
|
||||
|
||||
private List<BakedQuad> m_generalQuads;
|
||||
private List<BakedQuad>[] m_faceQuads;
|
||||
|
||||
public TurtleMultiModel( IBakedModel baseModel, IBakedModel overlayModel, IBakedModel leftUpgradeModel, Matrix4f leftUpgradeTransform, IBakedModel rightUpgradeModel, Matrix4f rightUpgradeTransform )
|
||||
{
|
||||
// Get the models
|
||||
m_baseModel = makeFlexible( baseModel );
|
||||
m_overlayModel = makeFlexible( overlayModel );
|
||||
m_leftUpgradeModel = makeFlexible( leftUpgradeModel );
|
||||
m_rightUpgradeModel = makeFlexible( rightUpgradeModel );
|
||||
|
||||
// Bake the quads
|
||||
m_generalQuads = new ArrayList<BakedQuad>();
|
||||
m_generalQuads.addAll( m_baseModel.getGeneralQuads() );
|
||||
if( m_overlayModel != null )
|
||||
{
|
||||
m_generalQuads.addAll( m_overlayModel.getGeneralQuads() );
|
||||
}
|
||||
if( m_leftUpgradeModel != null )
|
||||
{
|
||||
m_generalQuads.addAll( transformQuads( m_leftUpgradeModel.getFormat(), m_leftUpgradeModel.getGeneralQuads(), leftUpgradeTransform ) );
|
||||
}
|
||||
if( m_rightUpgradeModel != null )
|
||||
{
|
||||
m_generalQuads.addAll( transformQuads( m_rightUpgradeModel.getFormat(), m_rightUpgradeModel.getGeneralQuads(), rightUpgradeTransform ) );
|
||||
}
|
||||
|
||||
m_faceQuads = new List[ EnumFacing.VALUES.length ];
|
||||
for( EnumFacing facing : EnumFacing.VALUES )
|
||||
{
|
||||
List<BakedQuad> faces = new ArrayList<BakedQuad>();
|
||||
faces.addAll( m_baseModel.getFaceQuads( facing ) );
|
||||
if( m_overlayModel != null )
|
||||
{
|
||||
faces.addAll( m_overlayModel.getFaceQuads( facing ) );
|
||||
}
|
||||
if( m_leftUpgradeModel != null )
|
||||
{
|
||||
faces.addAll( transformQuads( m_leftUpgradeModel.getFormat(), m_leftUpgradeModel.getFaceQuads( facing ), leftUpgradeTransform ) );
|
||||
}
|
||||
if( m_rightUpgradeModel != null )
|
||||
{
|
||||
faces.addAll( transformQuads( m_rightUpgradeModel.getFormat(), m_rightUpgradeModel.getFaceQuads( facing ), rightUpgradeTransform ) );
|
||||
}
|
||||
m_faceQuads[ facing.getIndex() ] = faces;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BakedQuad> getFaceQuads( EnumFacing side )
|
||||
{
|
||||
return m_faceQuads[ side.getIndex() ];
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BakedQuad> getGeneralQuads()
|
||||
{
|
||||
return m_generalQuads;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAmbientOcclusion()
|
||||
{
|
||||
return m_baseModel.isAmbientOcclusion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGui3d()
|
||||
{
|
||||
return m_baseModel.isGui3d();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBuiltInRenderer()
|
||||
{
|
||||
return m_baseModel.isBuiltInRenderer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextureAtlasSprite getParticleTexture()
|
||||
{
|
||||
return m_baseModel.getParticleTexture();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemCameraTransforms getItemCameraTransforms()
|
||||
{
|
||||
return m_baseModel.getItemCameraTransforms();
|
||||
}
|
||||
|
||||
@Override
|
||||
public VertexFormat getFormat()
|
||||
{
|
||||
return m_baseModel.getFormat();
|
||||
}
|
||||
|
||||
private List<BakedQuad> transformQuads( VertexFormat format, List<BakedQuad> input, Matrix4f transform )
|
||||
{
|
||||
if( transform == null || input.size() == 0 )
|
||||
{
|
||||
return input;
|
||||
}
|
||||
else
|
||||
{
|
||||
List<BakedQuad> output = new ArrayList<BakedQuad>( input.size() );
|
||||
for( int i=0; i<input.size(); ++i )
|
||||
{
|
||||
BakedQuad quad = input.get( i );
|
||||
output.add( transformQuad( format, quad, transform ) );
|
||||
}
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
||||
private BakedQuad transformQuad( VertexFormat format, BakedQuad quad, Matrix4f transform )
|
||||
{
|
||||
int[] vertexData = quad.getVertexData().clone();
|
||||
BakedQuad copy = new BakedQuad( vertexData, quad.getTintIndex(), quad.getFace() );
|
||||
int offset = 0;
|
||||
for( int i=0; i<format.getElementCount(); ++i ) // For each vertex element
|
||||
{
|
||||
VertexFormatElement element = format.getElement( i );
|
||||
if( element.isPositionElement() &&
|
||||
element.getType() == VertexFormatElement.EnumType.FLOAT &&
|
||||
element.getElementCount() == 3 ) // When we find a position element
|
||||
{
|
||||
for( int j=0; j<4; ++j ) // For each corner of the quad
|
||||
{
|
||||
int start = offset + j * format.getNextOffset();
|
||||
if( (start % 4) == 0 )
|
||||
{
|
||||
start = start / 4;
|
||||
|
||||
// Extract the position
|
||||
Point3f pos = new Point3f(
|
||||
Float.intBitsToFloat( vertexData[ start ] ),
|
||||
Float.intBitsToFloat( vertexData[ start + 1 ] ),
|
||||
Float.intBitsToFloat( vertexData[ start + 2 ] )
|
||||
);
|
||||
|
||||
// Transform the position
|
||||
transform.transform( pos );
|
||||
|
||||
// Insert the position
|
||||
vertexData[ start ] = Float.floatToRawIntBits( pos.x );
|
||||
vertexData[ start + 1 ] = Float.floatToRawIntBits( pos.y );
|
||||
vertexData[ start + 2 ] = Float.floatToRawIntBits( pos.z );
|
||||
}
|
||||
}
|
||||
}
|
||||
offset += element.getSize();
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
private IFlexibleBakedModel makeFlexible( IBakedModel model )
|
||||
{
|
||||
if( model == null )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else if( model instanceof IFlexibleBakedModel )
|
||||
{
|
||||
return (IFlexibleBakedModel)model;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new IFlexibleBakedModel.Wrapper( model, DefaultVertexFormats.ITEM );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,211 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.client.render;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import dan200.computercraft.api.turtle.ITurtleUpgrade;
|
||||
import dan200.computercraft.api.turtle.TurtleSide;
|
||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||
import dan200.computercraft.shared.turtle.items.ItemTurtleBase;
|
||||
import dan200.computercraft.shared.turtle.items.TurtleItemFactory;
|
||||
import dan200.computercraft.shared.util.Colour;
|
||||
import dan200.computercraft.shared.util.Holiday;
|
||||
import dan200.computercraft.shared.util.HolidayUtil;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.block.model.ItemCameraTransforms;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.resources.IResourceManager;
|
||||
import net.minecraft.client.resources.IResourceManagerReloadListener;
|
||||
import net.minecraft.client.resources.model.IBakedModel;
|
||||
import net.minecraft.client.resources.model.ModelManager;
|
||||
import net.minecraft.client.resources.model.ModelResourceLocation;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.client.model.ISmartItemModel;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import javax.vecmath.Matrix4f;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
public class TurtleSmartItemModel implements ISmartItemModel, IResourceManagerReloadListener
|
||||
{
|
||||
private static class TurtleModelCombination
|
||||
{
|
||||
public final ComputerFamily m_family;
|
||||
public final Colour m_colour;
|
||||
public final ITurtleUpgrade m_leftUpgrade;
|
||||
public final ITurtleUpgrade m_rightUpgrade;
|
||||
public final ResourceLocation m_overlay;
|
||||
public final boolean m_christmas;
|
||||
|
||||
public TurtleModelCombination( ComputerFamily family, Colour colour, ITurtleUpgrade leftUpgrade, ITurtleUpgrade rightUpgrade, ResourceLocation overlay, boolean christmas )
|
||||
{
|
||||
m_family = family;
|
||||
m_colour = colour;
|
||||
m_leftUpgrade = leftUpgrade;
|
||||
m_rightUpgrade = rightUpgrade;
|
||||
m_overlay = overlay;
|
||||
m_christmas = christmas;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals( Object other )
|
||||
{
|
||||
if( other == this ) {
|
||||
return true;
|
||||
}
|
||||
if( other instanceof TurtleModelCombination ) {
|
||||
TurtleModelCombination otherCombo = (TurtleModelCombination)other;
|
||||
if( otherCombo.m_family == m_family &&
|
||||
otherCombo.m_colour == m_colour &&
|
||||
otherCombo.m_leftUpgrade == m_leftUpgrade &&
|
||||
otherCombo.m_rightUpgrade == m_rightUpgrade &&
|
||||
Objects.equal( otherCombo.m_overlay, m_overlay ) &&
|
||||
otherCombo.m_christmas == m_christmas )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + m_family.hashCode();
|
||||
result = prime * result + (m_colour != null ? m_colour.hashCode() : 0);
|
||||
result = prime * result + (m_leftUpgrade != null ? m_leftUpgrade.hashCode() : 0);
|
||||
result = prime * result + (m_rightUpgrade != null ? m_rightUpgrade.hashCode() : 0);
|
||||
result = prime * result + (m_overlay != null ? m_overlay.hashCode() : 0);
|
||||
result = prime * result + (m_christmas ? 1 : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
private ItemStack m_defaultItem;
|
||||
private HashMap<TurtleModelCombination, IBakedModel> m_cachedModels;
|
||||
|
||||
public TurtleSmartItemModel()
|
||||
{
|
||||
m_defaultItem = TurtleItemFactory.create( -1, null, null, ComputerFamily.Normal, null, null, 0, null );
|
||||
m_cachedModels = new HashMap<TurtleModelCombination, IBakedModel>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResourceManagerReload( IResourceManager resourceManager )
|
||||
{
|
||||
m_cachedModels.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBakedModel handleItemState( ItemStack stack )
|
||||
{
|
||||
ItemTurtleBase turtle = (ItemTurtleBase) stack.getItem();
|
||||
ComputerFamily family = turtle.getFamily( stack );
|
||||
Colour colour = turtle.getColour( stack );
|
||||
ITurtleUpgrade leftUpgrade = turtle.getUpgrade( stack, TurtleSide.Left );
|
||||
ITurtleUpgrade rightUpgrade = turtle.getUpgrade( stack, TurtleSide.Right );
|
||||
ResourceLocation overlay = turtle.getOverlay( stack );
|
||||
boolean christmas = HolidayUtil.getCurrentHoliday() == Holiday.Christmas;
|
||||
TurtleModelCombination combo = new TurtleModelCombination( family, colour, leftUpgrade, rightUpgrade, overlay, christmas );
|
||||
if( m_cachedModels.containsKey( combo ) )
|
||||
{
|
||||
return m_cachedModels.get( combo );
|
||||
}
|
||||
else
|
||||
{
|
||||
IBakedModel model = buildModel( combo );
|
||||
m_cachedModels.put( combo, model );
|
||||
return model;
|
||||
}
|
||||
}
|
||||
|
||||
private IBakedModel buildModel( TurtleModelCombination combo )
|
||||
{
|
||||
Minecraft mc = Minecraft.getMinecraft();
|
||||
ModelManager modelManager = mc.getRenderItem().getItemModelMesher().getModelManager();
|
||||
ModelResourceLocation baseModelLocation = TileEntityTurtleRenderer.getTurtleModel( combo.m_family, combo.m_colour );
|
||||
ModelResourceLocation overlayModelLocation = TileEntityTurtleRenderer.getTurtleOverlayModel( combo.m_family, combo.m_overlay, combo.m_christmas );
|
||||
IBakedModel baseModel = modelManager.getModel( baseModelLocation );
|
||||
IBakedModel overlayModel = (overlayModelLocation != null) ? modelManager.getModel( baseModelLocation ) : null;
|
||||
Pair<IBakedModel, Matrix4f> leftModel = (combo.m_leftUpgrade != null) ? combo.m_leftUpgrade.getModel( null, TurtleSide.Left ) : null;
|
||||
Pair<IBakedModel, Matrix4f> rightModel = (combo.m_rightUpgrade != null) ? combo.m_rightUpgrade.getModel( null, TurtleSide.Right ) : null;
|
||||
if( leftModel != null && rightModel != null )
|
||||
{
|
||||
return new TurtleMultiModel( baseModel, overlayModel, leftModel.getLeft(), leftModel.getRight(), rightModel.getLeft(), rightModel.getRight() );
|
||||
}
|
||||
else if( leftModel != null )
|
||||
{
|
||||
return new TurtleMultiModel( baseModel, overlayModel, leftModel.getLeft(), leftModel.getRight(), null, null );
|
||||
}
|
||||
else if( rightModel != null )
|
||||
{
|
||||
return new TurtleMultiModel( baseModel, overlayModel, null, null, rightModel.getLeft(), rightModel.getRight() );
|
||||
}
|
||||
else if( overlayModel != null )
|
||||
{
|
||||
return new TurtleMultiModel( baseModel, overlayModel, null, null, null, null );
|
||||
}
|
||||
else
|
||||
{
|
||||
return baseModel;
|
||||
}
|
||||
}
|
||||
|
||||
// These should not be called:
|
||||
|
||||
@Override
|
||||
public List getFaceQuads( EnumFacing facing )
|
||||
{
|
||||
return getDefaultModel().getFaceQuads( facing );
|
||||
}
|
||||
|
||||
@Override
|
||||
public List getGeneralQuads()
|
||||
{
|
||||
return getDefaultModel().getGeneralQuads();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAmbientOcclusion()
|
||||
{
|
||||
return getDefaultModel().isAmbientOcclusion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGui3d()
|
||||
{
|
||||
return getDefaultModel().isGui3d();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBuiltInRenderer()
|
||||
{
|
||||
return getDefaultModel().isBuiltInRenderer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextureAtlasSprite getParticleTexture()
|
||||
{
|
||||
return getDefaultModel().getParticleTexture();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemCameraTransforms getItemCameraTransforms()
|
||||
{
|
||||
return getDefaultModel().getItemCameraTransforms();
|
||||
}
|
||||
|
||||
private IBakedModel getDefaultModel()
|
||||
{
|
||||
return handleItemState( m_defaultItem );
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user