package net.mcft.copy.backpacks.client; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.BlockModelRenderer; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.entity.layers.LayerRenderer; import net.minecraft.client.renderer.texture.TextureMap; import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; import net.minecraft.entity.EntityLivingBase; import net.minecraft.item.ItemStack; import net.minecraft.util.EnumHand; import net.minecraft.util.EnumHandSide; import net.minecraft.util.math.MathHelper; import net.mcft.copy.backpacks.ProxyClient; import net.mcft.copy.backpacks.api.BackpackHelper; import net.mcft.copy.backpacks.api.IBackpack; import net.mcft.copy.backpacks.api.IBackpackType; import net.mcft.copy.backpacks.block.entity.TileEntityBackpack; /** Contains methods and nested classes which handle rendering of backpacks as tile entity and layer on regular entities. */ public final class RendererBackpack { private RendererBackpack() { } private static void render(IBackpack backpack, float partialTicks, boolean renderStraps) { BlockModelRenderer renderer = Minecraft.getMinecraft().getBlockRendererDispatcher().getBlockModelRenderer(); Minecraft.getMinecraft().getTextureManager().bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE); ItemStack stack = backpack.getStack(); int color = ProxyClient.ITEM_COLOR.getColorFromItemstack(stack, 0); float r = (color >> 16 & 0xFF) / 255.0F; float g = (color >> 8 & 0xFF) / 255.0F; float b = (color & 0xFF) / 255.0F; renderer.renderModelBrightnessColor(ProxyClient.MODEL_BACKPACK, 1.0f, r, g, b); if (renderStraps) renderer.renderModelBrightnessColor(ProxyClient.MODEL_BACKPACK_STRAPS, 1.0f, r, g, b); float lidAngle = 0.0F; IBackpackType type = backpack.getType(); if (type != null) { int lidTicks = backpack.getLidTicks(); int prevLidTicks = backpack.getPrevLidTicks(); lidAngle = type.getLidAngle(lidTicks, prevLidTicks, partialTicks); } float lidYOffset = 9 / 16.0F; float lidZOffset = 5 / 16.0F; GlStateManager.pushMatrix(); GlStateManager.translate(0.0F, lidYOffset, lidZOffset); GlStateManager.rotate(lidAngle, -1.0F, 0.0F, 0.0F); GlStateManager.translate(0.0F, -lidYOffset, -lidZOffset); renderer.renderModelBrightnessColor(ProxyClient.MODEL_BACKPACK_TOP, 1.0f, r, g, b); GlStateManager.popMatrix(); } // TODO: See if this can be changed back to FastTESR? // Forge apparently has an animation API? asie says to ask fry. public static class TileEntity extends TileEntitySpecialRenderer<TileEntityBackpack> { @Override public void renderTileEntityAt(TileEntityBackpack entity, double x, double y, double z, float partialTicks, int breakStage) { IBackpack backpack = BackpackHelper.getBackpack(entity); if (backpack == null) return; float angle = entity.facing.getHorizontalAngle(); GlStateManager.pushMatrix(); GlStateManager.translate(x + 0.5, y + 0.5, z + 0.5); GlStateManager.rotate(angle, 0.0F, -1.0F, 0.0F); GlStateManager.translate(-0.5, -0.5, -0.5); render(backpack, partialTicks, true); GlStateManager.popMatrix(); } } public static class Layer implements LayerRenderer<EntityLivingBase> { // TODO: Allow this to be changed for backpack models that are visually bigger. private static final float HEIGHT_OFFSET = 4.0F / 16.0F; private static final float DEPTH_OFFSET = 10.5F / 16.0F; public boolean shouldCombineTextures() { return false; } public void doRenderLayer(EntityLivingBase entity, float limbSwing, float limbSwingAmount, float partialTicks, float ageInTicks, float netHeadYaw, float headPitch, float scale) { IBackpack backpack = BackpackHelper.getBackpack(entity); if (backpack == null) return; GlStateManager.pushMatrix(); // Make backpack swing with body as players swing their arms. float swingProgress = entity.getSwingProgress(partialTicks); float swingAngle = MathHelper.sin(MathHelper.sqrt(swingProgress) * ((float)Math.PI * 2.0F)) * 0.2F; if ((entity.swingingHand == EnumHand.OFF_HAND) ^ (entity.getPrimaryHand() == EnumHandSide.LEFT)) swingAngle *= -1; if (swingAngle != 0) GlStateManager.rotate((float)Math.toDegrees(swingAngle), 0.0F, 1.0F, 0.0F); // Rotate backpack if entity is sneaking. if (entity.isSneaking()) { // FIXME: Can be sneaking while flying with the elytra, then backpack is misaligned..? GlStateManager.translate(0.0F, 0.2F, 0.0F); GlStateManager.rotate(90.0F / (float)Math.PI, 1.0F, 0.0F, 0.0F); } GlStateManager.scale(0.8F, 0.8F, 0.8F); GlStateManager.translate(0.5F, 0.5F, 0.5F); GlStateManager.rotate(180.0F, 0.0F, 0.0F, 1.0F); GlStateManager.translate(0, -HEIGHT_OFFSET, -DEPTH_OFFSET); render(backpack, partialTicks, false); GlStateManager.popMatrix(); } } }