2017-05-07 00:18:59 +00:00
|
|
|
/*
|
2017-05-01 13:32:39 +00:00
|
|
|
* This file is part of ComputerCraft - http://www.computercraft.info
|
2019-01-01 01:10:18 +00:00
|
|
|
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
|
2017-05-01 13:32:39 +00:00
|
|
|
* 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.turtle.blocks.TileTurtle;
|
|
|
|
import dan200.computercraft.shared.util.Holiday;
|
|
|
|
import dan200.computercraft.shared.util.HolidayUtil;
|
2017-05-01 13:51:26 +00:00
|
|
|
import net.minecraft.block.state.IBlockState;
|
2017-05-01 13:32:39 +00:00
|
|
|
import net.minecraft.client.Minecraft;
|
2017-06-12 08:14:57 +00:00
|
|
|
import net.minecraft.client.renderer.BufferBuilder;
|
2019-02-10 09:45:15 +00:00
|
|
|
import net.minecraft.client.renderer.EntityRenderer;
|
2017-05-01 13:32:39 +00:00
|
|
|
import net.minecraft.client.renderer.GlStateManager;
|
|
|
|
import net.minecraft.client.renderer.Tessellator;
|
|
|
|
import net.minecraft.client.renderer.block.model.BakedQuad;
|
2017-05-06 13:59:30 +00:00
|
|
|
import net.minecraft.client.renderer.block.model.IBakedModel;
|
2017-05-01 13:51:26 +00:00
|
|
|
import net.minecraft.client.renderer.block.model.ModelManager;
|
|
|
|
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
|
2017-05-01 13:32:39 +00:00
|
|
|
import net.minecraft.client.renderer.texture.TextureMap;
|
|
|
|
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
|
|
|
|
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
2017-05-01 13:51:26 +00:00
|
|
|
import net.minecraft.client.renderer.vertex.VertexFormat;
|
2017-05-06 13:59:30 +00:00
|
|
|
import net.minecraft.util.EnumFacing;
|
|
|
|
import net.minecraft.util.ResourceLocation;
|
|
|
|
import net.minecraft.util.math.Vec3d;
|
2017-05-01 13:32:39 +00:00
|
|
|
import net.minecraftforge.client.ForgeHooksClient;
|
2017-05-06 13:59:30 +00:00
|
|
|
import net.minecraftforge.client.model.pipeline.LightUtil;
|
2017-05-01 13:32:39 +00:00
|
|
|
import org.apache.commons.lang3.tuple.Pair;
|
|
|
|
import org.lwjgl.opengl.GL11;
|
|
|
|
|
|
|
|
import javax.vecmath.Matrix4f;
|
|
|
|
import java.util.List;
|
|
|
|
|
|
|
|
public class TileEntityTurtleRenderer extends TileEntitySpecialRenderer<TileTurtle>
|
|
|
|
{
|
2018-12-26 09:09:15 +00:00
|
|
|
private static final ModelResourceLocation NORMAL_TURTLE_MODEL = new ModelResourceLocation( "computercraft:turtle", "inventory" );
|
2019-02-11 16:38:33 +00:00
|
|
|
private static final ModelResourceLocation ADVANCED_TURTLE_MODEL = new ModelResourceLocation( "computercraft:turtle_advanced", "inventory" );
|
2018-12-26 09:09:15 +00:00
|
|
|
private static final ModelResourceLocation COLOUR_TURTLE_MODEL = new ModelResourceLocation( "computercraft:turtle_white", "inventory" );
|
|
|
|
private static final ModelResourceLocation ELF_OVERLAY_MODEL = new ModelResourceLocation( "computercraft:turtle_elf_overlay", "inventory" );
|
2017-05-01 13:32:39 +00:00
|
|
|
|
|
|
|
@Override
|
2019-03-29 21:21:39 +00:00
|
|
|
public void render( TileTurtle tileEntity, double posX, double posY, double posZ, float partialTicks, int breaking, float f2 )
|
2017-05-01 13:32:39 +00:00
|
|
|
{
|
2019-03-29 21:21:39 +00:00
|
|
|
if( tileEntity != null ) renderTurtleAt( tileEntity, posX, posY, posZ, partialTicks );
|
2017-05-01 13:32:39 +00:00
|
|
|
}
|
|
|
|
|
2017-05-11 17:44:02 +00:00
|
|
|
public static ModelResourceLocation getTurtleModel( ComputerFamily family, boolean coloured )
|
2017-05-01 13:32:39 +00:00
|
|
|
{
|
|
|
|
switch( family )
|
|
|
|
{
|
|
|
|
case Normal:
|
|
|
|
default:
|
2017-05-11 17:44:02 +00:00
|
|
|
return coloured ? COLOUR_TURTLE_MODEL : NORMAL_TURTLE_MODEL;
|
2017-05-01 13:32:39 +00:00
|
|
|
case Advanced:
|
2017-05-11 17:44:02 +00:00
|
|
|
return coloured ? COLOUR_TURTLE_MODEL : ADVANCED_TURTLE_MODEL;
|
2017-05-01 13:32:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-10 09:45:15 +00:00
|
|
|
public static ModelResourceLocation getTurtleOverlayModel( ResourceLocation overlay, boolean christmas )
|
2017-05-01 13:32:39 +00:00
|
|
|
{
|
|
|
|
if( overlay != null )
|
|
|
|
{
|
|
|
|
return new ModelResourceLocation( overlay, "inventory" );
|
|
|
|
}
|
2018-12-26 09:09:15 +00:00
|
|
|
else if( christmas )
|
2017-05-01 13:32:39 +00:00
|
|
|
{
|
|
|
|
return ELF_OVERLAY_MODEL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-29 21:21:39 +00:00
|
|
|
private void renderTurtleAt( TileTurtle turtle, double posX, double posY, double posZ, float partialTicks )
|
2017-05-01 13:32:39 +00:00
|
|
|
{
|
2019-02-10 09:45:15 +00:00
|
|
|
// Render the label
|
|
|
|
String label = turtle.createProxy().getLabel();
|
|
|
|
if( label != null && rendererDispatcher.cameraHitResult != null && turtle.getPos().equals( rendererDispatcher.cameraHitResult.getBlockPos() ) )
|
|
|
|
{
|
|
|
|
setLightmapDisabled( true );
|
|
|
|
EntityRenderer.drawNameplate(
|
|
|
|
getFontRenderer(), label,
|
|
|
|
(float) posX + 0.5F, (float) posY + 1.2F, (float) posZ + 0.5F, 0,
|
|
|
|
rendererDispatcher.entityYaw, rendererDispatcher.entityPitch, false, false
|
|
|
|
);
|
|
|
|
setLightmapDisabled( false );
|
|
|
|
}
|
|
|
|
|
2017-05-01 13:32:39 +00:00
|
|
|
GlStateManager.pushMatrix();
|
|
|
|
try
|
|
|
|
{
|
2019-03-27 18:59:02 +00:00
|
|
|
IBlockState state = turtle.getWorld().getBlockState( turtle.getPos() );
|
2017-05-01 13:32:39 +00:00
|
|
|
// Setup the transform
|
2019-03-27 18:59:02 +00:00
|
|
|
Vec3d offset = turtle.getRenderOffset( partialTicks );
|
|
|
|
float yaw = turtle.getRenderYaw( partialTicks );
|
2017-06-12 08:14:57 +00:00
|
|
|
GlStateManager.translate( posX + offset.x, posY + offset.y, posZ + offset.z );
|
2017-05-01 13:32:39 +00:00
|
|
|
|
|
|
|
// Render the turtle
|
2017-11-21 00:34:35 +00:00
|
|
|
GlStateManager.translate( 0.5f, 0.5f, 0.5f );
|
2017-05-01 13:32:39 +00:00
|
|
|
GlStateManager.rotate( 180.0f - yaw, 0.0f, 1.0f, 0.0f );
|
2017-11-21 00:34:35 +00:00
|
|
|
if( label != null && (label.equals( "Dinnerbone" ) || label.equals( "Grumm" )) )
|
|
|
|
{
|
|
|
|
// Flip the model and swap the cull face as winding order will have changed.
|
|
|
|
GlStateManager.scale( 1.0f, -1.0f, 1.0f );
|
|
|
|
GlStateManager.cullFace( GlStateManager.CullFace.FRONT );
|
|
|
|
}
|
|
|
|
GlStateManager.translate( -0.5f, -0.5f, -0.5f );
|
2017-05-01 13:32:39 +00:00
|
|
|
// Render the turtle
|
2019-03-29 21:21:39 +00:00
|
|
|
int colour = turtle.getColour();
|
|
|
|
ComputerFamily family = turtle.getFamily();
|
|
|
|
ResourceLocation overlay = turtle.getOverlay();
|
2017-05-06 13:59:30 +00:00
|
|
|
|
2017-05-11 17:44:02 +00:00
|
|
|
renderModel( state, getTurtleModel( family, colour != -1 ), colour == -1 ? null : new int[] { colour } );
|
2017-05-01 13:32:39 +00:00
|
|
|
|
|
|
|
// Render the overlay
|
|
|
|
ModelResourceLocation overlayModel = getTurtleOverlayModel(
|
|
|
|
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
|
|
|
|
{
|
2017-05-06 13:59:30 +00:00
|
|
|
renderModel( state, overlayModel, null );
|
2017-05-01 13:32:39 +00:00
|
|
|
}
|
|
|
|
finally
|
|
|
|
{
|
|
|
|
GlStateManager.disableBlend();
|
|
|
|
GlStateManager.enableCull();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Render the upgrades
|
2019-03-27 18:59:02 +00:00
|
|
|
renderUpgrade( state, turtle, TurtleSide.Left, partialTicks );
|
|
|
|
renderUpgrade( state, turtle, TurtleSide.Right, partialTicks );
|
2017-05-01 13:32:39 +00:00
|
|
|
}
|
|
|
|
finally
|
|
|
|
{
|
|
|
|
GlStateManager.popMatrix();
|
2017-11-21 00:34:35 +00:00
|
|
|
GlStateManager.cullFace( GlStateManager.CullFace.BACK );
|
2017-05-01 13:32:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-29 21:21:39 +00:00
|
|
|
private static void renderUpgrade( IBlockState state, TileTurtle turtle, TurtleSide side, float f )
|
2017-05-01 13:32:39 +00:00
|
|
|
{
|
|
|
|
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 );
|
|
|
|
|
2018-12-23 17:46:58 +00:00
|
|
|
Pair<IBakedModel, Matrix4f> pair = upgrade.getModel( turtle.getAccess(), side );
|
2017-05-01 13:32:39 +00:00
|
|
|
if( pair != null )
|
|
|
|
{
|
|
|
|
if( pair.getRight() != null )
|
|
|
|
{
|
|
|
|
ForgeHooksClient.multiplyCurrentGlMatrix( pair.getRight() );
|
|
|
|
}
|
|
|
|
if( pair.getLeft() != null )
|
|
|
|
{
|
2017-05-06 13:59:30 +00:00
|
|
|
renderModel( state, pair.getLeft(), null );
|
2017-05-01 13:32:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
finally
|
|
|
|
{
|
|
|
|
GlStateManager.popMatrix();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-29 21:21:39 +00:00
|
|
|
private static void renderModel( IBlockState state, ModelResourceLocation modelLocation, int[] tints )
|
2017-05-01 13:32:39 +00:00
|
|
|
{
|
|
|
|
Minecraft mc = Minecraft.getMinecraft();
|
|
|
|
ModelManager modelManager = mc.getRenderItem().getItemModelMesher().getModelManager();
|
2017-05-06 13:59:30 +00:00
|
|
|
renderModel( state, modelManager.getModel( modelLocation ), tints );
|
2017-05-01 13:32:39 +00:00
|
|
|
}
|
|
|
|
|
2019-03-29 21:21:39 +00:00
|
|
|
private static void renderModel( IBlockState state, IBakedModel model, int[] tints )
|
2017-05-01 13:32:39 +00:00
|
|
|
{
|
|
|
|
Minecraft mc = Minecraft.getMinecraft();
|
|
|
|
Tessellator tessellator = Tessellator.getInstance();
|
2017-05-01 13:51:26 +00:00
|
|
|
mc.getTextureManager().bindTexture( TextureMap.LOCATION_BLOCKS_TEXTURE );
|
2017-05-06 13:59:30 +00:00
|
|
|
renderQuads( tessellator, model.getQuads( state, null, 0 ), tints );
|
2017-05-01 13:32:39 +00:00
|
|
|
for( EnumFacing facing : EnumFacing.VALUES )
|
|
|
|
{
|
2017-05-06 13:59:30 +00:00
|
|
|
renderQuads( tessellator, model.getQuads( state, facing, 0 ), tints );
|
2017-05-01 13:32:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-29 21:21:39 +00:00
|
|
|
private static void renderQuads( Tessellator tessellator, List<BakedQuad> quads, int[] tints )
|
2017-05-01 13:32:39 +00:00
|
|
|
{
|
2017-06-12 08:14:57 +00:00
|
|
|
BufferBuilder buffer = tessellator.getBuffer();
|
2017-05-01 13:51:26 +00:00
|
|
|
VertexFormat format = DefaultVertexFormats.ITEM;
|
|
|
|
buffer.begin( GL11.GL_QUADS, format );
|
2018-12-23 17:46:58 +00:00
|
|
|
for( BakedQuad quad : quads )
|
2017-05-01 13:32:39 +00:00
|
|
|
{
|
2017-05-01 13:51:26 +00:00
|
|
|
VertexFormat quadFormat = quad.getFormat();
|
|
|
|
if( quadFormat != format )
|
|
|
|
{
|
|
|
|
tessellator.draw();
|
|
|
|
format = quadFormat;
|
|
|
|
buffer.begin( GL11.GL_QUADS, format );
|
|
|
|
}
|
2017-05-06 13:59:30 +00:00
|
|
|
|
|
|
|
int colour = 0xFFFFFFFF;
|
|
|
|
if( quad.hasTintIndex() && tints != null )
|
|
|
|
{
|
|
|
|
int index = quad.getTintIndex();
|
2018-12-23 17:46:58 +00:00
|
|
|
if( index >= 0 && index < tints.length ) colour = tints[index] | 0xFF000000;
|
2017-05-06 13:59:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
LightUtil.renderQuadColor( buffer, quad, colour );
|
2017-05-01 13:32:39 +00:00
|
|
|
}
|
2017-05-01 13:51:26 +00:00
|
|
|
tessellator.draw();
|
2017-05-01 13:32:39 +00:00
|
|
|
}
|
|
|
|
}
|