1
0
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:
Daniel Ratcliffe
2017-05-01 14:32:39 +01:00
parent 38623b31c4
commit e85cdacbc5
1123 changed files with 191332 additions and 3 deletions

View File

@@ -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;
}
}

View 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);
}
}

View File

@@ -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);
}
}

View File

@@ -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
);
}
}

View File

@@ -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);
}
}
}

View 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;
}
}
}

View 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 );
}
}

View File

@@ -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;
}
}

View File

@@ -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 ) );
}
}

View File

@@ -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 );
}
}
}
}

View File

@@ -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 );
}
}
}

View File

@@ -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
);
}
}
}

View File

@@ -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++;
}
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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();
}
}
}
}

View File

@@ -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 );
}
}
}

View File

@@ -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 );
}
}