package slimeknights.tconstruct.tools.common.client; import com.google.common.collect.ImmutableList; import net.minecraft.block.Block; import net.minecraft.block.BlockChest; import net.minecraft.block.BlockEnderChest; import net.minecraft.block.BlockSign; import net.minecraft.block.BlockSkull; import net.minecraft.block.material.Material; import net.minecraft.block.state.IBlockState; import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.PlayerControllerMP; import net.minecraft.client.renderer.BlockRendererDispatcher; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.ItemRenderer; import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.VertexBuffer; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.texture.TextureManager; import net.minecraft.client.renderer.texture.TextureMap; import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.resources.IResourceManager; import net.minecraft.client.resources.IResourceManagerReloadListener; import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumHand; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; import net.minecraftforge.client.event.FOVUpdateEvent; import net.minecraftforge.client.event.RenderSpecificHandEvent; import net.minecraftforge.client.event.RenderWorldLastEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import org.lwjgl.opengl.GL11; import java.util.List; import javax.annotation.Nonnull; import slimeknights.tconstruct.library.tools.DualToolHarvestUtils; import slimeknights.tconstruct.library.tools.IAoeTool; import slimeknights.tconstruct.tools.ranged.TinkerRangedWeapons; @SideOnly(Side.CLIENT) public class RenderEvents implements IResourceManagerReloadListener { private static final ResourceLocation widgetsTexPath = new ResourceLocation("textures/gui/widgets.png"); // GuiIngame.widgetsTexPath private final TextureAtlasSprite[] destroyBlockIcons = new TextureAtlasSprite[10]; @SubscribeEvent public void renderExtraBlockBreak(RenderWorldLastEvent event) { PlayerControllerMP controllerMP = Minecraft.getMinecraft().playerController; EntityPlayer player = Minecraft.getMinecraft().player; World world = player.getEntityWorld(); ItemStack tool = player.getHeldItemMainhand(); // AOE preview if(tool != null) { Entity renderEntity = Minecraft.getMinecraft().getRenderViewEntity(); double distance = controllerMP.getBlockReachDistance(); RayTraceResult mop = renderEntity.rayTrace(distance, event.getPartialTicks()); if(mop != null) { tool = DualToolHarvestUtils.getItemstackToUse(player, world.getBlockState(mop.getBlockPos())); if(tool.getItem() instanceof IAoeTool) { ImmutableList<BlockPos> extraBlocks = ((IAoeTool) tool.getItem()).getAOEBlocks(tool, world, player, mop.getBlockPos()); for(BlockPos pos : extraBlocks) { event.getContext().drawSelectionBox(player, new RayTraceResult(new Vec3d(0, 0, 0), null, pos), 0, event.getPartialTicks()); } } } } // extra-blockbreak animation if(controllerMP.isHittingBlock) { tool = DualToolHarvestUtils.getItemstackToUse(player, world.getBlockState(controllerMP.currentBlock)); if(tool != null && tool.getItem() instanceof IAoeTool && ((IAoeTool) tool.getItem()).isAoeHarvestTool()) { BlockPos pos = controllerMP.currentBlock; drawBlockDamageTexture(Tessellator.getInstance(), Tessellator.getInstance().getBuffer(), player, event.getPartialTicks(), world, ((IAoeTool) tool.getItem()).getAOEBlocks(tool, world, player, pos)); } } } // RenderGlobal.drawBlockDamageTexture public void drawBlockDamageTexture(Tessellator tessellatorIn, VertexBuffer vertexBuffer, Entity entityIn, float partialTicks, World world, List<BlockPos> blocks) { double d0 = entityIn.lastTickPosX + (entityIn.posX - entityIn.lastTickPosX) * (double) partialTicks; double d1 = entityIn.lastTickPosY + (entityIn.posY - entityIn.lastTickPosY) * (double) partialTicks; double d2 = entityIn.lastTickPosZ + (entityIn.posZ - entityIn.lastTickPosZ) * (double) partialTicks; TextureManager renderEngine = Minecraft.getMinecraft().renderEngine; int progress = (int) (Minecraft.getMinecraft().playerController.curBlockDamageMP * 10f) - 1; // 0-10 if(progress < 0) { return; } renderEngine.bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE); //preRenderDamagedBlocks BEGIN GlStateManager.tryBlendFuncSeparate(774, 768, 1, 0); GlStateManager.enableBlend(); GlStateManager.color(1.0F, 1.0F, 1.0F, 0.5F); GlStateManager.doPolygonOffset(-3.0F, -3.0F); GlStateManager.enablePolygonOffset(); GlStateManager.alphaFunc(516, 0.1F); GlStateManager.enableAlpha(); GlStateManager.pushMatrix(); //preRenderDamagedBlocks END vertexBuffer.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK); vertexBuffer.setTranslation(-d0, -d1, -d2); vertexBuffer.noColor(); for(BlockPos blockpos : blocks) { double d3 = (double) blockpos.getX() - d0; double d4 = (double) blockpos.getY() - d1; double d5 = (double) blockpos.getZ() - d2; Block block = world.getBlockState(blockpos).getBlock(); TileEntity te = world.getTileEntity(blockpos); boolean hasBreak = block instanceof BlockChest || block instanceof BlockEnderChest || block instanceof BlockSign || block instanceof BlockSkull; if(!hasBreak) { hasBreak = te != null && te.canRenderBreaking(); } if(!hasBreak) { IBlockState iblockstate = world.getBlockState(blockpos); if(iblockstate.getBlock().getMaterial(iblockstate) != Material.AIR) { TextureAtlasSprite textureatlassprite = this.destroyBlockIcons[progress]; BlockRendererDispatcher blockrendererdispatcher = Minecraft.getMinecraft().getBlockRendererDispatcher(); blockrendererdispatcher.renderBlockDamage(iblockstate, blockpos, textureatlassprite, world); } } } tessellatorIn.draw(); vertexBuffer.setTranslation(0.0D, 0.0D, 0.0D); // postRenderDamagedBlocks BEGIN GlStateManager.disableAlpha(); GlStateManager.doPolygonOffset(0.0F, 0.0F); GlStateManager.disablePolygonOffset(); GlStateManager.enableAlpha(); GlStateManager.depthMask(true); GlStateManager.popMatrix(); // postRenderDamagedBlocks END } @SubscribeEvent public void handRenderEvent(RenderSpecificHandEvent event) { EntityPlayer player = Minecraft.getMinecraft().player; if(event.getHand() == EnumHand.OFF_HAND && player.isHandActive()) { ItemStack stack = player.getActiveItemStack(); if(stack != null && stack.getItemUseAction() == EnumAction.BOW) { event.setCanceled(true); } } ItemStack mainStack = player.getHeldItemMainhand(); RayTraceResult rt = Minecraft.getMinecraft().objectMouseOver; if(mainStack != null && rt != null && rt.typeOfHit == RayTraceResult.Type.BLOCK && DualToolHarvestUtils.shouldUseOffhand(player, rt.getBlockPos(), mainStack)) { event.setCanceled(true); EnumHand hand; ItemStack itemStack; if(event.getHand() == EnumHand.MAIN_HAND) { hand = EnumHand.OFF_HAND; itemStack = player.getHeldItemOffhand(); } else { hand = EnumHand.MAIN_HAND; itemStack = player.getHeldItemMainhand(); } ItemRenderer itemRenderer = Minecraft.getMinecraft().getItemRenderer(); itemRenderer.renderItemInFirstPerson( Minecraft.getMinecraft().player, event.getPartialTicks(), event.getInterpolatedPitch(), hand, event.getSwingProgress(), itemStack, event.getEquipProgress()); } } @SubscribeEvent public void onFovEvent(FOVUpdateEvent event) { ItemStack stack = event.getEntity().getActiveItemStack(); if(stack != null) { float zoom = 0f; float progress = 0f; if(stack.getItem() == TinkerRangedWeapons.longBow) { zoom = 0.35f; progress = TinkerRangedWeapons.longBow.getDrawbackProgress(stack, event.getEntity()); } if(zoom > 0) { event.setNewfov(1f - (progress * progress) * zoom); } } } @Override public void onResourceManagerReload(@Nonnull IResourceManager resourceManager) { TextureMap texturemap = Minecraft.getMinecraft().getTextureMapBlocks(); for(int i = 0; i < this.destroyBlockIcons.length; ++i) { this.destroyBlockIcons[i] = texturemap.getAtlasSprite("minecraft:blocks/destroy_stage_" + i); } } }